Separate your contentloading from the class that holds your object data.
public static class Art
{
private static Dictionary<string, Texture2D> _textures;
private ContentManager _cm;
public static Init(ContentManager cm)
{
_cm = cm;
//add each texture to the dictionary of textures with the path- you were sure to load anyway.
}
public static void LoadAsset(string path)
{
if(_textures.KeyExists(path))
return;
_textures.Add(path,_cm.Load<Texture2D>(path)); // add your checks for the existence of file etc.
}
public Texture2D Sprite(string path)
{
return _textures(path); // ofcourse do some checking if a path exists in the dictionary etc.
}
}
Now your paths are no longer causing duplicate content to load because you decoupled that so:
// Actual behavior object the game interacts with. May be serialized in a savegame file.
public class Character
{
public Character(CharacterData data)
{
Level = 1,
Hp = 234,
Name = data.Name;
Texturepath = data.TexturePath;
Art.LoadAsset(Texturepath);
}
}
Now in your draw function you can point to the Art.Sprite() to pick up the texture;
Next to solve the rivals circular references- you shouldn't declare "new" characters in each character you create. Create a pool of characters first. And then appoint rivals afterwards.
Weapons can be a mixed bag. Let's say you have a weapon like "excalibur"- one exists, but any character could own it- so you may want to create it outside of the character. On the other hand, each weapon could be unique in the sense that it has its own durability stat- in that way you can create one when needed (when a character is created, a chest is opened etc).