3
\$\begingroup\$

I'm designing a CCG/TCG game (with the Kotlin language), and I am looking for advice regarding the text of the cards.

First of all, here is an example of one card, defined in XML:

  <card name="Sample Card"
        type="event"
        image="tex-event"
        metalCost="1"
        energyCost="1">
        <text>
            Whenever you destroy a creature, you will gain 3 energy.

            Your stronghold does not produce energy.
        </text>
        <traits>
            <trait name="ScavengeResOnDestroy" type="energy" amount="3"/>
            <trait name="ResFlux" target="self"/>
        </traits>
    </card>

ScavengeResOnDestroy, and ResFlux are direct mappings to class names. Scavenge refers to the first line in the text, and ResFlux to the second.

Before I go on and design a whole lot of cards this way (then again maybe this issue would become a lot clearer AFTER I would design some more cards..) Should I attempt to tie/"hard"-code the text descriptions into the Trait-classes?

The thing is, I find it quite hard problem to "generate" the text for a Trait.. For example ScavengeResOnDestroy could have several targets:

  • Self (Whenever you destroy a creature...)
  • Opponent (Whenever an opponent destroys a creature...)
  • Both (Whenever a player destroys a creature...)

And to complicate things even further, I could very well see a possibility to modify ScavengeResOnDestroy, like so:

  • Whenever you destroy a creature you do not control..
  • Whenever an opponent destroys any creature..."

Now I haven't done much research on the topic yet... but I guess I'd need to build some kind of "sentence generator" (I don't know the correct term)?

Do you think I should stick with simply defining the text for each card, as in the example, or possibly, under the <trait>? And perhaps generate the text only for the simplest traits? Something else?

\$\endgroup\$

3 Answers 3

4
\$\begingroup\$

I would say you should absolutely generate your descriptions procedurally. This will allow you to tweak your abilities and definitions to your hearts content at a later time without having to manually adjust many many descriptions.

Based on what you have shown, I would have somewhere where the Trait was defined not within a specific card, with a parameterised description, something like:

<traits>
    <trait name="ScavengeResOnDestroy" type="energy">
        <parameter name="amount" type="int" default="3"></parameter>
        <text>
            Whenever you destroy a creature, you will gain {parameter.amount} {type}.
        </text>
    </trait>
</traits>

Then, when used on a specific card:

<card name="Sample Card"    ... >
    <text>
        Your stronghold does not produce energy.
    </text>
    <traits>
        <trait name="ScavengeResOnDestroy" amount="3"/>
    </traits>
</card>

The idea here is to define each trait separately, and use some kind of templating language (either a library, or of your own creation) to allow you to dynamically generate your descriptions.

Combine this with parameterisation, the ability for your code to read in parameter values / attributes from the XML to affect how the traits etc. function and you will have the flexibility to change your traits etc:

  • At the global level (the system) - just change the description in one place to match the new functionality and it will be automatically applied across your game.
  • At the card level (tweaks and balance) - just change the parameters passed to the trait, and the description will be automatically updated.

To illustrate what I mean, psudo-code for rendering a card description:

  • Load card definition from XML
  • Look for any referenced traits [Find: ScavengeResOnDestroy]
  • Load trait definition from XML
  • Look for parameter definitions in trait definition [Find: amount]
  • Look for parameter values in card definition [Find: amount=3]
  • Get the <text> element from the trait definition.
  • Look for placeholders in the text [Find: parameter.amount and type]
  • Replace placeholders with their individual values [parameter.amount --> 3, type --> energy]
  • Render text:

Whenever you destroy a creature, you will gain 3 energy.

\$\endgroup\$
1
  • \$\begingroup\$ And it would be quite easy to add selection rules, like if you have a limit to how many times an effect can occur <when par="limit" eq="0"><text>Each time ...</text>...<else><text>The first {par.limit} time(s) ... And not to mention that you probably would want to have the text strings brought in from a localized file so you can support multiple languages \$\endgroup\$ Commented Jun 5, 2015 at 11:30
1
\$\begingroup\$

An option would be to remain quite vague in the description, but to add another section which simply states facts:

<card name="Sample Card"
      type="event"
      image="tex-event"
      metalCost="1"
      energyCost="1">
  <text>
    "Your coffee addiction turns you in a vampire machine"


    Whenever you destroy a creature, you will gain energy.

    Your stronghold does not produce energy.
  </text>
  <traits>
    <trait name="ScavengeResOnDestroyAny" type="energy" amount="3"/>
    <trait name="ResFlux" target="self"/>
  </traits>
</card>

Then the card description would look like:

Sample card

"Your coffee addiction turns you in a vampire machine"

Whenever you destroy a creature, you will gain energy.

Your stronghold does not produce energy.

With this card:

  • Gain target: player
  • Gain resource on destruction of any creature: energy (3)

The text of the card will be hand written by you, but the "facts" will have some factual text chunks written by you, but assembled by your system. For instance, the trait name "ScavengeResOnDestroyAny" is associated with the text chunk "Gain resource on destruction of any creature", and "ResFlux" is associated with "Gain target".

I see these advantages with this approach:

  • You make sure the data used by your game is the data seen by your players
  • It lets you be more vague in the description
  • You don't need to update the description whenever you add a new feature to the cards
  • Integrating small chunks of text that do not need to be integrated with varying quantities (e.g. you will gain 1 energy vs you will gain 2 energies) can make your life easier
  • If you plan to translate your game, you might save yourself a couple of headaches with the last point as well
\$\endgroup\$
1
\$\begingroup\$

Pro:

  • It saves time. Writing the text is one step less you have to do when releasing a new card. This might not sound so much as long as you only support one language, but when you want to add internationalization, you will have to postpone the release until the translation into every supported language is finished, which can be quite a bottleneck when your French guy is sick, your Italian guy on vacation, your German chick just got a baby and you had to fire your Spanish dude for inserting profanity into your card texts and couldn't find a replacement yet.
  • Having the text derived from the game mechanics at runtime has the advantage that you no longer have to make sure that description and mechanics stay in sync when you do balancing changes.
  • Your texts will automatically be consistent between cards. With hand-written descriptions you might run into situations where one card says "kill", another "destroy" and a third "remove" which always means the same thing but could leave the players puzzled if there maybe is a subtle distinction. But with auto-generated texts, two cards which do the same thing will say that they do the same thing.
  • When you translate the game, you also reduce the risk of mistranslations causing a card to do something different than what the text says.

Contra:

  • You will run into situations where the text derived from the game mechanics will turn out to be needlessly convoluted compared to how you could describe the effect with natural language.
  • Because the descriptions are so tightly coupled to the mechanics, they will likely turn out quite sterile and formalized. This is good for understanding the mechanics, but lacks flavor and hurts atmosphere and immersion. This can be mitigated by adding a flavor text to cards - an additional text snippet which is irrelevant for the game mechanics but describes the card in the context of the fiction of the game universe (Magic: The Gathering does this very well - game mechanic effects are described in highly formalized language but flavor texts can be anything).

To get the best out of both worlds

Have a default text derived from the game mechanics but allow an optional XML node in your schema which overrides and/or appends to the auto-generated description with free text.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .