What's the best way to define types of objects that gets often reused?

Hello, I’m kinda of stuck trying to decide what’s the best way to organize my code. I need to create several types of objects. I’ll use spells and effects as an example, but the same problem is true for all other kinds of game objects. For example, my character needs to cast many different types of spells, some of which can cast many different types of effects and projectiles.

Right now, I have it set up so that each spell has its own class with all its properties and methods. One of its variables is the “effect”, which will be one instance of a class that extends the Effect class. So this effect could be FireEffect, IceEffect etc. So when it’s time to use this spell, the game might need to many instances of that effect or projectile. So the game will clone the Effect object as many times as it needs to and render them all. For example, the “FrostBolt” spell has a variable that is an instance of the IceEffect object. If the spell needs to cast 2 projectiles, the renderer will clone the instance IceEffect object from the FrostBolt class and render them accordingly.

I can’t help to feel this seems kinda of disorganized and inefficient. But I’m not sure how could it be better? I thought of, instead of using a dummy object for the Effect, instead just using a reference to its class. So the Frostbolt object would have a variable pointing to IceEffect.class instead of an instance of that class, and the game would just create new instances of that class. But if I do that, I would lose the ability to use setters on that IceEffect to modify it for that specific case. What if I need IceEffects of 100 different sizes? I don’t wanna have to create 100 different classes.

How do you guys usually solve these kind of problems? I want to build something that is easy to read and easy to maintain. Specifically, I want an engine that is robust enough so that later on it’s easy for game designers to add new types of spells and effects without much hassle. What’s the best way to approach this problem?

This question has been asked quite a bit… but, I’ll do my best to help you in the right direction.

Factory Design Pattern

It is very similar to this process. You are trying to create multiple spells with the slightly different behaviors. There are a lot of ways one can accomplish this feat.

  • You can use “enums”
  • You can use a scripting language
  • You can use a factory

Try not to use inheritance to make spells, but instead separate them by “type”. Like if you have a Firebolt, Icebolt, and Lightning Bolt…


//Don't do this...

public class FireBolt extends Bolt{}
public class LightningBolt extends Bolt{}
public class IceBolt extends Bolt{}

All you are going to do is create a mess of “instanceof” calls and write a lot of code. It becomes very cluttered quick.


public class Bolt{
//Where 'n' = Normal, 'l' = lightning, 'f' = fire, 'i' = ice;
public char type = 'n';
}

Much easier to read (and also a pretty nice example of how ‘enums’ make things simpler.) When you have different behaviors for attack and ranges, you can set them all in one function.


