The 2024 Wheel Reinvention Jam is in 7 days. September 23-29, 2024. More info

How Do Braid and The Witness Handle Entity IDs?

Hey, I've been puzzling over a detail in Jonathan Blow's Rust rant from a few years ago. One of the technical points discussed is how to deal with game entities holding references to other entities across frame boundaries. The challenge here is how to handle invalidating a reference to an entity after that entity has been destroyed (and its slot potentially re-used for another entity). I'm trying to understand precisely what his solutions were for reusing entity IDs in Braid and The Witness.

At 12:40, he talks about the typical solution, which he used in Braid and The Witness, which is to use an integer index as entity ID, and a system to convert that entity ID into an entity pointer. If that entity is still active, you get the pointer. If it's not, the system says that the entity ID is invalid. This makes sense to me if your entity ID stores an index into the entity array alongside a unique entity ID that never gets re-used (like the generational index the Rust speaker talks about). But what gets me is that Jonathan says that his games only use a single integer.

At 42:12, he says the The Witness just uses a direct array index. How is this any better than using a direct pointer to the entity in question? If the entity at that index gets freed and then re-used, there's no way for entities holding that reference to know that it's been invalidated. The only thing that makes sense to me is that maybe The Witness just never re-uses entity IDs, since there's not a whole lot of destroying of entities going on in the game, which would limit the usefulness of re-using freed entities.

The only way to know for sure would be to ask Jonathan Blow directly. Maybe someone on discord would have an idea ? You got me interested, so if you find out, I would like to know the answer.

As you mentioned, I think that the entity ids are simply not reused. It also looks like Dark Souls games don't reuse entity ids, so this design isn't as problematic as it looks like.

As you can see in the video (from 1:40), NPCs can't be created at runtime (unsure about Elden Ring). They must already be present in the map data files, and enabled/disabled at runtime. This seems to indicate to me that the ids themselves are not reused, because why should they need to be?

One thing I am not sure about is the dropped items, ground messages etc. Not really sure how these are handled, maybe no other entity needs to hold a reference to them so this is not a problem?

To go back on the topic of Braid and The Witness, I think it would be the simplest solution to do something like this. Please tell me if you learn more because I also would like to know.