1

In an example game engine server, the game world could be represented by a World object. The game might have multiple game worlds and a player who is in a world only needs to receive position data of units in that world.

class World
{
    public List<Unit> Units { get; set; }
}

However a piece of code also needs to be able to look up what world a unit is in easily, so the unit object itself keeps track of a world reference.

class Unit
{
    public World World { get; set; }
}

This works for lookup, but quickly becomes problematic when changing data when the programmer isn't aware of the relationship between objects going on, so I changed Units in World to be readonly and have the following code in Unit.

public virtual World World
{
    get { return _world; }
    set
    {
        // Unit must always be in a world
        Contract.Requires<ArgumentNullException>(value != null);

        // If already this, don't do anything
        if (value == _world) return;

        var oldWorld = _world;
        _world = value;

        if(oldWorld != null) oldWorld.UpdateUnitEntry(this);
        _world.UpdateUnitEntry(this);
    }
}

This works, but it feels like there's a better way to do this. Especially as I add more stuff that needs to be linked the same way (a World also has Structures and Players), a lot of repeated functionality comes in. Is there a better way to achieve this one-to-many relationship without manually updating both sides?

Layl Conway
  • 385
  • 9
  • 17

1 Answers1

0

In languages like C++ which don't have such sophistaced reference management and GC, having cyclic references like this a problem anyway(e.g. SharedPtr). This also problem for e.g. serialization of the game state.

This leads me to believe that there might be a better way to approach that issue general. E.g. Do the Units really need to know their World? Maybe look at that code that made you think you'll need that and maybe you can change it in way that this won't be required anymore.

So, maybe implement an entity management system and only referencs your game entities by an abstract ID or handle. Resolve the ID/handle before acting no the object behind but do not have an entity keep store a reference to another entity. If you find yourself wanting to serialize the game's state this will also help greatly.

Otherwise:

What you are doing is not strictly wrong or anything. If it is working and not too much of a pain, just keep it like that.

Nico Heidtke
  • 525
  • 4
  • 7