Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

Post What's on Your Mind

@Xi,
when you were talking about having more classes slowing the java program down, how significant is it?
because for what i'm working on, i need to make a minimum of ~120 cards, and each of them have their own behaviour that is unique.
Unique enough for me to want to program them all individually, anyway >.>

If I made each of them their own class which descended from a parent GameCard class, would the slowdown be noticable?
In the whole game, there's a total of ~830 cards, but I doubt I'd ever implement them all.

EDIT: in other news, i ran one of my songs through gxscc and found that the chorus sounded pretty good. probably because you can actually hear the harmonisation.

EDIT2: im considering making a little scripting syntax of some sort instead and utilising Runnable rather than coding every single card. I'd prefer to code them manually, but it feels like a dumb move, even though I need the control it grants.
 
ZenVirZan":1ypixmu1 said:
@Xi,
when you were talking about having more classes slowing the java program down, how significant is it?
because for what i'm working on, i need to make a minimum of ~120 cards, and each of them have their own behaviour that is unique.
Unique enough for me to want to program them all individually, anyway >.>

If I made each of them their own class which descended from a parent GameCard class, would the slowdown be noticable?
In the whole game, there's a total of ~830 cards, but I doubt I'd ever implement them all.
Every time the GC fires the more classes you have, even if they aren't being used, will make the hitching worse. It's alleviated by how powerful the machine is, so on a powerful PC it would make practically no difference. On a mid-range Android phone it will certainly be noticeable if you have 1 class for each type of card.

Minecraft has subclasses for some of their varying object types (mostly for different rendering styles) and the GC time on that game is terrible. Gets worse with each new update as they add more mobs and blocks.

Even if the performance impact was zero, you shouldn't be doing 1 new class for each type of card. Everything should be components and parameters where possible. Sort out what stats your cards have and have a base card type and a card instance type;
Java:
<div class="java" id="{CB}" style="font-family: monospace;"><ol>CardType dragon = <span style="color: #000000; font-weight: bold;">new CardType().setTitle( "Dragon" ).setHealth( <span style="color: #cc66cc;">100 );

 

CardInstance dragonInstance = <span style="color: #000000; font-weight: bold;">new CardInstance( dragon ); // dragon instance will now point to the type of card it is

dragonInstance.setDamage( <span style="color: #cc66cc;">50 );

myDeck.addCardInstance( dragonInstance );
This kind of technique is what Minecraft modding tutorials tend to suggest to alleviate the problems with sub-classing for every new type.

In Minecraft's case, they really should move the different rendering into instance of runnables, so they'd be;
Java:
<div class="java" id="{CB}" style="font-family: monospace;"><ol>Renderable renderable = <span style="color: #000000; font-weight: bold;">new Renderable(

@Override

<span style="color: #000000; font-weight: bold;">public <span style="color: #993333;">void render( objectInstance ) {

    // OpenGL code goes here

    // objectInstance.getPositionMatrix(), objectInstance.getType().getTexture(), etc

}

);
That way it's the instance's methods that are overridden rather than an entire class that gets registered on the GC.

EDIT: The way you'd do spells would be similar to that "Renderable" example;
Java:
<div class="java" id="{CB}" style="font-family: monospace;"><ol>Spell fireBreath = <span style="color: #000000; font-weight: bold;">new Spell().setName( "Fire Breath" );

fireBreath.setBehaviour( <span style="color: #000000; font-weight: bold;">new SpellBehaviour(

@Override

<span style="color: #000000; font-weight: bold;">public <span style="color: #993333;">void doSpell( GameState gameState, CardInstance caster, CardInstance target ) {

    // Crazy maths, etc to do with cards, game state, etc

}

) ).setDescription( "Breaths fire like a boss." );

 

dragonType.addSpell( fireBreath ).addSpell( fly );

If the spell requires a state to be stored (like charge up before firing) then apply the state to the casting card with a component;
Java:
<div class="java" id="{CB}" style="font-family: monospace;"><ol> 

@Override

