A4 Engine v2.4 Reference

The A4 Engine is a small engine for 2D action RPG games created by Santiago Ontañón (2014). Versions up to 1.2.2 were created in JavaScript. The current version, 2.4 has been created in C++, but a JavaScript version still exists (cross compiled to JavaScript via Emscripten). The A4 Engine was created specifically to test procedural content generation techniques, and thus, games are completely defined as xml files that are loaded by the game engine for execution. This page is NOT supposed to be a tutorial, but just a reference of the syntax used in the game definition files.

To create a game, the following set of files are needed:
The engine ships with an example game (Aventura 4), that contains all of these files. The main file, the game definition file, is called aventura4.xml and includes references to all the other files.

Outline of the remainder of this page:

Game Definition File

The Game definition file has the following structure:

<A4Game name="My Game Name" title="My Game Title" subtitle="My Game Subtitle"
        allowSaveGames="true/false"
        allowTalking="true/false"
        allowInventory="true/false"
        allowMagic="true/false"
        allowStats="true/false">
  <titleImage>title.png</titleImage>
  <story>
    <line> ... </line>
    ...
    <line> ... </line>
  </story>
  <ending id="ENDING_ID">
    <line> ... </line>
    ...
    <line> ... </line>
  </ending>
  <tiles sourcewidth="32" sourceheight="32" targetwidth="32" targetheight="32">
    <types file="graphics.png">
    ...
    </types>
    <seeThrough file="graphics.png">
    ...
    </seeThrough>
    <canDig file="graphics.png">
    ...
    </canDig>
    <animation name="coinpurse" dx="1" dy="1" period="4" looping="false" file="graphics2x.png">9</animation>
    <animation name="curious" dx="1" dy="1" period="8" looping="true" file="graphics2x.png">74,-1</animation>
    <animation name="scared" dx="1" dy="1" period="8" looping="true" file="graphics2x.png">84,-1</animation>
    <animation name="angry" dx="1" dy="1" period="8" looping="true" file="graphics2x.png">94,-1</animation>
    <animation name="tired" dx="1" dy="1" period="8" looping="true" file="graphics2x.png">104,-1</animation>
    <animation name="happy" dx="1" dy="1" period="8" looping="true" file="graphics2x.png">75,-1</animation>
    <animation name="magic missile" dx="1" dy="1" period="8" looping="false" file="graphics2x.png">114</animation>
    <animation name="fireball" dx="1" dy="1" period="8" looping="false" file="graphics2x.png">124</animation>
    <animation name="incinerate" dx="1" dy="1" period="8" looping="false" file="graphics2x.png">134</animation>  

  </tiles>

  <characterDefinition file="characters1.xml"/>
  ...
  <characterDefinition file="charactersn.xml"/>

  <objectDefinition file="objects1.xml"/>
  ...
  <objectDefinition file="objectsn.xml"/>

  <map file="map1.xml"/>
  ...
  <map file="map1.xml"/>

  <player class="PLayerClass1" x="12" y="14" map="0"/>
  ...
  <player class="PLayerClassn" x="12" y="14" map="0"/>

  <onStart>
  ... [script] ... 
  <onStart/>

  ... [story state and event rules] ...

</A4Game>
      
The tags have the following meaning:
Additional event rules can be added, which will be checked at each frame of the game during gameplay.

back to top

Character Definition Files

Character definition files are used to define player characters, NPCs and enemies. Each file has the following structure:

<Characters>
  ...
  <CharacterClass class="MyCharacterClass" super="SuperClasses" name="My Character Name">
    <animation name="animation-name" dx="1" dy="1" period="4" looping="false" file="graphics.png">animation sequence</animation>
    ...
    <animation name="animation-name" dx="1" dy="1" period="4" looping="false" file="graphics.png">animation sequence</animation>

    <attribute name="attribute name" value="attribute value"/>
    ...
    <attribute name="attribute name" value="attribute value"/>

    <items>
    ... [objects in the inventory] ...
    </items>

    ... [story state, event, conversation and inference rules] ...

    <onStart>
    ... [script] ... 
    <onStart/>
    <onEnd>
    ... [script] ... 
    <onEnd/>
  </CharacterClass>
        
The tags have the following meaning:
Additional event rules, conversation graph and inference rules can be added, which will be checked at each frame of the game during gameplay. These define how the characters behave in front of story events, or when other characters talk to them. All of these rules have access to a common "memory" of the things the character knows. This is further described in the AI section.

back to top

Object Definition Files

When defining maps and characters, you might want to add items to the inventory of characters, or objects to the maps, etc. A4 allows you to define items/objects using XML syntax, for example:

      <object class="HPPotion" completeRedefinition="true">
        <animation name="idle" dx="1" dy="1" period="1" looping="false" file="graphics.png">1</animation>
        <attribute name="ID" value="657"/>
        <attribute name="name" value="HP Potion+10"/>
        <attribute name="gold" value="25"/>
        <attribute name="takeable" value="true"/>
        <attribute name="usable" value="true"/>
        <attribute name="hp" value="10"/>
      </object>
    >
