Skip to main content

Card Action

Basic principle​

The main concept of a card action is that it accepts inputs and returns outputs, which can be used again as inputs for subsequent actions. During this process of input and output, an action can run logic that affects the game state.

Here is an example of the three properties: input, game state alteration and output.

  • Input (or params): Card action XY takes an input of type "player" as well as a number.
  • Game state alteration: These two input values update the game state -> The player receives N amount of health points from the number input.
  • Output: The final health point number is outputted and can be used by other actions again as an input value.

An action might not always consist of all three properties. Some actions might not change the game state, and are simply for the sake of calculating an output, while others might have no output but affect the game state.

Types​

A card action can serve multiple main purposes. For these purposes, we can categorize it into different types.

See the type definitions.

  • Trigger: A trigger is the entry point for a card flow.
  • Accumulator: An accumulator is what we call card actions, which don't make any game state changes. Their main purpose is to accumulate data and provide it as output (possibly calculated from inputs).
  • Server prompt: A server prompt is what we call an action that will await a game server prompt, which awaits a player to make an action (for example select some cards, which then can be used as output).
  • Alteration: An alteration is an action that affects the game state. These are usually the main abilities of a card. For example, it could alter a player's health points.

Schema​

There are two sides to a card action. The schema definition of the card action, and the composed action by the user.

The schema definition for an action defines the input params and output params it accepts. Part of this definition is the name of it and the value type.

See the general type definition in the code.

Here is an example of a schema for an action foobar:

{
"foobar": {
"type": "alteration", // this action is of type alteration
"params": {
// has an optional input named "foo-number"
"foo-number": {
"type": "number", // the input is of type number
"optional": true, // it is optional -> the user might not pass a value to this input
"description": "a foo number that will do some maths and other fun stuff" // an input also needs a description for what it is used
},
// has a required input named "foo-card"
"foo-card": {
"type": "card-collection", // the input is of type card-collection
"optional": false, // it is optional -> the user might not pass a value to this input
"description": "the cards are apparently also used by this action to do fun stuff" // an input also needs a description for what it is used
}
},
"output": {
"foo-card": "card-collection", // has an output named "foo-card" of type card-collection
"foo-player": "player-collection" // has an output named "foo-player" of type player-collection
}
}
}

You can find a list of possible types in the code.

User composed action​

The schema only defines the shape of an action. It defines how it renders in the Front-End during the creation of a card flow.

When the user actually builds a card, he will need to define the actual inputs for the action (unless they are optional of course).

The input values can be either be:

  • an actual static value (for example 42 for an input of type number)
  • or a variable referencing the output of a previous action in the flow (for example {111.output-xy-number})

Notice 111 inside the variable. This is the ID for the action for which the output is referenced, while output-xy-number is the name of the output.

See the types in the code.

Here is an example of a card flow consisting of two actions:

[
{
"id": 111,
"type": "on-card-death", // the action from the schema (probably an action of type "trigger" in this case)
"params": {} // triggers usually don't have any input params. But they might have output params, such as a "player-collection" -> the owner of the card which triggered the flow. -> This information is contained in the schema, not the composed action.
},
{
"id": 222,
"type": "foobar", // the action from the schema (in this case the "alteration" from the schema example from above)
"params": {
"foo-number": 42, // here the user defined a static input of `42`
"foo-card": "{111.owner}" // this references an output called `owner` from the `111` action (the trigger in this case)
}
}
]

Card Action handlers​

@todo

The Front-End UI​

The card creator is what is used in the Front-End to build card flow out of card actions.

A add a card action to the flow, there is the flow item chooser component.

Once added to the flow, each item in the flow will render as the CardFlowItemComponent component. Since each item can contain input params of different types, there is the CardFlowItemParam component which simply maps to a specific input component, based on the param type.


<code references>​

General:

Front-End UI: