Bit operating + Handling Weapons and/or Spells

Good afternoon,

as the title already has stated, I am trying to handle a large variety of spells (and/or weapons). Because weapons are basically the same idea as spells we will not talk about them. Basically I am new in handling large amount of objects which are almost the same. The only problem is that I do not know, where I need to start. I’ve searched online and found some decent tutorials about oop and Multiple Inheritance. But I’ve not become much smarter after reading that. The only thing I’ve learned is that you need to use Interfaces. But I believe that Interfaces are not that usefull, because you still need to write and copy all the code to do the same thing.

Interfaces
Java Multiple Inheritance

My Current setup is as following:

  • EntitySpell extends Sprite
  • SpellCaster (*)
  • Spell (**)
  • SpellFireBall extends Spell (***)

*SpellCaster:
This class is basically just a timer of the spell it is ‘holding’. It is also holding the level of the spell (but I’ve not implemented the leveling system yet).

[quote]public class SpellCaster {
	private float timer;
	
	Spell spell;
	
	public SpellCaster(Spell spell, int level){
		this.spell = spell;
		this.timer = spell.getCooldown();
	}
	
	public void update(float dt){
		if(timer < spell.getCooldown())
			timer+=dt;
	}
	
	public float getMana(){
		return spell.getMana();
	}
	
	public boolean castSpell(float x, float y){
		if(timer >= spell.getCooldown()){
			spell.castSpell(x, y);
			timer = 0;
			return true;
		} else {
			return false;
		}
	}
}

The castSpell is a boolean, if it get casted, then the mana of the player will be reduced by the manaCost which is located in the SpellCaster

**Spell:
Just a simple abstract class that contains some information about the spell i.e. mana/cooldown (and it passes the castSpell event).

***SpellFireBall:
This is the real problem, I am trying to solve the issues it is providing me with, I don’t want to write the code twice on multiple Spells like i.e. SpellLightningBolt. It is just a waste of space and time, at this moment it is still a small class without many lines of code in it, but when this class is completed it will be filled with information which is on many spells the same (but remember, not all the spells will be the same, i.e. buffs will be targeted to player instead of target to the cursor. These buffs will only work on the player and not on the enemy unlike the spell FireBall).
Because of this I cannot create a superclass Spell that is extended by SpellFireBall. So what is the best way of creating classes like Spells and or Weapons.

Please, if you have dealt with this issue on your project(s), can you tell me what you’ve done? I am not seeking for your codes or whatever, just a summary of what you’ve done or what you think that is the correct way.

If you have any question about the script, what I am doing etcetera, just post a comment to ask :slight_smile:

As always, thanks for reading the post
-RoseSlayer

Use composition instead of inheritance. (More info here).

You shouldn’t have a bunch of classes for different kinds of spells. You should have a single Spell class, and that class should contain (in other words, be composed of) all of the variables necessary to describe the different kinds of spells. Then to create a new spell, you just create a new instance of Spell, not a new subclass.

For example, I could have this class:

public abstact class Animal{
   public void eat();
   public void speak();
}

And then to create animals, I could subclass that class:

public class Cat extends Animal{
   public void eat(){
      System.out.println("I eat a mouse!");
   }
   public void speak(){
      System.out.println("Meow!");
   }
}

public class Dog extends Animal{
   public void eat(){
      System.out.println("I eat a bone!");
   }
   public void speak(){
      System.out.println("Bark!");
   }
}

As I add more animals, the number of classes I need will really add up. Then to add a function to all of them, it’s a lot of copy-pasting. Instead, I can use composition instead of inheritance:

public class Animal{

   private String food;
   private String word;

   public Animal(String food, String word){
      this.food = food;
      this.word = word;
   }

   public void eat(){
      System.out.println("I eat a " + food + "!");
   }
   public void speak(){
      System.out.println(word);
   }
}

Now I don’t need any other classes. I can just create instances of that one class, and they’ll have all the information they need:

Animal cat = new Animal("mouse", "Meow!");
Animal dog = new Animal("bone", "Bark!");

And data driven. I like this sytle for code composition: http://www.java-gaming.org/topics/archtypes-composition-and-code-is-data/26554/view.html

So basically I need to create like two classes:

  • Spell - A class that contains all the code which has a constructor, so you can edit everything
  • Spells - In here you create a spell like: Spell fireball = new Spell(1, true, 12.1f (…))