Where the class of item/object is defined in the "class" attribute, "completeRedefinition" should be set to "true" if we want to redefine completely an object (i.e., if we want the A4 Engine to ignore the object definition file for this type of object). The subtags are equivalent to those required to define object types in the object definition file. The object definition files have the following structure:

<Objects>
  <ObjectClass class="MyObjectClass" super="SuperClasses" name="MyObjectName">
    <animation name="animation-name" dx="1" dy="1" period="4" looping="false" file="graphics.png">animation sequence</animation>
    ...
    <animation name="animation-name" dx="1" dy="1" period="4" looping="false" file="graphics.png">animation sequence</animation>

    <attribute name="attribute name" value="attribute value"/>
    ...
    <attribute name="attribute name" value="attribute value"/>

    <items>
    ... [objects in the inventory] ...
    </items>

    ... [story state and event rules] ...
  </ObjectClass>
  ...
</Objects>  
    
The tags have the following meaning:
Additional event rules can be added, which will be checked at each frame of the game during gameplay. Vehicles allow characters that have "canSwim" set to false to move through water (if the vehicle has canSwim=true) and characters that have "canWalk" set to false more through land (if the vehicle has "canWalk=true").
Vehicles have hit points, when a character is attacked while in a vehicle, the vehicle takes the damage. When the vehicle loses all of its hit points, it is destroyed, and drops the character. If a character that cannot swim is dropped in the water, it dies (analogously for a character that cannot walk, dropped on land).
A4 includes a set of default item and object classes that can be used in any game. Specifically, A4 incorporates the following default item/object classes:
back to top

Map Definition Files

A4 expects the maps to be in an XML format that extends that of the TILED map editor (TMX). When creating a map, make sure to add a property called "name" that takes the name of the map as a value. If you open any A4Engine map in TILED, it might be able to load and display the tile layers. However, if you save the map, it will lose all the scripts, and additional information required by the A4Engine. So, this is not recommended.

Maps are organized in "layers". It is recommended that you define two layers in a map (but you can define more if you want). The first layer will be used for the background tiles and objects (e.g. floor, grass, water, etc.), and the second layer for the foreground objects (walls, trees, etc.).
Each layer is defined as:

    <layer name="Tile Layer 1" width="WIDTH" height="HEIGHT">
    <data>
      <tile gid="TILEID"/>
      ...
      <tile gid="TILEID"/>
    </data>
    </layer>
    
Where each "tile" line corresponds to one of the WIDTH*HEIGHT tiles in the map (starting from the top-left corner, and proceeding line by line). The TILEID is the number of the tile in the graphics file (Starting from the top left). Everything that does not have any behavior (floor, walls, trees, rivers, etc.) is defined in the tile layers. Everything that has a behavior (enemies, items that can be picked-up, doors that can be open, etc.) does in the object layers. After you define the tile layers, you need to add the object layers. An object layer is defined as:

    <objectgroup name="LAYER NAME" width="WIDTH" height="HEIGHT">
      ...
      <object class="OBJECT CLASS" x="X" y="Y" width="W" height="H"/>
      ...
    </objectgroup>
    
Notice that the x, y, width, and height of objects is defined in pixels. Object definition follows the exact same format as when defining items in the inventory of characters, as described above. In addition to the object classes that come predefined with A4Engine, and those that you define in the object and character definition files, in maps, you can specify objects of three additional classes: For each object defined in any object layers, additional event/story/inference rules, scripts, items, etc. can be added in the same way as in the object and character definition files.

Maps defined in TILED can have a set of "properties". It is very important that you define a property giving a name to your map, like this:
<properties>
  <property name="name" value="[MY MAP NAME]"/>
</properties>
Each map must have a different name, since the name is the internal ID that the A4Engine uses to differentiate maps.

Finally, notice that TILED can only be used to author the tile layers. Object layers and other properties of the maps cannot be added in TILED, since it does not support the extended XML format used by the A4 Engine. So, after the map has been saved from TILED, in addition to objects, you can add additional event rules, and an onStart tag like in the Game definition file.

back to top

AI

A4 provides some basic functionality to define the AI of Enemies and NPCs in the game. Specifically, the AI of a character is defined based on the following elements:
The predefined types of WMEs that the A4 engine uses internally are (these WMEs can be used by any of the behaviors or rules to store information, and act as a "blackboard"): Perception WMEs are created with the minimum activation (they are only active while the object is being perceived), action perception WMEs are created with an activation of 100 (i.e., the character remembers the action for 2 seconds).

back to top

Scripts

A4 allows the specification of scripts for many tasks. A script in A4 is a sequence of actions, where each action is defined in the following way:

<actionName ...action attributes...>
  ... sub-actions ...
</actionName>  
    
