How do I implement references or relations for entities within a serialized savegame?

I have a 2D tile based RPG for which I'm developing save game function. In particular, I'm trying to save this structure:

A caster can have multiple buffs that he maintains. Each buff can have multiple effects applied to players or monsters. The pattern has links both ways (caster has buff, buff knows who cast it)

If I serialize caster, buffs and effects, how can i restore the relationship: caster - buff - effect - target?

Would I need to implement something like unique identifiers for monster, buffs and players and then link them all together once the save game is loaded?

• I don't think the question needs details of your iOS implementation. If you need to add more info to your question to get better information, you can do that, but as far as I could tell your edit was extra information that wasn't needed. – MichaelHouse Jan 5 '14 at 18:54
• Related (possible duplicate?): gamedev.stackexchange.com/questions/68254/… – user1430 Jan 5 '14 at 19:02
• I think related for sure. That question is asking about what type of data to use for identifying references between assets, this question is asking about how to maintain references between components and entities when writing/reading them to disk. So, we can use the information from that other question and apply it here, but the other question doesn't answer this one. – MichaelHouse Jan 5 '14 at 19:07

Unique identifiers are a good option. However, they don't need to be used in game, only when writing and then reading the data from a save. Hopefully you'd already have some way to differentiating between entities you can use, otherwise you can make something up (typically an int or long)

Pick a unique ID for each entity, then proceed to writing the entities. For each entity, write its ID and when you write its components, add that ID as a header to the component information. Also write the ID for any target info. Then, when you're reading back in, you can use something like a dictionary to store the entities in, referenced by their ID. Then when you read a component, you can get the ID and index into the dictionary and add that component to that entity.

When I read and write entities, I write all of the entities first, without their components. This makes it much easier when reading in the components later because you have all the entities available to you. It avoids the situation where you're reading in an entity that has a component that targets another entity, but you haven't created that target entity yet because it's deeper in the file.

• That's similar to what I was thinking. The only thing that concerned me about this is someone has described this approach to me as "reinventing SQL". Is there a way to avoid that? – Alex Stone Jan 5 '14 at 18:29
• It's more like reinventing NoSQL. But since that's the goal you are trying to achieve, sans formal db engine, it's not something you need to try to avoid. – Seth Battin Jan 5 '14 at 18:47