Game.cpu.generatePixel change



  • @nobodysnightmare Let's not turn this into a contest of egos thing; we're just trying to find a solution to a problem ❤ And it seems like we've found one by simply increasing the bucket cost of generatePixel to 10 000 -> The simplest solutions are often the best for situations like these.

    @artch For as much detail as I put in the post, I apparently didn't put enough if you thought that 😮 It's okay though; thank you for seeing the community's concerns seriously and for the patience you've shown in the face of such hostility 🙂

    ❤

  • Dev Team

    @nobodysnightmare Consecutiveness of calls doesn't change anything. You simply wait until your bucket is full (one if) and spam chargePixel until the pixel is generated. No risk, no challenge, too easy. Extra rules can make it more difficult, but a good mechanic is a simple mechanic.

    Negative feedback is clearly visible but expected. It's just unclear whether it is an indicator of the mechanic being bad or simply unpopular. Unpopular change does not neccesarily mean a bad change.

    ❤👎


  • @artch The challenge comes from the implications, not the directly-written-code. "Simply wait until your bucket is full" is already the state of affairs for all proposed solutions so far; what makes my idea different is how consecutive calls costing active CPU instead of bucket CPU is in how it limits the player's longterm CPU consumption.

    Consider the following:

    1. A player can use, at most, 500 active CPU per tick.
    2. A player (assuming GCL 30) can produce, at most, 300 active CPU per tick.
    3. chargePixel exclusively consumes CPU from the active production.

    In the following example: chargePixel could be set to consume 400 CPU for 30 ticks.

    1. This limits the player to 100 active CPU per tick <- this is down from 300, and certainly down from the highest-at 500.
    2. This draws 100 CPU from the bucket per tick.
    3. This removes 6000 CPU from the system overall.
    4. MOST IMPORTANTLY: If the player uses more than 100 CPU in a tick while using chargePixel, it'll result in premature script cut-off due to going over the limit.

    In order to make the above work, there'd have to be a rule "generatePixel can only be used if it's the very first intent, otherwise it's ignored" to prevent going around the fourth point. Hopefully, this clarifies where the challenge comes from -> It's about committing to having sustainably higher efficiency code. That is the challenge ❤


  • Dev Team

    @neyazayah said in Game.cpu.generatePixel change:

    MOST IMPORTANTLY: If the player uses more than 100 CPU in a tick while using chargePixel, it'll result in premature script cut-off due to going over the limit.

    This can't be done. It's not how CPU limits in Screeps work, an in-game call cannot reduce CPU execution limit within the current tick.



  • Like the others, I think this is a strange and abrupt way of dealing with the overly simplistic generation of pixels. Perhaps instead you could make it behave more like Bitcoin mining and self-balance:

    EDIT: hadn't read post immediately above, crossed out impractical bits.

    • Introduce a "hash function" as Game.cpu.hash, which is artificially expensive and actually taken off the current tick's use (e.g. 100CPU). You could implement this behind the scenes as an HMAC with a per-shard secret, so people can't actually implement it.
    • Introduce a "difficulty" level for the "Pixel Chain". You have to find an input in a particular format (e.g. ${shard}-${Game.time}-${random} that has a hash value below that difficulty (interpreted as a number in ?-endian order).
    • Submitting an entry could also cost CPU to "validate" (whether or not it's correct) and have to be done in a particular tick used as part of the input. This means you need to have enough left over after generating them to submit it...
    • Perhaps a penalty if you sub invalid inputs?
    • Periodically update the difficulty level to reflect the amount of mining happening, targeting a constant generation rate. People then have to decide what their CPU is worth...
    • When people get this right, you could give them a batch of pixels at once, introducing more randomness to the process. Nothing, nothing, nothing, 100 pixels!, nothing, nothing...


  • @artch Strongly against original idea for reasons already stated. Interested in multiple calls version as it's more interesting than "low bucket code".

    My proposal for multiple calls version: It takes HALF of your normally available cpu/tick for the FOLLOWING tick and requires calls for as long as it takes to build up 5000, shard specific. New pixel API with a pixel progress response for given shard (eg, charging pixel at 400/5000). This is useful for other things besides just pixels as it's good practice for reserving cpu for military operations or autoscaling for shard cpu allocations. To increase difficulty you could limit bucket usage as well.



  • @artch I think I understand what you mean, but there are several ways around that problem.

    1. We could have the function cost a constant amount, similar to how intents already cost .2 CPU (and only allow its usage if there's the required amount's CPU available).
    2. Or we could have the function affect the next tick by artificially (and temporarily) lowering the player's GCL (possibly to negative values).

    Both of these things are malleable, as far as my understanding at least.

    Also, what @Davaned said is another way 🙂



  • @neyazayah Definitely definitely not by lowering gcl. That's a huge pile of side effects that are 100% not feasible and not correlated directly with cpu anyway as it's decoupled once you reach GCL 28.

    Shards already have cpu allocations, we should just use that as the means for handling pixel generation. Decreasing the allocation temporarily (equivalent to allocating a chunk of cpu to another shard/the pixel factory) would lower the barrier to entry for cross-shard play by making related code multipurpose.



  • @davaned Oh, yes! I'm not familiar with the intimate details of the game's programming, so I missed that part.

    There could be an "artificial shard" that the player dedicates CPU towards, and that is what generates the pixel? However, what @artch wants is challenge, so maybe there's a cooldown? How else might we make that challenging?

    Edit: Or are you simply saying that this is just the mechanism by which CPU is removed, and everything else about the idea remains standing?


  • Dev Team

    I still think we need a simple elegant solution here, not a whole lot of new API and inter-tick state data. Currently only two alternatives are on the table: cancelling intents or 10000 CPU cost. Let's discuss them.

    👍


  • It seems to me that a next-tick effect is analogous to upgrading a controller or trigger a creep spawn. This tick I perform an action, next tick I see effect and resources are gone. The one informational api would just be a counter.

    But if you feel it's unworkable, in that case 10K is preferable to the shadow canceling of all intents. Although if the goal is balancing number of pixels I'd argue for slightly under 10k (9.5k?) to reduce edge cases. I still think the original way will likely result in players ignoring it or handling pixel gen in another shard.

    👍


  • @artch

    high-energy pixel continuum burst

    Barely noticed any effect at all when generating. Seems more like an easter egg hunt kind of thing.

    @thmsn said in Game.cpu.generatePixel change:

    Hi @artch

    Could you elaborate some more on the reasoning behind this change? I don't quite get why it should also cancel all other intents? What exactly is high-energy continuum?

    Are you trying to make people not generate pixels?



  • I think charging 9500 or so bucket is fine. 10K leaves you with zero bucket. To me the issue with pixels wasn't generating, by the RNG around cashing them in for high tier decorations. If those decorations did something functional then you would also see a HUGE spike in pixel prices.

    ➕👍👂👆


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

    @neyazayah said in Game.cpu.generatePixel change:

    MOST IMPORTANTLY: If the player uses more than 100 CPU in a tick while using chargePixel, it'll result in premature script cut-off due to going over the limit.

    This can't be done. It's not how CPU limits in Screeps work, an in-game call cannot reduce CPU execution limit within the current tick.

    You seem to misunderstand the idea, we already have it in the game - intents. The difference would just be that this intent doesn't cost the usual 0.2, but 400 cpu.

    While I agree that accusing you of not caring for the community does not help the discussion, you just disregarding any and all propositions that don't fit the idea of change you already have in mind does not help your image here either. I do think it is unfair for you to just disregard genuinely good ideas by only giving pseudo arguments. And while you say you want a simple and elegant solution, the only ones you even consider are the exact opposite of that - unless you mean simple and elegant for you devs to implement, in which case you're right, but that line of thinking just increases the already abysmal chasm between devs and players.

    Since everything else - no matter how good, actually elegant and practicable - seems off the table anyway, my vote is on increasing the generation cost. I do however also think that the whole 10k are not a good idea, as they will just cause too many edge cases - a good portion of which the players will presumably not be able to influence -, so somewhere in the 9.5k-9.9k range should make that workable.


  • Dev Team

    @rayderblitz

    You seem to misunderstand the idea, we already have it in the game - intents. The difference would just be that this intent doesn't cost the usual 0.2, but 400 cpu.

    Intents do not have the ability to do this:

    it'll result in premature script cut-off due to going over the limit

    Intents operate on your bucket, not on the "active CPU".



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

    I still think we need a simple elegant solution here, not a whole lot of new API and inter-tick state data. Currently only two alternatives are on the table: cancelling intents or 10000 CPU cost. Let's discuss them.

    Definitely.

    I would like some clarification on game mechanics though.

    My understanding is:

    You have 20 + GCL * 10 CPU for the tick

    If you go over, you can use up to 500 from the bucket, if available

    If you go under, any excess is given to the bucket, which is capped at 10k

    So a 10k generate pixel would nuke your bucket, but you'd still have your CPU for that tick?

    If so, I think that is the best solution. It introduces interesting challenges around your bucket not always being there.



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

    Intents do not have the ability to do this:

    it'll result in premature script cut-off due to going over the limit

    Intents operate on your bucket, not on the "active CPU".

    I see, that seems to be a common misconception then. I think for the community to better understand the implications the change entails it is important for this to be cleared up.

    So the 0.2 operate on the bucket, does that mean the other cpu used does too? If not, how do those work together for the 500(-ish) cut-off per tick? https://docs.screeps.com/cpu-limit.html only mentions how averaging it out works, but does not mention what to expect when you skirt the edge of this system. According to my current understanding (including these facts you mentioned) the 10k could lead to some problems caused by not the user, but the system.


  • Dev Team

    @cribbit This seems correct.


  • Dev Team

    @rayderblitz Your script has execution limit that is predefined before it starts. It is always min(bucket, 500). No in-game calls can change this hard execution limit.

    Basically, there is no such thing as active / bucket CPU as in your description. It is all the same. All CPU used during the tick decreases your bucket. All intents decrease the bucket too. Every tick your bucket increases. And the limit is just min(bucket, 500). I can't seem to get what do you mean by active CPU.

    🤦


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

    @rayderblitz Your script has execution limit that is predefined before it starts. It is always min(bucket, 500). No in-game calls can change this hard execution limit.

    Basically, there is no such thing as active / bucket CPU as in your description. It is all the same. All CPU used during the tick decreases your bucket. All intents decrease the bucket too. Every tick your bucket increases. And the limit is just min(bucket, 500). I can't seem to get what do you mean by active CPU.

    Huh, wasnt "active CPU" a term you introduced?

    Anyway, since both normal (processing) cpu and intent cpu seem to work with the same pool (a min of 500 and bucket), it seems to me that it's doable. All an intent does is just add an artificial (predetermined) 0.2 cpu to whatever the checks of that intent cost, right? So if you have 250 in normal cpu doing calculations and 256 in intents in a tick, that should give you a timeout as far as my understanding goes, since you go over the 500 limit. The same would apply to 400 in calculations and 105 in intents, 50 in processing and 450 in intents and so on, did I get that right?

    Now, the idea is to have generatePixel clone the behavior of intents and replace the 0.2 cost with a 400 cost. Assuming I understood the above correctly, that should be doable. That way we would effectively (but not factually) reduce the available cpu in this tick to 100. In doing so we would then be able to implement many if not all of the ideas proposed by @NeyaZayah and others.

    As for the change you currently have in mind, one thing that I'm not yet sure is clear to me but would be critical is how exactly adding the current tick's cpu to the bucket (since it is used as the base for the cpu calculations) works. Is it calculated before the tick with a min(10000, bucket+cpu) or can you have more than 10k (bucket + cpu) during that tick and afterwards it's min'd out? Depending on what is the case here it might lead to the problems the player isn't to blame for I mentioned above. Then there are also issues like Game.cpu.getUsed() sometimes not accurately reporting the up to date cpu usage I and others have observed (assuming that hasn't been fixed in the meantime, haven't noticed it in a while).

    👍☝