Well this will safe alot of time, but spells are in this way not unique. So if you have multiple players with a fireball, playerA has fireball(lv.1) and playerB has fireball(lv.14), they will both be calling the same fireball. I know you can do fireball.cast(levelFireball) etcetera, but with weapons this will not work (atleast I don’t believe it will), also using this methode I cannot use different ways of leveling up a spell, for example a spell like enrage(this will buff the player), has other variables then a spell like fireball. If for example upgrading fireball from lv.1 -> lv.2 will give it an unique feature like spawn triple fireballs, how will I handle this in the Spell class. Doesn’t this class get way too large if I create like 20 different levelMethodes?

/Edit/
Didn’t saw you had add some more information in your comment. Thanks again for spending time, but yet I’ve those questions

/Edit2/
I can also create a class that contains vars as:

	public static final byte focusEnemy = 0;
	public static final byte focusPlayer = 1;
	public static final byte focuseAll = 2;

and just call them in the Spells class as:

	Spell fireBall = new Spell(true, focusEnemy);
	Spell enrage = new Spell(true, focusPlayer);

This type of spellHandling is already alot better than I am currently doing, but still is it the best?

What is your way to tackle this problem?
-RoseSlayer (Also thanks for responding as quick as you did!)

Just chiming in here:
There is no such thing as ‘the best’, since different games/applications need different functionality.
You can’t make a ‘fit all’ solution, its simply not possible.

I’m not sure why you need that second class. You might also save a bunch of Spells to a text file or something. How you store them is up to you.

Not necessarily. Maybe your Spell class has a level variable. And why wouldn’t it work with a weapon?

[quote=“roseslayer,post:4,topic:55500”]
Well, maybe you have a couple different classes: Spell, Effect, Weapon. Whatever makes the most sense to you. If two items will have completely different methods, then split them into a different class. If two items will just have different attributes, then they should simply be different instances.

[quote=“roseslayer,post:4,topic:55500”]
Maybe you have another class that represents upgrades like that. Then each Spell could have a List of Upgrade instances. That’s just an example- there are a ton of ways to break your composition down.

[quote=“roseslayer,post:4,topic:55500”]
Like Longor1996 said, there is no such thing as the best. Programming is an art. There are multiple (infinite!) ways to solve any particular problem. Really, you should just go with whatever fits into your head the best. Don’t worry too much about getting it perfect, because it won’t be.

There is no the best, I know but I am trying to gain alot of information about this subject, I’ve had trouble with this in the past. Just need some tactics how other handle it.

I’ve done this kind of large classes in the past and always had some trouble with it. If I create as example a weapon like fireAxe = new Weapon(1, “fireAxe”); and I give this weapon to multiple entities i.e. the player and a creature. If the durability is 1 and I hit a tree with this axe, both my weapon and his weapon will be broken, as the object that is in their hands is reffering to the same object. I don’t know how to handle this type of multipleUsage classes. I know the player can do a Weapon myWeapon = new Weapon(1, “fireAxe”) and the same in the creature. So they have not the same objects held in their hands, this is the way to tackle this problem, but it is not the smartest to write the constructor of your weapon in the main class (if you get what I mean with this). I want a global class that has easy access to all of the different weapons. So it only takes one line (withouting adding variables yourself), to take the weapon and use it (without duping it). How are you handling that?
/Edit/
Well I know you can do the following to get a weapon without duping it,

public Weapon createFireAxe(){return new Weapon(1, "fireAxe");}

but this isn’t a great way of getting a specific weapon.

-RoseSlayer

Instead of using a class as a collection of variables, just use a Collection:

// in this case spells are referred to by name
public static Map<String, Spell> spells = ...

[quote]to take the weapon and use it (without duping it).
[/quote]
If multiple things have to have different states of some thing, you cannot get around having copies of some form. Might as well go the direct and simple route.
You could make a convenience function for getting fresh spell instances if it really bothers you:


public static Spell getSpell(String name) {
    if (!spells.containsKey(name)) throw new IllegalArgumentException(...);
    return spells.get(name).copy();
}

In this fashion, spells are almost like factories for themselves, if you like the design pattern lingo.

EDIT: your edit is also creating copies, FYI. It’s also not parametric over spells, aka not flexible.
Also, in case it’s not obvious, that spells map and it’s contents are to be considered immutable once built.