<span style="color: #000000; font-weight: bold;">public <span style="color: #993333;">void doSpell( GameState gameState, CardInstance caster, CardInstance target ) {

    [url=http://www.google.com/search?hl=en&q=allinurl%3AComponent+java.sun.com&btnI=I%27m%20Feeling%20Lucky]<span style="color: #aaaadd; font-weight: bold;">Component[/url] fireBreathCharge = caster.getComponent( "fireBreath_charge" );

    <span style="color: #b1b100;">if ( fireBreathCharge == <span style="color: #000000; font-weight: bold;">null ) {

        fireBreathCharge = <span style="color: #000000; font-weight: bold;">new [url=http://www.google.com/search?hl=en&q=allinurl%3AComponent+java.sun.com&btnI=I%27m%20Feeling%20Lucky]<span style="color: #aaaadd; font-weight: bold;">Component[/url]( "fireBreath_charge" );

        caster.addComponent( fireBreathCharge );

    }

    <span style="color: #b1b100;">if ( fireBreathCharge.incrementInteger( "charge" ) == <span style="color: #cc66cc;">10 ) {

        fireBreathCharge.setInteger( "charge", <span style="color: #cc66cc;">0 );

        target.applyDamageHealth( <span style="color: #cc66cc;">500 );

    }

    caster.applyDamageMana( <span style="color: #cc66cc;">10 );

}

 
Obviously don't copy this model 1:1 because it's not going to be perfect, but it's going to be the most expandable way to do things. Modern game engines all use this component paradigm due to problems with OOP in games - Java just happens to benefit from it due to the too-many classes problem.
 
I've already got a DataCard and a GameCard, which is the instancing aspect handled.

The design I initially came up with was to make a bunch of triggers - onCast, onAttack, onDefend, onTurnStart, onTurnEnd, onKill, etc. which were in the parent class. These can then be tested (along with many, many other methods that return based on the state of other parts of the card) together in groups and it makes game flow very simple, while the cards still stay adaptable. The reason why I want this control is to do things like the following:

A card's on death might be to draw 3 cards, show them to your opponent, take one and discard 2 for example.

Another would be to gain +1000 attack for every fire card on the field during the attacking part of the turn.

I want to be able to add these in without having to change my game flow at all, and they'd be set up to add events to a queue from within the onX methods, and I can do logic there as well, to do different things based on the current game state. The events are complex enough to be too hard to pass simply as variables, but simple enough to not force me to program them individually.

I'll think over that component concept you shared, thanks. That looks like something similar to what I'd need to do.
 
To do that with components you'd have something like;
Java:
<div class="java" id="{CB}" style="font-family: monospace;"><ol> 

CardType dragonCard = <span style="color: #000000; font-weight: bold;">new CardType().setBlahBlah...;

 

dragonCard.setOnAttack( <span style="color: #000000; font-weight: bold;">new Behaviour(

@Override

<span style="color: #000000; font-weight: bold;">public <span style="color: #993333;">void run( GameState gameState, CardInstance caster ) {

    caster.addAttack( <span style="color: #cc66cc;">1000 * gameState.getCardsOnField().count() );

}

));

 
 
And then when a card instance appears the call would be; cardInstace.onAttack(); which does a null check to see if the Behaviour is set before calling the run( gameState, cardInstace ); method.

One other benefit with component programming is that it's somewhat easier to dump and load this stuff to file. You can generate JSON that describes the variables involved and the runnables would be from a selection of named hard-coded instances or through a scripting language if you swing that way.
 
So in other words, use Anonymous classes for everything?
EDIT: Alright, so that works really well for proceedures. What about if I need a different way of returning a value between cards?

eg. generally speaking, isBlocker(GameCard attacker) would return the value of flagBlocker for the object it's called on.
but for one card, isBlocker(blah) is determined by, say, the attacker's elemental type.
So it becomes more like (if I was to code each card)

public boolean isBlocker(GameCard attacker){
return (attacker.dataCard.civ == "water" ? flagBlocker : false);
}


Is there a way you'd suggest I do this with Anonymous classes, or something similar?

EDIT2: Alright, so I'll use anonymous children of this EventTrigger class to record actions with #run, and when I need to calculate booleans and integers, I'll do the same but use #integer and #bool instead. I can get away with this because I pass the caster (the calling object) to it, which has all of its attributes public, saving me from having to pass them as arguments.
21493c9184.png
 
Okay, so I've decided to bring forward my New Year's vows ( :toot: ), given that I almost killed myself driving last night ( :eek:: ) and the general downward spiral my life has taken since my girlfriend dumped me ( :eek:uch: ). So without further adieu, I will quit drinking ( :cheers: ) and smoking cigarettes (drugs of any kind really :smoke: ) starting today. That and I should probably continue exercising ( :fap: ) and take my pills, none of which I've done the past two weeks. I feel otherwise I will really end up killing myself ( :boo: or maybe :devil: ). Maybe I should also schedule an appointment with my psychiatrist...

Bring it on, 2016 ( :box: ). You can't possibly make things worse.

(Also, I hope the emoticons made this post less depressing.)
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top