screeps-game-api
screeps-game-api copied to clipboard
ObjectId deserialization doesn't work if id has leading zero
I'm storing the object ids of a Source into the screep.memory and load it later to try and get the Source object back. This works great if the object id starts with [1-9a-f]. But if the object id starts with a 0, it breaks. It serializes it without the leading 0 and later, when trying to load it, it complains that it doesn't find an object with this id.
I've tried several mechanisms of serializing (including the common way of doing id.to_string() and then str_id.parse(), but also a serde way with id.to_u128() and then serde_json) but none of them worked, leading me to believe that the broken code is actually the one creating object id instances from and u128.
In case it matters, here's the serde code:
creep.memory().path_set("task.source_id", serde_json::to_string(&sources_id.to_u128())?);
[...]
let source_id = creep.memory()
.path_string("task.source_id")?
.unwrap()?;
let source_id: u128 = serde_json::from_str(&source_id)?;
let source_id: ObjectId<Source> = ObjectId::try_from(source_id)?;
let source = game::get_object_typed::<Source>(source_id)?
.unwrap()?;
Hrm - seems like #244 might have resurfaced :( What's the length of the ids you're seeing issues with?
Examples:
- 06aebab343040c9baaa22322
- 067e688485782086e2504c69
I also noticed that there are test cases for serialization but none of them has a leading zero https://github.com/rustyscreeps/screeps-game-api/blob/master/src/local/object_id/raw.rs#L275
Hmm, yeah - that's definitely a failure case right now, as it'll only pad to 15 characters with the current workaround. What kind of server's generating these, out of curiosity? I think we'll be able to just add a 24-character padding case in addition to the 15-character one to avoid having to store more data.
This is shard3 on the official game server
Oh no :( Well that's terrible - I thought all MMO objects had their timestamp of creation encoded as their first 8 characters, so that pretty much all of 'em start with a 5. I'll see if I can get the workaround I'm thinking of working - can you point me to what kind of objects got those ids (or maybe just where they're at on shard3?)
Oh sorry, it seems I gave you wrong information. It was on screeps.com but not in the online world. It's simulation mode that gives those ids to objects. Double checking shard3, the objects do seem to all start with 5. So I guess the bug is simulation mode only, wasn't aware of that.
It is not restricted to a subset of object kinds as far as I'm aware. I've so far seen it in sources, room controllers and resource piles (the latter one being the most frequent because they get created relatively often and then break my script if they start with a zero).
Ahh gotcha, that makes sense - thanks a bunch for reporting that other issue that you've found with running in the sim as well. I think we should definitely plan on aiming for compatibility with the sim, but the sim is unfortunately weirdly different from live environments in a handful of ways and presents some specific stuff to work around, in addition to resetting the runtime environment every ~12 ticks.
The doc update for #136 should probably include also mentioning that it's busted in sim currently also and provide recommendations to work around that; for now I'd recommend spinning up an empty private server for your local testing.
Resolved by #333 - fixed in bindgen release!