I think it really depends on how your characters obtain these weapons and spells in the first place. Are they located in the game world (on the map or in a chest or something)? Are they obtained automatically? Are they there from the beginning?

The answer to that question really determines how you store your instances. Maybe you store your game world in a map file, and the weapons are predefined in there as well. Maybe you procedurally generate your game world, and you’d do the same type of generation for your weapons.

But yes, I would imagine that each instance represents a specific weapon: if two characters are holding two different axes, then that’s two separate instances that you’re going to have to create using the new keyword. When you create those instances is decided by my second paragraph. The only reason two characters would share a single instance of a Weapon is if they were somehow both carrying the same exact “physical” weapon, which doesn’t seem likely.

What if players can build their own spells at runtime, or design their own weapons? For these cases, a static inheritance-based approach would never work.

With Java 8 the landscape of inheritance vs composition ideological conflicts has subtly changed with the advent of default methods in interfaces.

Cas :slight_smile:

Yeap. And functional interfaces. Take a bioware or elder scrolls like game, using an archtype system all items, monsters, effects, etc. could be defined using only inheritance in around a dozen classes. (give or take given some design decisions). Player’s designing their own doesn’t add any problems here either. Who is creating the data does matter for the base system…it’s all just data.

This excludes all “game mechanic” code. But in java8 that can be however many static utility (or enum classes) one needs. Each of these is more or less independent of everyone else. Java 8 drastically reduces the number of classes required due to functional interfaces.

The weapons are obtained by the following: Crafting, trading/buying, drops
The spells are obtained by the following: Monsters have a very small chance to give the player a spell that fits the monster unique ability (atleast if the player has the requirments) if killed.

Well this doesn’t help me much, unfortunately…

This is exactly what I am trying to achieve, do you know how this work and give some small information about it?

As always, thanks for the posts and time spended.
-RoseSlayer

Then those times are when you would use the new keyword to create instances of a Weapon. When you craft a weapon, you’re creating a Weapon instance. When you trade or buy, you’re probably moving a pre-existing instance from one List (whoever owns it originally) to another List (the player’s list of weapons). When you spawn a monster, you probably create any weapons it might drop ahead of time (or do it when the monster dies, either one works).

Similarly, you’d create a new instance of the Spell class whenever a player earned that spell. You wouldn’t need to share instances between players, and you wouldn’t need one master class responsible for creating spells.

I know this sounds terrible, but the problem is I don’t know how to create a new instance of a spell without hardcoding the atributes into the enemy/player class…

Spell fireball = new Spell(1, false);

Because of this I have always used a static class that contains the weapons/spells. If I faced an constructor that doesn’t require any attributes I am still confused with making a new instance of a spell because I will hardcode it like:

Spell fireball = new SpellFireBall(); 

/Edit/
Nvm, just need to implement cloneable and clone it with the list you’ve already provided, am I right?

public static Spell getSpell(String name) {
    if (!spells.containsKey(name)) throw new IllegalArgumentException(...);
    return spells.get(name).copy();
}

-RoseSlayer

Wouldn’t you still be hardcoding them in your static class?

Either way, the answer is to procedurally generate instances by using random values.

What exact attributes are you talking about? Can you give us some specific examples of how you would do it your old way?

I did not read the whole thread so it’S possible, that someone else allready wrote the same thing…
Create classes only, if the logic is different, if the spells just have different stats, only use different data.
For example:
A Fireball does 10 dmg, costs 10 mana and has a posibility to give a burn-debuff
A Lightningbolt does 15 dmg, costs 20 mana and has posibility to paralyze the enemy

Both Spells can be of the same class, just with different data.
The data could be stored in a file (for example as JSON).

Many things could allready be solved this way. For example a Healspell might just have negative dmg.
But for some speels you still might need a different class.

I got the same problem as you a while back. My current solution takes the data driven route.
Each ability/skill/spell/chant/martial arts can be boiled down to formulas. The more complex an ability has to be, the more values you have to provide. I haven’t implemented status effects like cripple or bleed, but here is the general direction my skills work:


public class Skill implements Serializable{

	private static final long serialVersionUID = 1L;

	
	public final String name;
	public final String description;
	
	private CombatAnimation animation; 
	
