This document explains how to create a splits.json file for the Timer mod in plain language with examples. You only need to know basic JSON structure; the examples below show ready-to-use snippets.
Place the finished file at terra/mod-data/timer/splits.json inside your Alabaster Dawn folder so the timer can load it automatically.
Enable the Show Event Overlay option at the bottom of the Gameplay options before you start. The overlay shows live event values (map names, langIDs, variable paths, enemy names) that you can use in the splits file.
The file must be a JSON object with one key: splits, which is an array of event objects.
Example skeleton:
{
"splits": []
}type(required): The kind of event to watch for. See the types below.once(optional): Whentrue, the event is used only once and will be ignored afterwards.disabled(optional): Whentrue, the event is ignored until you remove or change this field.- Other fields depend on
type(see each type for details).
- When the game reports that a named story (plot) finished.
- Fields:
type: "storyEnd",name(plot key), optionalonce.
Example: trigger when the plot plg ends (only once):
{
"type": "storyEnd",
"name": "plg",
"once": true
}Notes: If you omit name or set it to an empty string, the event will match any story end.
- When a centered message appears on screen.
- Fields:
type: "centerMessage",langID(a number identifying the message), optionalonce.
Example: trigger for language/message id 291:
{
"type": "centerMessage",
"langID": 291,
"once": true
}- When the player is teleported / a map is loaded.
- Fields:
type: "loadmap",name(map name), optionalonce.
Example: split when map town_square loads:
{
"type": "loadmap",
"name": "town_square"
}- When a game variable changes to a specific value.
- Fields:
type: "eventTriggered",name(variable path),value(the value to match), optionalonce.
Example: trigger when map.puzzle1Done becomes true:
{
"type": "eventTriggered",
"name": "map.puzzle1Done",
"value": true
}- When an enemy's HP is reported (useful for boss HP triggers).
- Fields:
type: "hp",name(enemy name), optionalbelowand/orabove(numbers), optionalonce.
How below and above work:
below: the event only triggers if the reported HP is less than or equal tobelow.above: the event only triggers if the reported HP is greater than or equal toabove.
Example: trigger when an enemy named boss_ogre drops to 0 HP (dead):
{
"type": "hp",
"name": "boss_ogre",
"below": 0,
"once": true
}Example: trigger when a boss falls below half HP (assuming max 100):
{
"type": "hp",
"name": "boss_ogre",
"below": 50
}- Combine several events so the split only happens after all listed conditions are satisfied.
- Fields:
type: "combined",conditions(an array of Event objects), optionalonce.
Example: split after the player loads map dungeon and then a variable map.puzzle1Done becomes true:
{
"type": "combined",
"conditions": [
{ "type": "loadmap", "name": "dungeon" },
{ "type": "eventTriggered", "name": "map.puzzle1Done", "value": true }
],
"once": true
}This example shows several types in one splits.json:
{
"splits": [
{ "type": "storyEnd", "name": "plg", "once": true },
{ "type": "storyEnd", "name": "ch1", "once": true },
{ "type": "centerMessage", "langID": 291, "once": true },
{ "type": "hp", "name": "boss_ogre", "below": 0, "once": true },
{
"type": "combined",
"conditions": [
{ "type": "loadmap", "name": "dungeon" },
{ "type": "eventTriggered", "name": "map.puzzle1Done", "value": true }
],
"once": true
}
]
}- Make small changes and test one split at a time.
- Use
"once": truefor splits you only want once (e.g., chapter ends). - Use
"disabled": trueto temporarily turn off a split without deleting it. - Enable the
Show Event Overlayoption at the bottom of the Gameplay options to see live event values (map names,langIDs, variable paths, enemy names) while playing — copy those exact values into your splits. - If a split does not trigger, check that the
name,langID, orvaluematch exactly what the game reports. - The splits file reloads every time you start a run.