Game.cpu.generatePixel change



  • @artch said in Game.cpu.generatePixel change:

    I don't agree this isn't a real coding problem. The limitation is artificial, but so are any other gameplay limitations in the game. This limitation forces you to think what you would like to perform on this tick - game actions or pixel generation. And now the real coding problem is how to decide this. How to predict what is the best tick to call generatePixel. The criteria was very simple before: run it whenever you have spare 5000 CPU. It's just one if condition. Now this decision is a bit more complicated and involves more factors.

    This is not like other limitations in the game. Other limitations exist in the game world and the decisions involved are about what your creeps/structures should do in the game world to react to those challenges or limitations in the game world. The whole game is about writing code to make better decisions in the game world.

    This limitation or “decision” you want to introduce is very different because it takes you out of the world and you are basically choosing:

    1. Play the game this tick / participate in the world this tick
    2. Don’t play the game this tick / don’t participate in the world this tick

    This is not an interesting choice and it seems to go against the very purpose of the game.

    I believe many players have written their code in such a way that something useful is happening EVERY tick. I remember watching one of @Mototroller ’s rooms a long time ago and being so impressed that a remote mining creep showed up and moved into place on the exact tick that the previous creep died. It was beautiful in a way. There are many other types of things that can be optimized in similar ways that I believe many players have worked on. Skipping ticks entirely throws a wrench in all of this.

    Choices and limitations are good, but I think it is bad if one of the options in the choice is to stop playing the game entirely for a tick.

    Yes we can come up with complicated ways of deciding, but it places unnecessary complications on EVERY other part of your code, and still results in nullifying ALL of your code for a tick to perform one small action.



  • I suspect that this decision isn't about game play, but about how you can purchase pixels for cheaper on the steam marketplace than you can by buying it direct from screeps.


  • Dev Team

    @helam said in Game.cpu.generatePixel change:

    Choices and limitations are good, but I think it is bad if one of the options in the choice is to stop playing the game entirely for a tick.

    Why stop playing the game entirely for a tick? Take note generatePixel call doesn't cancel your tick, it just cancels your intents, i.e. creeps and structures commands. You still can process data, memory, perform calculations, build caches, make estimations, tune your heuristics. This is totally up to you how you overcome this challenge with maximum efficiency.


  • Dev Team

    @crazydubc It would be very strange if players sold items on the community marketplace for a higher price than the official store, their offer would be quite pointless then 🙂

    🤔☝


  • @artch imo idea of wrapping "You still can process data, memory, perform calculations, build caches, make estimations, tune your heuristics" around 'generatePixel()' is quite pointless.

    I'm aware that one could do 'refresh all CostMatrixes and all Paths in all rooms' on 'generatePixel()' lost tick, but most (if not all) prefer to do, and is doing that just fine, without losing a tick.

    I think i would not be wrong to say that in general, what players DO NOT want, is to lose a tick of intents, especially since gain itself is barely above nil

    👏👆👍


  • @artch can we have some clarification on whether we are still charged 0.2 CPU for the cancelled intents?

    I think the answer is going to be yes, in which case you should really make that clear to everyone.



  • I think that the overwhelmingly negative replies to this idea should be taken as a sign that the wrong decision is being made here, even if the intention is pure. And I think it might help to break down the properties of generatePixel as it is now and as it will be if the scheduled change occurs:

    AS IT IS NOW:

    1. This is a super boring solution and virtually the only interaction people have with the system -> if(Game.cpu.bucket>9700) Game.cpu.generatePixel();
    2. Hard to balance <- With a bucket limit of only 10 000, the CPU consumed by generatePixel cannot be higher than that.
    3. Economic woes <- It's trivially easy to turn unused CPU into money, thereby flooding the market with both pixels and credits.
    4. CPU woes <- It's trivially easy to stack large amounts of unused CPU.

    AS IT WILL BE:

    1. This is a super boring solution and virtually the only interaction people have with the system -> if(Game.shard===ONE_I_DONT_USE) return Game.cpu.generatePixle();
    2. Hard to balance <- With a bucket limit of only 10 000, the CPU consumed by generatePixel cannot be higher than that.
    3. Economic okay? <- Pixels will be far less common, so this is mostly* fixed <- *Not fixed for people with barely-utilized alt-shards; economy isn't actually fixed.
    4. CPU woes <- It's trivially easy to stack large amounts of unused CPU.

    It's easy to whine and complain that something isn't how we'd like it, but I think it'll be a lot better for both the players and the game if we explore alternatives; otherwise, this is going to 1) Not actually do what's intended and 2) Become an underutilized feature. I've read through all of @artch's replies to the complaints so far, and I think I've come up with an idea adjacent to what he intends that could actually be interesting for players?

    Game.cpu.chargePixel();

    It's similar to generatePixel in that it consumes CPU, but different in the following ways:

    1. Consumes X active CPU when called (far less than 5 000; think 100-490; this number counts against "CPU used this tick").
    2. Must be called Y times IN A ROW (X=200 cpu & Y=25 ticks would equal 5 000 CPU consumed total).
    3. Has a Z percent chance that, at the end of the call-series, a pixel is generated (Z=1 would be as it is now; this is your knob for economic balance!).

    This function does not create any additional world-objects. X, Y, and Z are variables that can be tweaked for balance or dynamically adjusted to hit a performance goal on the server.

    1. Variable X provides a challenge to the player: Can you operate at -100 CPU per tick for an extended period?
    2. Variable Y provides a CPU-sink for the server: How big this number is will determine how much CPU is removed from the game.
    3. Variable Z provides an economic knob: Too many pixels/credits? Lower the percentage! Too few? Raise it!

    Optional extras:

    1. Stun the creeps in a room provided by Game.cpu.chargePixel(roomName) at the end of the call-series? 4.1) Must be a controlled room? 4.2) Number of creeps adjusts the chance of Z? 4.3) Stun the creeps in adjacent rooms? 4.4) Generate extra fatigue for affected creeps during the call-series?
    2. Creeps in a room provided by Game.cpu.chargePixel(roomName) "poop out" pixels with a random chance of variable W? It drops on the floor, and you have to be quick before it decays! <- This could potentially cause some chaos in a person's logistics network that they might be challenged to overcome ❤ 5.1) Pixels that exist physically have a timeToDecay of variable V EVEN IF carried by a creep; get it to a terminal/controller fast!
    3. Variable Z could compound with each successive call-series-loop to encourage LONG TERM pixel generation (e.g. it starts at 10% and adds 1% for each call-series, resetting after a time of disuse).
    4. Probably a bunch of other things I'm not thinking of that could make this fun.

    In summary: There's a better way to approach this problem that's more fun AND better addresses the economic, cpu, and player-challenge problems posed by the current (and proposed) solutions ❤

    👍👆

  • Dev Team

    @neyazayah So your basic procedure (without extras) is simply calling the same method again and again every tick and eventually gain a pixel. It's absolutely the same challenge as it is now - one line of code. With one if condition for how much spare CPU I have. I don't see how it's more interesting and fun than the current API. And it has the same issue - too little coding effort to get a pixel.

    👎🤦


  • NeyaZayah's AS IT IS NOW and AS IT WILL BE hits the nail on the head. I thought the intent behind .generatePixel() and related graphics is to allow a trivial amount of code (2 lines) to allow access to graphics in the game. Getting players to express themselves with 2D graphics and spicing up the look of the surrounding MMO world at the same time.

    The suggestion to cancel intents isn't a interesting problem or solution to work towards. Simply adding challenges for challenge's sake is not fun.

    What is the problem we're trying to solve? The communities response has been overwhelmingly negative so let's find a different solution to the problem we're trying to fix.

    1. If the problem is to many pixels are being generated by generatePixel(). The function already consumes 5000 CPU of 10000 bucket. We could play with the idea of a value between 5000-8000 but I expect this would disrupt far to many players to be viable. So we can't go higher unless bucket is changed and I doubt that's feasible. So we have to look elsewhere.

    2. "Pixelization" currently costs 500 and refunds are 400 of that 500. Both of these can be changed to slow down the 'value' of pixel generation. Double/Half the amounts that we know work until we find a value that works well. If we want to slow down pixel generation, change pixelization to cost 1000. If that slows down things to much, half the difference to 750 and so on until we find a happy medium. If re-rolling is a concern we can adjust those amounts.

    3. If we're interested in a more complex change we could change the amount of pixels generated per generatePixel() call. If we increase pixelization costs by the same amount. generatePixel() could generates 10 pixels if we change "Pixelization" costs to become 5000 instead of 500. This would allow us to play with the generatePixel amount so if our new "normal" is 10 we could half it to 5 (while keeping "Pixelization" at 5000) to half the 'value' of pixels.

    Note for suggestion #3: If we're entertaining this idea, do this by a factor of 100 or 500. These numbers are a lot easier to tweak then a factor of 10.

    Screeps already has a major problem of rewarding the old guard with the biggest economies and code-bases (Factory change did this most recently) and doing very little for the newer players (safe mode is one of the few catch-up mechanics we have). The proposed change will help those that are already idling all/most of their intents already and hurt those who desperately need those intents for energy and other things as they get their feet under them. Let's not compound problems that are only viable at higher RCL levels vs lower RCLs please.

    👏👍👆👑


  • I think we all glossed over:

    @systemparadox said in Game.cpu.generatePixel change:

    @artch said in Game.cpu.generatePixel change:

    @rayderblitz @Gadjung We don't consider any challenges that involve world game objects in pixel-related mechanics.

    That makes sense for buying them and using them, but for generating them that seems like a strange policy.

    Also, you are involving game world objects now - all of them. Every single object in my empire has to pause to generate pixels.

    This is, to me, a super important point. I would really like an answer on how this isn't totally going against that policy.

    👍👍


  • Gadjung was suggesting adding a new game object (new structure) to cross-highways that facilitate getting pixels, artch was saying they weren't considering adding new game objects (or structures) to the world for this. You have to read the full context of the thread.

    Pausing every object of yours isn't a good idea, don't get be wrong. But artch wasn't contradicting themself.



  • Also, other self-contradictory statements:

    @artch said in Game.cpu.generatePixel change:

    Just a routine balancing change, no big deal.

    vs

    @artch said in Game.cpu.generatePixel change:

    There is no "problem" we are trying to fix. Quite the opposite, we want to create a new coding problem here for those generating pixels. We want to create more coding challenge in it besides simple CPU consumption.

    We understand some may get upset since more coding efforts now should be put to continue generating pixels. But this is exactly the idea. Challenges are fun!

    Is it a balance change, or is it trying to create a challenge?

    If it's a balance change, what was out of balance?



  • @raskvann said in Game.cpu.generatePixel change:

    Gadjung was suggesting adding a new game object (new structure) to cross-highways that facilitate getting pixels, artch was saying they weren't considering adding new game objects (or structures) to the world for this. You're talking about two different things.

    Pausing every object of yours isn't a good idea, don't get be wrong. But artch wasn't contradicting themself.

    It says challenges that involve world game objects not implementation of new objects. This is pixels interacting with "world game objects." It is blatantly contradictory.


  • Dev Team

    @cribbit Please let's don't play words and spam pointless discussions here. It's obvious enough what was meant.


  • Dev Team

    Another suggestion that we discussed initially as an alternative for this new cancel rule is raising the bucket cost from 5000 CPU to 9900 CPU (UPD: 10000 CPU). What do you guys think about this one? Can you survive the next tick without skipping it after generatePixel call?

    👍


  • @artch said in Game.cpu.generatePixel change:

    Another suggestion that we discussed initially as an alternative for this new cancel rule is raising the bucket cost from 5000 CPU to 9900 CPU. What do you guys think about this one? Can you survive the next tick without skipping it after generatePixel call?

    I like that a lot more. Tbh even make it the full 10k, and extra CPU from the generation tick isn't given to bucket.


  • Dev Team

    @cribbit But then you will lose the entire tick, and not just intents?



  • @artch could you clarify this because I'm now confused?


  • Dev Team

    @systemparadox If you have negative bucket at the start of the tick, it will be skipped with an error Script execution has been terminated: CPU bucket is empty.



  • Ok I don't think @cribbit realised that.

    What if you charged 10K but the extra CPU did carry over like normal. Does it work like this:

    • Tick 1 starts with 9950 bucket and has 100 CPU allocated
    • Tick 1 executes generatePixel, costing 10K CPU
    • Tick 1 does some other stuff costing 40 CPU
    • Tick 2 starts with 10 bucket

    I think this does introduce some interesting challenges and decision making:

    • If you don't have enough bucket to start with, you lose a tick
    • If you spend too much CPU in tick 1, you lose a tick
    • If you spend too much CPU in tick 2, you lose a tick

    The challenge is getting enough bucket in the first place (9000 bucket is easy, but getting a full bucket seems quite hard because of periodic tasks), and in how close you can skirt the CPU limit vs the risk of losing a tick if you run over by mistake.

    This seems much more interesting and doesn't feel like the only way to participate in pixel generation is to opt out of the game entirely for a tick.