Game.cpu.generatePixel change
-
@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.
-
@cribbit This seems correct.
-
@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).
-
@rayderblitz said in Game.cpu.generatePixel change:
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?
No, there will be no timeout. The limit is on the execution time, not CPU points. You will be able to continue running your script until your
min(tick_start_bucket, 500)
execution time is over, regardless how much extra CPU points you has spent during the tick. All extra will be simply subtracted from the bucket (which can even go negative).
-
@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.
If these are the only two options I personally prefer the higher CPU cost.
-
@artch said in Game.cpu.generatePixel change:
No, there will be no timeout. The limit is on the execution time, not CPU points. You will be able to continue running your script until your
min(tick_start_bucket, 500)
execution time is over, regardless how much extra CPU points you has spent during the tick. All extra will be simply subtracted from the bucket (which can even go negative).Ah, I see. No timeout then, but the different intent cost would be doable?
That's one aspect gone of course, but there are still many good ideas remaining. If there is really no changing your mind about any options other than the two you mentioned then I'm still for the (not quite, to be safe) 10k cost. I think it would be a shame though, as both solutions would generally just lead to players ignoring the change, ignoring the system or switching over to a slave shard (which is basically no effort, much less a challenge).
As this change is supposed to be for the players, however, I do think it's important to invest more time into working out an interesting system that will be a worthwhile change and adds to the players' experience - even if it takes a little more effort to work it out. If you give us more information about the criteria, restrictions etc. the community is very much willing to help out and I think you should take advantage of that. "[A] simple elegant solution" is not something easy to work with when the only two currently accepted solutions are not that at all.
-
@rayderblitz Unfortunately the community can only help in discussing the ideas rather than implementing them. And we lack developer resources to refactor this mechanic currently. Season and Arena are much more important projects than pixel generation. But we may revisit it some day in the future.
-
@artch For the "10000 CPU" cost option, I assume your normal CPU tick limit (max 300) would still be available to use since that 10k is strictly coming from the bucket? If so, this is definitely the best route as it increases the difficulty in farming pixels without causing undesired limitations in other areas. You would still have enough CPU for high priority intents like tanking tower damage during a siege. This lets you farm pixels 100% of the time if you solve the problem where the other route forces you to suspend pixel generation in situations where skipping intents for one tick is not an option.
-
@artch said in Game.cpu.generatePixel change:
@rayderblitz Unfortunately the community can only help in discussing the ideas rather than implementing them. And we lack developer resources to refactor this mechanic currently. Season and Arena are much more important projects than pixel generation. But we may revisit it some day in the future.
Yeah, that I definitely get. Even if the community provides you with fleshed out code you need to verify it does what you want the way you want etc. Though that makes me wonder why you decided to push this change now, given there is so much going on. You guys are working on Seasonal, Arena and other planned content like the other power creeps.
Personally speaking - though I'm certain I may as well speak on behalf of a majority of the community - I would rather see you invest the time you have into those features than time you already don't have into barely to not at all worked out concepts like this currently discussed change. Sometimes no update for a while is better than a forced one - not that that even is the case with everything coming up.
-
@rayderblitz We pushed it now because increasing 5000 to 10000, or adding intents cancelling is a very simple change. And it's long overdue, we discussed it 2 months ago already.
-
generatePixel cost will be changed from 5000 to 10000 CPU on December 10. No other changes to this method will be made.
-
@artch said in Game.cpu.generatePixel change:
generatePixel cost will be changed from 5000 to 10000 CPU on December 10. No other changes to this method will be made.
My exact reaction:
-
I'm much happier with this option that the original proposal of cancelling intents.
If you're good with your CPU management and plan a bit you should be able to handle this no problem. I expect to see more interest in #operatingsystems as a result of this, which is no bad thing.
-
notification 28 hours before deployment...
-
@rhef said in Game.cpu.generatePixel change:
notification 28 hours before deployment...
This has been announced 2 weeks ago for December 7, but got delayed for 3 more days. See this thread from the top post.
-
I guess it depends on what you mean by "this".
A tweet on Nov 23 announced that a different change (cancelling intents) is going to be deployed at a different date (December 7), requiring different changes to our codes.
A forum post on Dec 8 (20:32 CET) announced the actual change on a forum post (not even a new thread) that would happen on Dec 10. This was then reposted by o4kapuk on slack 3 minutes later. It never actually made it to twitter and the first time a lot of people (those who have not read the forum thread since Dec found out about it was a little over a day before it was actually deployed... if they read slack during the week, that is - because I for instance mostly have time for screeps during weekends and finding out that a breaking change forcing workarounds in my code to not break it was "announced" and deployed during the same week is just making me sad. There was no deadline - the revised design could have been announced through the proper channels with proper vacatio legis and deployed a week later, but it was not.
I'm just pointing out that the communication about that new design of the pixel change was not 100% perfect and I hope that we can all use that opportunity to draw conclusions and learn from it so that it is better in the future.
-
@rhef But why is it a breaking change? What does it break? The only possible negative effect may be a low-bucket situation, but this situation is normal (e.g. after runtime resets), and your code must be able to handle it properly. If it cannot handle it, then you miss a lot of ticks anyway, and 1 more missed tick doesn't make much difference to call it "breaking change".
In real breaking cases (when players are expected to change their code) we always test it on the PTR, announce it months in advance, and discuss drafts of the API with the community again and again. Since you're new to Screeps, you may have not seen these discussions, so just one example of such schedule:
- The new
Store
API has been proposed for discussion on April 26, 2019. - The PTR implementation was available to test on June 24, 2019.
- It has been released to production on October 14, 2019.
- The new
-
You can see the impact it had on #announcements-any slack, people started hitting global resets a lot when pixel generation ate their entire bucket unexpectedely. You can probably see a clear trend of it on a server-side chart of global resets per tick, if you are monitoring it.
My code never had to worry about bucket being at much less than 4k. I have an expensive room planner figuring out whether some new buildings or roads need to be done, sometimes it runs on the same tick as a creep scheduler - now they can burst through the limit, cause a reset, which will then on the next tick try to run pathfinder-heavy room planners for all rooms (as those set some room properties that are used by other systems to optimize the work for a small/medium/large room), which causes another reset until the server-side mechanism triggers when it sees that I'm skipping multiple ticks in a row, freezes my code completely to fill up the buffer and then brings my code back online in hope that it can plan all rooms before it bleeds out.