Creating a single class or use polymorphism?

Hi all,

So I’m trying to make a 2D game where I have 50 unique collectables(items). These collectables are obtained by the player under certain circumstances, ex: defeating monsters, in-game events…etc.

Upon getting these collectables, the icon of it will appear on the “show room” panel, and the status of it becomes “unlocked”.

These collectable has no real interactions with the game, they only contains some data like an example below:

public class Collectable
{
      public int id {get;set;}
      public string name {get;set;}
      public ItemType type {get;set;}
      public int rarity {get;set;}
      public float bonus {get;set;}
}

Notice that “bonus” is the bonus given to the player in some in-game events, ex: 0.2 additional chance to obtain Collectable XXX upon defeating monsters.

Now I have two questions:

-Should I create only one class like above then assign the values to it at runtime upon creation, or, create a Collectable base class and then create other 50 classes that inherit from the base class?
Or if there’s any better way you suggest?

//Option 1:
public void CreateCollectables()
{
         collectablelist.Add(new Collectable(){1,"item1", ItemType.Battle,1,0.1});
         collectablelist.Add(new Collectable(){1,"item2", ItemType.Type1,1,0.1});
         collectablelist.Add(new Collectable(){1,"item3", ItemType.Type2,1,0.1});
         ...
         ...
         collectablelist.Add(new Collectable(){1,"item50", ItemType.Event,1,0.1});
}

//Option 2:
public class Collectable1 : Collectable{
        public Collectable1()
       {
               id = 1; 
               name= "item1" 
               ...
        }
}
//then
public void CreateCollectables()
{
         collectablelist.Add(new Collectable1());
         collectablelist.Add(new Collectable2());
         collectablelist.Add(new Collectable3());
         ...
         ...
         collectablelist.Add(new Collectable50());
}

-If I were to map a collectable to a slot in the panel, what would be the ideal structure?

public class Collectable
{
...
CollectableSlot slot;
}
//or?
public class CollectableSlot
{
...
Collectable collectable;
}

Any comments are welcomed, thank you!

Hi @coolguyjoey, my take on OOP is that is always about you and your team’s ability to create, understand and maintain the code functionality you need vs code performance concerns:

For example:

  1. Will 50 scripts for each type of behavior going to make your job easier or harder in terms of finding a particular class code you need to adjust or modify? That will depend on what code 50 class have in common, and how you organize the code files. If you don’t name and organize the script files using some method, it can be hard to the script you need to edit. If 50 scripts have code in common and you need to edit, do you want to edit that 50 times? On the other hand, if you don’t similarly organize your inheritance using some method, it can make code equally difficult to understand and maintain.

  2. Will having 50 scripts affect the performance of your game? There is a performance hit, albeit small per reference use per object instance, for referencing object and properties on objects - especially where the properties themselves are references to other objects with properties the code may need to access. Linking to any properties of 50 class instances from some manager script, and having to do that repeatedly, is going to cost more than having everything in one script. If you have to loop through references to access properties of other objects a million times, it can be costly. That is why we create ‘cache’ variables - to reduce the de-referencing costs.

Always take the route that balances those concerns.

It sounds like in your example that you don’t need 50 scirpts, but some scheme that disassociates the the treatment of a collectable from the data of the collectables - I think into some kind of collection (list/dictionary) and, probably on a separate non-MonoBehavior class to be instanced on a read through a json file, because it is much easier to set up all that data in a text file. If your collectables reference game objects, you need to represent those in the json file too - and not difficult to do.

If it were me, I would set up a json file that represents an array of objects that contains all of the information for each unique collectable. I would also write a non-MonoBehavior Collectable class to embody each collectable as an object instance and reference each instance in a dictionary element that will be accessed by the players. If the collectables have any behaviors I would include it in the Collectables class definition. Players will need a list/collection to reference the Collectable class instances they acquire.

At runtime, during the game set up, initialize the collectables dictionary and in a loop grab each json representation use the data to Instantiate a Collectable class object, and then finally add to the dictionary. When it is done, we have a dictionary of all the collectables.

Then when a player finds a collectable, a reference to that specific collectable is added to the players unique list.

I doesn’t sound like you need Inheritance unless collectables themselves have different attributes or behaviors. In that case, I would created a Base Collectables class and as many sub-classes as necessary to embody those. The json elements for each collectable would need to reflect which subclass a collectable belong to, and the logic of the initialization loop would need to choose which subclass of Collectable would be Instantiated base on that data.

If there are Collectable sub-classes, the dictionary treatment needs to be changed because now it needs to accommodate sub-class members in one dictionary. So it will need to be initialed on the base Collectables class. There will be some nuances to how the dictionary is read from - in some cases we may need to Caste what is read from the dictionary into the proper subclass.

All that is off the top of my head - I’ve done this before for a weapons/inventory system, but it’s been a couple of years

BTW, OOP ‘Polymorphism’ means overriding methods/functions - you’re code may call for that, but the core issue in your question is one of OOP Inheritance.