architecture – Collectible card game, cards and effects

I think the trick here is that many cards have the same type of effects with some variations while some cards have totally unique effects.

Imo, what you should do, is do that.
This is written in typewritten characters, but you can get the idea.

class Effect extends {

static fromArray (game, map, data) {

if (data.type == "SelfDestructEffect") {

return the new SelfDestructEffect (card, data.damagePerTurn);

}

}

}

The SelfDestructEffect class extends Effect {

constructor (game, map, damagePerTurn) {

this.card = map;
this.game = game;

this.game.on ("new-turn", () => {this.onNewTurn ()});

}

onNewTurn () {

this.card.damage (1);

}

}

You create components that describe an effect of a map. You try to make them as customizable as possible so you can reuse them as much as possible between cards. You can still create "unique" components (that is, that will only be used by a single card) for really special effects.

Here are cards.json

{
name: "Berzerker",
type: "Beastman",
components: [

        {
            type: "self-destruct-effect",
            damagePerTurn: 1
        }

    ]
}

Note: The way I deserialize the JSON to make the components is not really scalable. If you want to know how I deserialize the components, you can ask me to write the code.