Links and tags for objects

I’m thinking a lot about links between objects, and ways for them to tag each other…

Like say a homing missile FINDS and locks on to some object… I could store a ref. to the target in the missile…

And I could do that for doors too… Like this door leads to THIS door, etc…

Well I can do that in game… Or in the editor… But how do I save this relationship to xml?

If I use something like index numbers of an object list, it will mess up when I delete and add objects.

All I know how to do is save data stored inside object instances, I don’t know how to SAVE actual object instances like this.

What I do in my games (especially in Exipelago, as it has quite complex save files) is I give every object in the game a number (unique number, just from a static counter) and when I need to store a reference, I store the UID instead - that way I can recreate the references from stored data after loading.

I actually just use a static counter and grab a number in the objects constructor, that way I always have a unique number and it doesnt matter when I delete objects.

1 Like

I don’t think I get what you mean…

Say one object is a AI controlled bomb that is set to go off when a certain enemy walks by.

Are you saying that each instance of enemy stores a unique ID number, and the bomb would check each enemy that walks by to see if bombs target ID matches enemys personal ID ?

I thought you were asking about references in savefiles? A savefile is just a state of the game which gets restored after loading. And UIDs are a way to store a representation of a reference to get restored after loading.

How you link your game together should be focused on performance and/or ease of readability - not how it’s gonna be serialized into a savegame.

So you are saying ON save, we know how many objects we have, so using their index in the save file is fine. On load, those same index numbers are still valid.

Hm, I may be misinterpreting the question here, but I’ll give what I think you might be looking for?

If you’re trying to create a type of system in your game to be able to attach ‘tags’ to objects in game, couldn’t you create a custom class like GameObject that takes a model and tag parameter; then, somewhere, you could create a List of GameObject.

GameObject class could look something like this:

public class GameObject {
    private Model m_ObjectModel; // The model of the game object.
    private string m_ObjectTag; // A tag that can be used to find this particular game object later.
    private bool m_ObjectEnabled = true; // Whether the model should be rendered or not.

    public GameObject(Model model, string tag) {
        m_ObjectModel = model;
        m_ObjectTag = tag;
    }

    public string GetTag() {
        return m_ObjectTag;
    }

    public bool IsEnabled() {
        m_ObjectEnabled;
    }

    //Do other stuff...
}

Then, where ever you have your list of game objects stored, you could create a function to find a specific game object with a tag with something like this:

public GameObject FindObjectWithTag(string tag) {
    GameObject foundObject = null;
    gameObjectList.ForEach(gameObj => 
    {
        //Check the tag of each game object in the scene.
        if(gameObj.GetTag().Equals(tag, StringComparer.OrdinalIgnoreCase) {
            foundObject = gameObj; // this is the game object we want.
            break;
        }
    });

    //Throw an exception if no object was found.
    if(foundObject is null)
        throw new Exception($"GameObject with tag {tag} does not exist!");

    return foundObject; 
}

If you’re also lacking a sort of trigger system, think of maybe adding something like an update function for the GameObject type where you could have a sort of sphere cast (sorry, I’m not too familiar with MonoGame’s 3D side) to check whether an object has just entered the radius.

So, in the case of having a bomb, you could do something like this if you have/add the above trigger-type system:

// this should be an event that is called when any game object enters the bombs area.
void override ObjectEnteredRadius(GameObject object)  {
    if(object.GetTag().Equals("Enemy") {
        ((Enemy)object).Kill();
    }
}

And if your bomb had an function to have it explode, with this gameobject system you could do this easily anywhere:
((BombObject)Game.FindGameObjectWithTag("Bomb")).Explode();

XML wise, this is all totally possible to save to a file. You could potentially take a look at this post on Stack Overflow here for more help. I am absolutely horrible working with XML but my 2D MonoGame project has a sort of generic list XML saver & loader, if you want to see it, look here. This code is pretty old, so it’s gross, don’t be too hard on me, lol.

I hope this was kind of what you were looking for, if not this can at least maybe help someone else. This code was not put into any kind of compiler, so I don’t know for sure if the syntax is 100% correct, but this should be good enough to get the general idea of what I’m explaining, I hope.

Yes… I could do that, but then I have all those checks in the foreach…
I’m looking for a fast way to hone in, like selecting specific cell from x,y coords…

What if I used a multi-dimensional array, 3 dimensions for grid-space, one dimension for faction, and another dimension for “tag”?

Yea I’m a little all over the place, I admit. I am forming a new game, so It’s all a bit of a fog upstairs right now. Shaders and content and marketing etc all bouncing around…

I can’t imagine why it’d be horribly slow; especially since you could technically just hold the object in a variable after finding it with FindObjectWithTag, the only thing to really be careful of is how the events are raised. Guess it may a bit out of my scope, but, in the case of your reply, you could create a dictionary maybe? Or yes, a multidimensional array could work, if I’m understanding correctly.

I don’t get this part… if an objects unique ID does not correspond to an index number on a list of objects, how am I supposed to use it?

ok wait… So we assign ID to objects on creation…

Then I can store that number in whatever object needs to link to that object…

Then on load, I go through and assign object refs from the linked ID number…

I suppose I could encode location info IN the the ID number… So as long as you know who you are looking for, you have some idea where they are…