Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

So I'm making a game where you can send ships to locations to sell or buy resources like wood, iron, gold, etc.

Now I was wondering how the resources should be created in de game. I came up with 2 options

  1. Create a class for each resource:

    public class ResourceBase {
        private int value;
        // other base properties
    }
    
    public class Gold : ResourceBase {
         public Gold {
             this.value = 40 // or whatever
         }
    }
    
  2. Create instances of a Resource class

    public class Resource {
        string name;
        int value;
    
        public Resource(string name, int value) {
            this.name = name;
            this.value = value;
         }
     }
    
    // later on...
    
    Resource gold = new Resource("Gold",40);
    

With the second option it's possible to fill the game resources from a resources.json file, I kinda like that structure.

New ideas / design patterns / structures are always welcome!

EDIT: It's a little bit like Assassins Creed Black Flag's companion app. See the resource bar on the image below

EDIT 2: I've done some more research on the "load items/resources from JSON file" and found this blog: Power of JSON in Game Development - Items. It shows the best of option 1 and option 2. You're still able to add functionality to each resource :)

enter image description here

share|improve this question
    
Minecraft has separate classes for each resource (not that you should) – MCMastery yesterday
    
@MCMastery ohh is minecraft open-source? I would like to have a look into that structure. And thx for mentioning – Funnydutchman yesterday
    
It is not, but it is always being de-obfuscated for servers... see github.com/Wolf-in-a-bukkit/Craftbukkit/tree/master/src/main/… – MCMastery yesterday
    
@MCMastery Thanks alot! – Funnydutchman yesterday
6  
Don't use a string like that. It's all too easy to mistype "gold" with "glod" or similar, and it's a huge pain to debug. Use an enum instead. – Nolonar 13 hours ago
up vote 38 down vote accepted

Go with the second approach, simply due to the fact that you can introduce new resource types or items at any time without having to rewrite or update code (data driven development).

share|improve this answer
3  
+1 for DDD. This is very fitting for such things as resources. – Kromster yesterday
    
Thank you Mario for confirming! – Funnydutchman yesterday
    
@Funnydutchman if someone's answer helped you, it is customary on Stack Exchange to upvote their answer by clicking the arrow above the number to the left. If an answer helped you the most, you should click the checkmark below the bottom arrow to accept their answer. Both actions give the answerer a bonus in reputation and make usable answers more visible to the community. – Nzall yesterday
2  
I don't see how'd you have to rewrite code with the first way; all you'd do is add a class (unless I'm missing something). – SirPython yesterday
1  
And here is the difference between Object Oriented code and Object Obsessed code. Just because you can create an object hierarchy doesn't necessarily mean you should. – corsiKa 9 hours ago

A rule of thumb is that you use different classes when objects require different code and instances of the same class when the objects only require different values.

When the resources have different game mechanics which are unique to them, it might make sense to represent them with classes. For example, when you have Plutonium which has a half-life time and Rabbits which procreate according to the fibonacci sequence, then it might make sense to have a base-class Resource with a method Update implemented as a no-op and two derived classes HalfLifeResource and SelfGrowingResource which override that method to decrease/increase the value (and maybe also include logic to govern what happens when you store both next to each other).

But when your resources are really just dumb numbers, then it makes no sense to implement them with anything more fancy than a simple variable.

share|improve this answer
    
Thanks @Phillipp for your answer. This is what I was thinking. But the resources won't really change in terms of properties/methods, so I will go with option 2 for now – Funnydutchman yesterday

I would like to add there are two extra options:
Interface: you can consider it if the resource class would be just a "storage" for 5 integers and each other entity would have different logic regarding resources (e.g. player spend/loot, city produces resource). In that case you might not want a class at all - you merely wanted to expose that some entity has a variable others can interact with:

interface IHasResources {
  int Gold { get; set; }
  int Wood { get; set; }
  int Cloth { get; set; }
  // ....
}

class Player : IHasResources { }
class City: IHasResources { }

in addition, this has the upside you can loot a city with exactly the same code as you would loot enemy fleet, promoting code reuse.
Downside is, implementing such interface can prove tedious if many classes implements it, so you might end up using interfaces but not for original problem, solving it with option 1 or 2:

interface IHasResources { 
   IEnumerable<Resource> Resources { get; }
}

Instances (with enum): in some cases, it would be desirable to use enum instead of string when defining resource type:

enum Resource {
   Gold, Wood, Cloth, //...
}

class ResourceStorage {
   public Resource ResourceType { get; set; }
   public int Value { get; set; }
}

this will provide a bit of "safety", because your IDE will give you list of all valid resources when assigning it after writing the dot ResourceType = Resource., in addition there are more "tricks" with enums you might need, like explicit Type or composition/flags which I can imagine to be useful when crafting:

[Flags]
enum Metal {
 Copper = 0x01/*01*/, Tin = 0x02/*10*/, Bronze = 0x03/*11*/
}
Metal alloy = Metal.Copper; //lets forget Value(s) for sake of simplicity
alloy |= Metal.Tin; //now add a bit of tin
Console.WriteLine(alloy); //will print "Bronze"


As for what is best - there is no silver bullet, but personally I would lean towards any form of instances, they might not be as fancy as interface but they are simple, doesn't clutter inheritance tree and are widely understood.

share|improve this answer
2  
Thank you for your answer @wondra I like the enum option and how you made that bronze out of copper and tin ;p – Funnydutchman yesterday
2  
I joined this community specifically so I could up-vote the enum solution. You can also look into using the enum Description attribute to map from some JSON representation of the enum (my-great-enum) to some C# representation of the enum (MyGreatEnum). – Dan Forbes yesterday
    
Apparently I have been out of the Java-loop too long. Since when is it allowed to have field declarations for interfaces? As far as I know those are automatically static and final, and thus not much use for purposes described in the question. – M.Herzkamp 11 hours ago
1  
@M.Herzkamp it is not a field, it a property - and Java does not support properties. Question is tagged C#, C# allow properties in interfaces - properties are methods under-hood after all. I am afraid same goes for flags annotation, not supported in Java though I am not completely sure. – wondra 9 hours ago

If your resources have no business logic of their own, or special case scenarios with how they interact with the environment, other resources (besides trade which you've covered) or the player then option two makes adding new ones very easy.

If you need to consider situations like what would happen if you mix two resources for crafting, if the resources can have vastly different properties (a bucket of water is very different than a lump of coal) or other complex economic interactions, then approach 1 is far more flexible for the engine, but not the data.

share|improve this answer

You should use option 1, which has 3 advantages:

  1. It's easier to instantiate a resource - instead of having to pass the type of the resource as a parameter, you would just do, for example, new Gold(50)
  2. If you need to give special behaviour to a resource, you can by changing it's class.
  3. It's easier to check if a resource is a certain type - resource instanceof Gold
share|improve this answer
    
All the answers have their pros and cons, it's hard to choose which is better. I've made an edit to the question, what do you think of that structure? – Funnydutchman 5 hours ago

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.