The list of actions that A4 supports is the following:
All of these actions return "true" or "false" if they could or not be executed successfully, and thus, all can be used as part of the condition of an if-then-else. An if-then-else returns the value of the last action executed internally.

back to top

Event Rules

Event rules are rules that are checked at each execution cycle, triggered by certain events. An event rule is defined as follows:

<eventRule event="EVENT" once="true/false">
    ... sub-actions ...
</eventRule>
      
When the event "event" is triggered, this rule will be executed. Currently, the engine supports the following events: You can specify whether this rule has to be executed only once, or each time this value is observed with the attribute "once" (default is "false").

back to top

Conversation Graph

Each character (e.g., NPC or enemy) can have a conversation graph that controls how does the character react while talking with other characters. You can create conversation graphs in two different ways: via a conversation graph file, or via adding individual conversation graph transitions. The first allows you to define a complete conversation graph in a separate XML file. The second allows you to specify a conversation graph transition by transition directly in the character definition. The recommended way to define conversation graphs is as follows: define one or more generic conversation graphs on separate files, and then when defining a new character, you load one conversation graph, and then complete it by defining additional conversation graph transitions.

A conversation graph file in an XML file defined as a set of states where each state has a name and a set of transitions. It is defined in XML as follows:

<conversarionGraph>
  <state name="STATE 1 NAME">
    <transition actor="ACTOR" performative="PERFORMATIVE" state="TARGET STATE" consume="CONSUME" topic="TOPIC">
      ... scripts ...
    </transition>

  </state>
  ...
  <state name="STATE n NAME">
    ...
  </state>
</conversarionGraph>
      
Each state requires specifying a name, and a set of transitions. Each transition can specify: Most of the parameters above are optional. If no actor, performative or topic are specified, that means that any actor, performative or topic can trigger this transition. If no target state is specified, then it is assumed that the transition does not change the state. Consumes by default is "true".

When specifying a character, the following statement can be added to load a conversation graph:

    <conversationGraph name="XML FILE NAME"/>
    
Additionally, character-specific transitions can be added to the loaded conversation graph as follows:

    <conversationGraphTransition from="SOURCE STATE"  actor="ACTOR" performative="PERFORMATIVE" state="TARGET STATE" consume="CONSUME" topic="TOPIC">
      ... scripts ...
    </conversationGraphTransition>
      
Basically, it is the same format as the transitions in the conversation graph files, except that a "from" parameter has to be specified (the name of the origin state).

back to top

Inference Rules

Inference rules determine additional inferences that characters (e.g. NPCs) can make, based on the content of their memory. An inference rule is defined as:
<inferenceRule premise="WME1, ..., WMEn" conclusion="WME" frequency="FREQUENCY" activation="ACTIVATION" once="true/false" cooldown="COOLDOWN"/>
At each AI update cycle, the character will have probability "FREQUENCY" of checking this rule (this is to avoid checking rules at each cycle, and also this can control the "intelligence" of different characters). If all the WMEs in the premise are satisfied in the memory of the character, then the conclusion WME will be added to the memory with activation value "ACTIVATION".
For example, if premise = "attack(?1,?2),friendly(?2)" and conclusion="unfriendly(?1)", then when the character sees someone attacking a friendly character, it will be believe that the attacker is unfriendly.
Additionally, parameters "once" (to set if a rule should only be executed once), and "cooldown" (number of game cycles that must pass before the rule can be triggered again) can be specified.
Finally, you can specify scripts (as nested XML statements in the rule) that will be executed when the rule is fired.
note: the subsumption relation used to check the premises is not relative.

back to top

Behaviors

NPCs and Enemies can have multiple "behaviors" attached to them. Behaviors are executed each time a character can execute an action (i.e. they will not be executed while a character is moving or attacking until the move or attack is done). Each behavior can return a desired action. If multiple behaviors return actions, ties are resolved by the priority of each behavior. If a behavior with high priority generates an action in a given cycle, it can be the case that behaviors with low priority are not executed at all during that cycle.

Most of these behaviors make use of the "working memory" that NPCs and Enemies have. The working memory is divided into two parts: short-term and long-term. Each of them is a list of "WMEs" (Working Memory Elements). A WME is a sctructure of the form "type(parameter1, ..., parametern)". WMEs in the short-term memory disappear after a while, WMEs in the long-term memory stay there forever. If a WME stays in the short-term memory for a very long time, it will be moved to the long-term memory.

A4 comes built-in with the following behaviors:

back to top

Spells

Characters that have magic points can cast spells (if they know them). The engine has the following spells implemented (the value in parenthesis is the number of magic points required to cast): All these effects are multiplied by the magic bonus that some items give. For example, if you have a magic bonus of x1.5, then incinerate will deal 48 damage instead of 32. Spell durations and travel distance are not affected by magic multipliers. For shield, increase and decrease, the bonus multiplier that matters is that of the receiver, not of the caster (i.e., magic has more effect on people with magic multipliers).

back to top