	public final int staminaCost;
	public final int initCost;
	public final int power;
	public final int strikeCount;
	private final int critModifier;
	private final int hitModifier;
	private final int armorModifier;
	
	public final boolean isRampUp;
	private final int rampUpModifier;
	
	public final String dmgType;
	
	public final int requiredLevel;
	
	public Skill(ConfigBlock config, String skillName) {
		name = skillName;
		description = config.getStringProperty("description");
		requiredLevel = config.getIntegerProperty("requiredLevel");
		
		animation = Assets.instance.animationMap.get(config.getStringProperty("animation", "slash01"));
		
		staminaCost = config.getIntegerProperty("staminaCost");
		initCost = config.getIntegerProperty("initCost");
		power = config.getIntegerProperty("power");
		strikeCount = config.getIntegerProperty("strikeCount", 1);
		critModifier = config.getIntegerProperty("critModifier");
		hitModifier = config.getIntegerProperty("hitModifier");
		armorModifier = config.getIntegerProperty("armorModifier", 100);
		isRampUp = config.getBooleanProperty("rampUp", false);
		rampUpModifier = config.getIntegerProperty("rampUpModifier", 0);
		dmgType = config.getStringProperty("damageType").toLowerCase();
			
	}
	
	public ArrayList<CombatAction> getActions(Character origin, Character target) {
		ArrayList<CombatAction> actions = new ArrayList<CombatAction>();
		
		origin.reduceStamina(staminaCost);
		origin.getTurnTimer().reduceValue(initCost);
		
		for(int swings = 0; swings < strikeCount; swings++) {
			CombatAction newAction = new CombatAction(target, CombatModifier.DAMAGE, animation);
			boolean isHit = MathUtilities.moreAccurateRandom() >= (target.getEvasion() - hitModifier);
			boolean isCrit = MathUtilities.moreAccurateRandom() <= (origin.getCriticalHit() + critModifier);
			
			newAction.isMiss = !isHit;
			newAction.isCrit = isCrit;
			
			newAction.value = power; // Get base power of the used skill
			newAction.value+= isRampUp ? (rampUpModifier + swings) : 0; // Apply ramp up power
			newAction.value*= isCrit ? Constants.COMBAT_CRIT_MODIFIER : 1.0f; // Apply critical hit modifier
			
			newAction.value*= 512 - (target.getDefense() * (armorModifier/100.0f) ); // Apply armor reduction from target
			newAction.value*= origin.getAttack() / (16f * 512f); // Apply attack from origin
			
			actions.add(newAction);
		}
		
		
		return actions;
	}
}

I wrote my own configuration handler/writer but I hope the idea behind is clear.
These skills are associated to masteries and the masteries are saved in compendiums for each player character.

Weapons (and equipment in general) is somewhat more complicated. I’m a wow player, I have special needs how equipment has to work and this is my pitfall …

I’ll do a mini-write up.

It’s hard to talk about anything without knowing what you want to do. Let me give an example. Let’s say a 3D 3rd person RPG.

Player moves mouse over bag on ground, left clicks and
Player moves mouse over an NPC, left clicks and
Player moves mouse over door, left clicks and
Player moves mouse over lever, button, whatever other thing the game might have and needs to respond to a left click, left clicks and

Let’s call all the things the player’s is clicking on entities. Let call the left click action “interact” and is an action handler. An action handler is data. Now NPC (which are entities) can perform “interact” with other entities. What’s the difference between the player(s) and NPCs? Nothing…other than their AI. Players are entities as well. Call the entity being clicked-on/interacted with “self” and the one performing the action “other”, then self has an action handler which does the appropriate “something”.

Why? What’s hard about weapons or equipment? What’s the difference between weapons and equipment? Are they really different from any item that can be found in an entity’s inventory?

Why a new instance? Is there entity specific data per spell? If yes, then one could factor out the common part and share the common. If no then there’s no reason to have identical copies.

Note I’m not saying how anybody should do something…the game design and want makes sense to the programmer dictates that.

Sure, there could be. OP has said that the spells can be leveled up, and I imagined this as an instance with an int level variable. But it’s not hard to imagine other specific data: maybe one person’s fireball is pink, and another’s is green. Maybe weapons wear out with use.

Like we’ve said, there are a million ways to do this. There isn’t a single best approach. But it seems like maybe OP is new to OOP, so I was trying to keep it simple.