public void attack{

if(type == 'f'){
      //Do fire attack stuff
}else if(type == 'i'){
      //Do ice attack stuff
}else if(type == 'l'){
      //Do lightning attack stuff
}else{
      //Do default attack stuff
}

It makes it easier to create special attributes for a particular weapon that way, as they are all shared in one type. Anyway, this allows a bit more flexibility and it is… easier to read. If you post some code examples, I may be able to help you go more in depth. But this should help you get started hopefully.

I should have posted that I am already using factories for some game objects, namely characters and levels. But I am trying to get away from it. In fact, my plan for the next week was to refactor away from all my factories. And about a week ago I was replacing all my enums for creating spell effects with the current system of inheritance that you specifically just told me not to :slight_smile:

The reason why I am moving away from factories and enums, is that I have the impression that it would get too messy if there are too many variations to build. Am I wrong to assume that? So far I only have 8 items in my biggest factory, and I already feel it’s clumsy to maintain. So imagine when I have 100 different spells? What about 1000? I want the variation, flexibility and ease to maintain and create new content to be the primary goals of my engine. I want, for example, for one of the members of the team to be able to easily create a new spell he just thought of, and easily add that to the game without much hassle. A factory would force him to edit the factory every time this happens. Ideally, I imagine a system where he could just write a file, drop it on the right directory, and there it is for us to use. I want to move complexity away from the process of creating new spells/characters/levels as much as possible. And if that means complexity needs to go into the engine instead, then it’s an OK trade-off for me.

The problem with enums, lists of types and factories is that it makes this process clumsy, slow and hard to maintain. (or at least that’s my impression, please correct me if I’m wrong) Because all these methods require you to maintain a separate list. Made a new character? Add it to the factory. Made a new spell? Add it to the list of types. I want to avoid having to maintain a list of thousands of different types of spell, each with its own peculiarities. That’s why I’m using the current stupid clone-a-dummy-instance system. Right now the engine doesn’t need to know which spells exist, I just a new FireEffect() to the spell, and it just works.

On my previous project, I went the scripting language route you suggested. But that quickly showed to be too much trouble for too little gain. This time, I thought instead of building a whole system for parsing a scripting language, why not just use Java itself? It’s already a language that fits all my requirements, so instead of writing a script file for a new spell, just write a new Java class for that spell instead.

Anyway, thanks for the help :slight_smile: I don’t have much experience with big factories, so maybe my impression is wrong. The main reason why I’m posting here is to try to get a better idea of the pros and cons of each method, since I don’t have much experience with any of them. So I can better weight the advantages and decide what’s more efficient to use where. And your comment does help me figure it out.

If you care about looking at my actual code. This is my current libgdx project. Here is my factory for characters. And here is one of the classes I’m using my new system on, I basically just create a dummy instance of an implementation of this class, and use getClone() when I new to create a new object of that type.

Ah… So you want a customized system where people can easily drop in spells. This is a lot more specific, and it is something I’ve been playing around with for a while. This is exactly how I believe you should accomplish your goal. (Totally opinionated, so please don’t light your torches…)

  1. Choose a scripting language and stick to it. When it comes to adding anything over 100 different items, you will absolutely need to look into a scripting language to make it easy to edit, and easier to maintain. There is a huge selection of them out there but the ones I like to use are…
  • Lua, Javascript (Rhino) - for action scripts
  • JSON, XML, Binary - for data storage
  1. Make your data generic: You want to make it easy for you to store in the data, and use that data to perform different behaviors in your code. In the later part of my first message, I was touching on how to make this happen. By assigning a number “index” to your spell and weapon abilities, you can fit a lot of different object patterns into one class. You can even mix and match certain elements together.

This is vital for a system that is easy to extend. You can have a very very large number of “integer” indexes which can all represent different weapons, behaviors, etc. All you really need for the data text file is to tell the engine which index to follow. You can essentially make infinite behaviors in this way.

It really is nothing without an example so…

I’ll give you a quick example for weapons and another one for magic. In my previous post, I was giving you a quick feel for what was available, and what I personally would do. However, this one will be a lot more direct.


public class Weapon{

//The weapon name
private String name;

//'N' for Normal, 'F' for fire, 'W' for wind, 'I' for Ice, 'L' for Lightning
public char elementType;

//'C' for Club, 'M' for Mace, 'S' for Sword, 'L' for Longsword
public char wieldType;

//The amount of damage this weapon deals...
public int damage;

//Has a chance to perform critical damage...
public boolean critical;

//I think you get the idea.... etc...
}

and for magic spells…


public class Spell{

//The spells name
private String name;

//'N' for Normal, 'F' for fire, 'W' for wind, 'I' for Ice, 'L' for Lightning
public char elementType;

//'B' for bolt, 'L' for Laserbeam, 'D' for Direct, 'B' for Ball 
public char magicType;

//Number of shots allowed
public int shots;

//The amount of damage this magic spell deals...
public int damage;

//Has a chance to perform critical damage...
public boolean critical;

//Other magic things you may need...
}

By doing this method, it makes it a lot easier to use scripts to load and edit the objects, or even to use Java’s Serializable classes to load and save the data types. So yeah, I don’t recommend inheritance. I went over how you can put this into behaviors previously, so using a mix of these two things should put you in the right track for simplifying your code base to allow for easy to write scripts.

I just want to warn you that this is simplified. If not built well, you can end up with another tangled mess. Try to visualize and plan out how your actions and abilities will be split up before you organize them like this to prevent creating a flurry of singletons. If you use the right balance of classes and index actions, you can have very easy to extend code that is easy to understand… (not an easy thing to accomplish when you are programming).

Bloch’s “Effective Java” offers the advice: “Favor composition over inheritance” (Item 16)

It might be worth reading for some pros and cons on this issue.

I’ve begun to prefer using an interface over subclassing. If possible, I “abstract” the parameter and let the instance interpret the abstraction (e.g., using the range [0, 1) as a parameter when the actual range is quite different or hard to predict). However, this is just general advice. I haven’t implemented a setup for the game scenario in detail like ctomni231 has.

The best example I have, in the project I’m currently working on, is using an interface for “events” in an audio system, so that a call to other parts of the program can be made when a given frame of sound is being played. There are lots of types of commands that might be executed at this point, from synth parameter changes to triggering graphics changes. The interface wrapper is key to making this happen. But again, its a different situation that what you have. (Hmm, I guess what is did here is more like passing a lambda.)

Why not just do it all in data? ie your class handles how the different effects (damage, element type etc) are used but the data structure holds the data for any given spell. This way, to create a new spell, all you’d have to do is add data. If you can produce a formula for how powerful a spell is then your system could create new spells by it self and litter them around your game so you can use them. I’m pretty sure that something like Borderlands 2 doesn’t have a bazillion different classes to match it’s bazillion different types of gun - they’d just do it all in data or more likely a single number that’s used as a seed to generate a repeatable list of random numbers that can then be used to produce the effects of a given weapon.