API changes
- Memory parsing now runs inside a game script. Learn more
- New global object
RawMemory
allows to implement your own memory stringifier. Learn more - Added new global methods
Room.serializePath
andRoom.deserializePath
. Use them to save your memory size and CPU. - Added new option
serialize
toRoom.findPath
method. - Added new option
serializeMemory
toCreep.moveTo
method.
Attention: this option will be set to true by default on November 9!
my cpu increased 2.5 times, but memory parsing cost only 10 CPU
why?
@Ranger Try to insert this snippet to the first line of your
main
, how much does it show?about 10
До обновления обновления кеша global было каждые 6-10 тиков, а сейчас почти каждый тик, и количество CPU на обновление увеличилось.
@Ranger You probably need to profile your code then. It's hard to tell something without digging into your code. Although, we would be interested to see the results.
But it is problem not only for me
caching global scope not working
Yes, there was an issue with caching indeed. Fixed, thanks.
but why cache is updating very frequently, every 6-10 ticks in average?
The serializer/deserializer is too slow compared to just storing the path entirely and taking the JSON parse hit.
Anywhere from 20-25% increased CPU usage if I turn on serialization.
That is 20-25% increased CPU usage on move/findPath commands solely, not overall CPU.
Artem: can you provide us with a call back to serialize/deserialize Memory (the variable)? Otherwise, how do we write our own serializer from RawMemory without rewriting all access to creep.memory, room.memory etc.
@Hernanduer: We've optimized
Room.deserializePath
a bit. Could you please run your tests again?@NhanHo: This question is under consideration now. What API would you like to see regarding it?
@Artem: before I can comment on the API, can you clarify me a few points on the Memory variable first. Right now, my understanding is that the first time you access the Memory variable, the server will deserialize RawMemory using a JSON deserializer and store the content there. So what will happen if my first access is Memory = {}; (an assignment instead of an access)?
Let's say I put in my code Memory = CustomSerializer.parse(RawMemory) at the start of my code, would it work correctly as I expect, with the global Memory variable available to be used throughout all modules? And assuming that I will keep the Memory structure similar to the current one, will all the shortcut creep.memory/ room.memory work the same?
Writing that down, I think the api could be a set of callbacks that allow you to populate all the shortcut being used right now. So there will be one for each of those type of memory (one for creep, one for spawn...). Would that be too many?
Right now you can't assign global
Memory
variable at all, since its definition containswritable:false
property. And it doesn't make much sense, a callback API seems to be clearer anyway.In that case, I think a callback API (may be implicit as a module ?) will work. Just two simple call that will be used to decode and encode Memory. Preferably one that will also disable access to Memory from the code if it's not parsed (basically you can't accidentally use Memory and have it deserialize with the JSON one)
@Artem
It's still just too expensive compared to normal running. I added some profiling to my creeps and they see more than a 100% increase in cost for findPathTo and moveByPath commands (which also goes into moveTo as well)
Something like 30 and 42 CPU respectively right now going to 70+ and 80+ with serializing turned on.
The small gains from the faster Memory parse are not nearly enough for this increase in cost.
This is something DarkTrooper noticed and I can verify:
Game.creeps[creepInRoom1].pos.findPathTo(Game.creeps[creepInRoom2], {serialize: true})
will return an empty array if the two objects are in different rooms. You can serialize the path returned by findPathTo without problems but using the "serialize" parameter causes the empty array issue.
Fixed, thanks.
Could you please perform some more granular profiling? Our tests show single-digit CPU consumption for 1000 iterations of serialize/deserialize pairs (which is equivalent to 1000 moving creeps).
@Artem regarding the cpu usage, I discovered it was almost entirely because of the empty paths being returned. Now it is quite small and even an improvement on JSON equivalent parsing