Documentation of the data formats and event scripting language. Includes lists of all the data in the base game that can be used or replaced through modding, and examples of enemy stats and event rewards.

Modding workflow

Creating new mods

Create a folder named “mods” in the game’s root folder. The game will load local mods from subdirectories in this folder.

E.g. to start work on a new mod, create the folder mods/MyNewMod, and start adding mod files to it. See further documentation on what files and data the game looks for.

Most data is reloaded when a scenario is started from the main menu, but adding new scenarios, paperdolls or resources requires a restart of the game.

Uploading to Steam

Once the mod is ready to be shared, copy its folder to another folder called steam_uploads (also located in the game’s root folder).
E.g. from mods/MyNewMod to steam_uploads/MyNewMod
This folder serves as a repository for uploading data to Steam and is not loaded by the game directly.

Optionally add PNG file called steamicon.png, which will be used as the icon for the mod on Steam Workshop.

Open the game and go to the Mods menu from the main menu. You will see a list of all the mods in steam_uploads. The first time you upload a mod, the mod will need to be initialized. Press the Init button, and a new file called modinfo.dat will be created in the mod’s folder. Do not delete or edit this file, as it contains important data connecting this mod to Steam. It cannot be recreated.

Once the mod is initialized and ready, the Upload button will be available, as well as title and description info. You can edit these fields and they will be updated on Steam Workshop when you upload. You should also add a message to describe what’s changed in this upload.

When you press the Upload button, the game will check that all files compile correctly and then start uploading to Steam. Hopefully everything goes well, and then a success message will be displayed. If anything went wrong, an error message will be displayed instead.

Then what?

Continue working on your mod in mods/ folder and when new changes are ready to be uploaded, copy the contents to its counterpart in steam_uploads, but make sure not to overwrite modinfo.dat.

To make a mod visible to others, you need to go into Steam Workshop and change its visibility. You can also edit descriptions and titles there, though note that those changes will not be downloaded back to steam_uploads and may be overwritten the next time you upload.

Scripts – Basic syntax

Comments:
Line comments
// this is a line comment, anything after the two slashes will be ignored
 --- this is also a line comment

Instructions ():

   ... 

e.g.

setlocal alpha 555

exception:
if arguments are expressions (see below), they need to be separated by a comma
currently this only applies to one instruction: add_stat, which takes a string
expression and an int expression as arguments

e.g.

add_stat "vio", 5+rand(3)

newlines separate instructions
exception: if, while, else, and blocks {, }, do not require newlines for the instruction that follow
see section: Basic Statements

Values:
Values of script variables can currently have 3 types

Int a signed 32-bit integer value 5

(Only the decimal form is currently supported)

String a string value “hello” List a list value of multiple other values {5, “hello”, {“another”, “list”}}

Comparisons are only valid between types of the same kind
e.g.

5 = "5"

is always false

Operations always result in the same type as the first operand, and the second will be converted to this type of possible
e.g.

5 + “5” will be 10 “5” + 5 will be “55” 5 – {6} will result in an error, as a list cannot be converted to int Scripts – Expressions Expressions ():
Expressions can be used as arguments to instructions to perform calculations
Any number of operators and comparisons can be combined anywhere that an expression is expected
They can use any of the following as operands
variables: 
 an unquoted string, e.g., alpha. 
 Will load the value of a previously defined script variable or a built-in value (see later)
 The order of precedence for loading values is
 1. local variables (defined with setlocal)
 2. script variables (defined with setvar)
 3. built-in variables
 4. globals (defined with global)
 
 literals:
 integers, e.g. 5
 strings, e.g. "abc"
 lists, e.g. {5,5,5,5}

Sub-expressions can be grouped with parentheses
e.g.

(alpha + beta) * gamma
 alpha + (beta * gamma)

Available operators
(a and b are operands, they can be either named variables or literals)

Prefix operators:

+a (does nothing)
 -a negation
 negates a value, e.g. turns 5 into -5.
 Only valid for ints
 
 !a boolean inversion
 turns a boolean true (1) into false (0) and vice versa
 Only valid for ints

Arithmetic operators:

a * b multiplication
 multiplies a with b, e.g. 5*2 => 10
 Only valid for ints
 
 a / b division
 divides a with b, e.g. 10 / 2 => 5
 Only valid for ints
 
 a + b addition
 Ints: adds a and b, e.g: 5+2 => 7
 Strings: appends b to the end of a, e.g: "abc" + "d" => "abcd"
 Lists: appends b as the last element of the list, e.g: {1,2,3} + "hello" => {1,2,3,"hello"}
 
 a - b subtraction
 subtracts a and b, e.g. 10 - 2 => 7
 Only valid for ints

Ordering operators
(operands must be of same type)
(not defined for lists)

a < b "less than" comparison
 Ints: 1 if a is less than b, otherwise 0, e.g. 10 < 5 => 0
 Strings: calculates lexical string ordering, e.g: "a" < "b" => 1
 
 a <= b "less than or equal to" comparison
 Ints: 1 if a is less than or equal b, otherwise 0, e.g. 10 <= 10 => 1
 Strings: calculates lexical string ordering, e.g: "b" <= "a" => 0
 
 a > b "greater than" comparison
 Ints: 1 if a is greather than b, otherwise 0, e.g: 10 > 5 => 1
 Strings: calculates lexical string ordering, e.g: "a" > "b" => 0
 
 a >= b "greater than or equal to" comparison
 Ints: 1 if a is greater than or equal to be, otherwise 0, e.g: 10 >= 10 => 1
 Strings: calculates lexial string ordering: e.g: "b" >= "a" => 1

Comparison operators
(always false if operands are not of same type)

a = b equality comparison
 1 if a and b are exactly equal, otherwise 0
 Lists: checks that each element of the lists are equal
 
 a != n inequality comparison
 1 if and b are not exactly equal, otherwise 0
 Lists: checks if any of the elements of the lists are not equal

Logical operators
(interpret their operands as boolean values (true/1 or false/0))
(non-zero ints are considered true, zero is false)
(non-empty strings are considered false, otherwise all strings are true)
(non-empty lists are considiered false, other all lists are true)

a && b logical AND
 1 if both a and b are true, otherwise 0
 
 a || b logical OR
 1 if either a or b are true, 0 if both are zero

Index operator

a[b] gets the value at index b of a
 Ints: not valid
 Strings: returns the character value at the specified index as an int
 Lists: returns the value at the specified index

Scripts – Additional expressions

Additional expressions
Function calls:
function_name()

calls the built-in function function_name with the specified arguments (see below for definition)
trying to call an unknown function will result in a compile error
e.g: rand(5), returns a random value between 0 and 4
see section “Built-in functions” for full list of available functions

Select:

[: ]

selects any of the specified arguments based on the value of the expression
e.g:

[rand(3): "a", "b", "c"]

will result in either “a”, “b” or “c”, based on the value of rand(3)
conditional operator ( ? (a) : (b)) can be implemented as [: a, b]
if results in a value that is outside the range of the arglist (less than 0 or larger than the number of items)
a warning will be issued and the first item chosen

shorthands:

a|b|c

shorthand for [diff: a,b,c]

a\b\c

shorthand for [q_diff, a,b,c]

Argument list expression ()
Argument lists are used in function calls, list literals, and certain other contexts
They are a list of expressions separated by commas; , ,
e.g.

func(1,2,3)

1,2,3 is the here
they are usually enclosed by parentheses, but in list by brackets [],
and in select expressions, the square bracket ends the list

List expansion operator (…)
This operator expands a list value into additional individual arguments in an
it is only valid in places that accepts an
e.g.

setlocal arr {1,2,3}
 func(...arr)

will be interpreted as func(1,2,3)
as arr is a list variable

using the operator on a non-indexable value is an error
using it on a string will result in a list of character values
e.g.

..."abc"

may result in {97,98,99}

Scripts – Statements

Statements ()
A statement is one of the following
  • – an instruction
  • if – an if statement
  • while – a loop statement
  • end – a return statement
  • @/label – a label statement
  • jump – a jump statement
  • {…} – a block statement; multiple statements enclosed in brackets

Basic Statements
If

if  
 

if statement

executes the statement if is true/1, otherwise doesn’t and skips to the statement after the if block
e.g.

if alpha = 5 
 dbg_log("hello")

only executes dbg_log if alpha is 5

for multiline ifs, use block statements

if alpha = 5 {
 dbg_log("hello")
 dbg_log("world")
 }

can be nested to to any depth
e.g.

if (alpha = 5)
 if (beta = 4)
 if (gamma = 3)
 dbg_log("yup")

only executes dbg_log if alpha is 5, and beta is 4, and gamma is 3
(this could of course also be written as if (alpha = 5 && beta = 4 && gamma = 3) )

If-else

if  
 <"then" stmt> 
 else 
 <"else" stmt>

if-else statement
executes if is true/1, otherwise executes
if is executed, is skipped
e.g.

if alpha = 5
 dbg_log("hello from 5")
 else
 dbg_log("hello from something else")

as with any statement, use block statements for multiline ifs or else blocks

Looping

while 
 

loop statement

executes repeatedly as long as is true/1
use block statements for multiple instruction etc. etc.

End

end []

return statement
ends execution of the current script
if the current script has been started with call, returns control to the calling script
can push value of the optional as a return value to the caller

Label

@

or

label 

label statement

creates a new label named that be jumped to, or be the target of other jumping instructions
only valid in the current script context
label names must be unique
unused labels will result in a compile error

Jump

jump 

jump statement
moves execution from the current position to the instruction following the label
e.g.

@branch1
 ...
 jump branch1

goes back and runs the code from branch1 again (beware of infinite loops when jumping upwards)

can also be a select statement, by the must consist of valid labels

caution: excessive jumping makes code hard to follow and reason about,
prefer using other methods of structuring code

Set variable

setvar  

set script variable statement
sets a variable named to the value of
this value is available throughout the whole script
e.g.

setvar alpha rand(4) * (beta + gamma)

shorthands:

addvar  
 => setvar  ( + ())

adds to the current value of

subvar  
 => setvar  ( - ())

subtracts from the current value

Set local variable

setlocal  

set local variable statement

sets a local variable named to the value of
this value is only available in current script context (event),
not in other events, not even if they have been goto’d or call’d
e.g.

setlocal alpha "hello " + "world"

shorthands

addlocal  

same as addvar, but for local variables

sublocal

same as subvar, but for local variables

Debug log

dbg_log()

debug log statement
prints the arguments in to the debug log

Scripts – Built-in functions

Built-in Functions
These can be used in expressions. to_int(a) returns a interpeted as an int to_str(a) returns a interpreted as a string rand(a) returns a random value between integers 0 and a-1 (always less than a) rand(a,b) returns a random value between integers a, and b-1 (always less than b) rand_entry(a) returns a randomly selected entry in the list or string a var(a) returns the value of the script variable named by the string a length(a) returns the length of the string or list a subset(a, idx) returns a subset of the string or list a, starting at idx subset(a, idx, end) returns a subset of the string or list a, starting at idx and ending at end get_name(a) returns a string value containing the name defined by the string a monster_name(a) returns a string value containing the name of the monster defined by the string a monster_gfx(a) returns a string value containing the resource name of the graphics of the monster defined by the string a has(a) return true or false depending on if the current play has a certain gear, magic, etc.
special values:
“gear” – checks if the player has an item of type weapon, armor, or relic
“weapon”/”magic”/”armor”/”relic”/”mist” – checks if the player has an item of this item type ranked_player(a) returns the index of the player of rank a (ie. 1 – 4, if 4 players)
can be used with e.g. pl_port to set the portrait of the player of a certain rank
pl_port ranked_player(2)
sets the portrait to player of rank 2

Scripts – Built-in variables

Built-in script variables
These can be used in expressions. stats list of the names of all possible stats a player can have diff the difficulty of the current tile the player is on q_diff the difficulty of the player’s current quest pl_name a string of the current player’s name playerrank the current player’s rank numberofplayers the number of players that currently playing nplayers same as numberofplayers turns_left the number of turns left of the game total_turns the total number of turns at the start of the game vio
tou
mag
sne
soc
coo value of the current player’s current stat of this type gold value of current player’s current amount of cash lvl current player’s level turns number of turns taken in the game game_time measures the number of milliseconds elapsed since the game was started

Scripts – Script instructions

Script Instructions
These instructions handle how scripts are parsed or define new events. strict
legacy
changes the parsing mode of the parser
these are only valid outside of events and will be interpreted as the end of the event if present inside an event

global
defines a new global variable named with the value
only valid outside of events and will be interpreted as the end of an event
is executed during compile time and in the order defined; beware of using variables other than earlier globals in

id: [override]
defines a new event named
the id must be unique, if the event already exists in the base game you will get an error
if you really want to override an existing script, mark the event as override.
e. g.

id: event_that_exists override

if no such event actually exists to override, you will instead get an error for that.

Scripts – Event instructions

Event instructions
The following instructions are only valid inside an event goto [()]
starts the event and changes context there
if the optional is specified, these values will be available in the goto’d event as local variables
argument variables are named
argv: a list of all the arguments
arg_0 … arg_N: named variables of the values in the order defined in
argc: number of arguments passed to event

e,g,

goto test_event (1, 2, 3)

test_event will have local variables
argv = {1, 2, 3}
argc = 3
arg_0 = 1, arg_1 = 2, arg_2 = 3

can also be a select statement, but the results must be valid event ids and cannot be full expressions

call [()] []
same goto, but when ends, control returns to the current event and continues with the next instruction
after call
if is specified, a local variable named is stored with the value of the return value
e.g.

call test_event rval
 dbg_log(rval)
 
 id: test_event
 end 5

dbg_log will display 5, as that was the value returned from test_event and stored in rval

rng



defines a random switch statement
selects a random value between 0 and N and executes one of the following N instruction based on that value
e.g.

rng 3
 dbg_log("selected 0")
 dbg_log("selected 1")
 dbg_log("selected 2")

will execute one of the dbg_log statements
the others are skipped

as with other , block statements are considered a single statement

rng
NOTE: Preferably don’t use this one
similar to rng, but reads all the immediately following instructions of type
and uses them in the list of random instructions to execute
e.g.

rng jump
 jump label1
 jump label2
 jump label3
 @label1

will use one of the random jump instructions between rng and label1

ch_if
ch_0
ch_1
ch_2
ch_str
NOTE: Wonky legacy syntax here
choice statement, displays a choice box, with a number of options
any of these initiates parsing of a choice statement
ch_0, ch_1, ch_2
Pushes the line as a new choice option
ch_str
Takes a string expression and pushes the value as a new choice option
ch_if
Make the next ch_X statement conditional on the value of the
If it is false/0, that option can’t be selected

If the value of ch_X is -, that option is ignored
NOTE: This is not necessary and only available for legacy reasons
If you only want two options, then you only need to write two ch_X instructions

text in choice boxes is filtered, see section String Filtering

choice
acts as break between ch_X and the results of the choices

reads as many after choice as the number of ch_X lines (ie. ch_if does not count to choice count)
that is, with two choices, it will read two s and execute the one chosen in the box

e.g.

ch_0 Choice 1
 ch_str "Choice 2"
 choice
 dbg_log("chose 1")
 dbg_log("chose 2")

displays a choice box with two options: “Choice 1” and “Choice 2”.
Depending on which is chosen, either of the two dbg_logs are executed
Statements not chosen are skipped
As with other block statements can be used for multiline instruction results etc. etc.

endturn
removes all remaining moves of the current player and skips the “resolve tile” step of the turn
meaning no other events would be drawn

exhaust
removes all remaining moves of the current player

add_ee []
adds the event on the map the next time the game returns to the map
if the enchantment event can’t be placed on the current tile the script jumps
to the optional label , if specified

fg_ev
do this before “fight” to add an override after-winning-event to the fight.
this will ignore any after-winning-event set in the monster data.
this override will remain with the monster on the map.

(if you want an event when you lose a fight, you add it in the monsters data:
– lose_ev: )

start_fight
start a fight with a monster with id of the value of
e.g.

start_fight "monster_id"

starts a fight with the monster monster_id

shorthands

fight 
 => start_fight ""

start_fight_msg
works like start_fight except it shows a random encounter message in the beginning of combat

block_check
shortcut to check levels based on area [#blockerlvls]
and does a goto: to [#monster_lvlblockers] if level is not high enough

Scripts – Event instructions (quests)

q_nm
sets the name of the quest to
any event that has a q_nm command in its body can’t be drawn if an
active quest has the name or if a quest in its line has the name q_ev
sets the quest event to

q_rew
sets the quest reward to
also accepts select literals

q_mr
value of = minimum range (number of tiles) away the quest objective has to be
sets the minimum range for the quest objective

q_diff
if you set to anything over 0, the next add_quest or add_quest all will place the quest somewhere in the region of that difficulty
but if you set this to 0, the quest will be placed in your current region or below

q_area
= darklair / castle
places the next add_quest or add_quest_all in this specific area.
other areas than darklair and castle will show an error
= NULL disables this feature and places quests normally, only needed if you place more than one quest in one event

q_req
explanation of requirement to do the quest event
displays as text in the quest menu

add_quest []
adds a new quest and spawns the event in an appropriate place.
relies on q_nm and q_ev and q_rew being set beforehand.
if this event was the “next event” of a quest, that quest is replaced with this new one.

optional =

  • all, adds quest for all players
  • main, adds as main quest

shorthands

add_quest_all
 => add_quest all
 add_quest_main
 => add_quest main

Scripts – Event instructions (misc)

wait
wait for / 50 seconds before running the next instructions
e.g.
wait 25

waits for 0.5 seconds

wait_for_input []
waits until the player presses a button
if is specified, the value of the pressed button is stored in the local variable

death_check
checks if the player is dead, and if so ends the script

Scripts – Event instructions (text)

box_clear
clears the message box nm_clear
clears the name box

name
displays the value of in the name box

shorthands

nm 
 => name ""
 
 nm_p
 => name pl_name
 display the current player name
 
 nm_n 
 => name get_name("")
 displays a name string 
 
 nm_m 
 => name monster_name("")
 displays name of monster 

message
displays the values of in the message box
text in message box is filtered, see section String Filtering

box
displays the line as text in the message box
text in message box is filtered, see section String Filtering

nag
works like the box command if the user has the Hint Messages setting on
otherwise this command is skipped

add
adds the line as text to the message box
text in message box is filtered, see section String Filtering

Scripts – Event instructions (misc. scene, graphics)

reset_snok_counter
snok events MUST have this
reset the Snok counter which allows players to get a Snok encounter
must be called in every Snok event when the player gets the reward
if the group has Snok event group with 1 or more in event_groups.txt it’s allowed to draw it. Castle And Dark Castle have no Snok available, so it cannot be drawn there. next_act
makes the game move forward one act after the event.

run_scene
runs an EventScene prefab from Resources/EventScenes/ named as value of

shorthands

scene 
 => run_scene ""

set_bkg
sets the background image to the value of (searches first in Assets/Resources/Backgrounds)

shorthands

bkg 
 => set_bkg ""

bkg_restore
restores the background to the tile-appropriate one

set_port
sets the portrait to the value of (searches first in Assets/Resources/Portraits)
to clear, use img name “None”, which is a small 100% transparent texture

shorthands

port 
 => set_port ""
 
 port_m 
 => set_port monster_gfx("")

port_pl
displays the portrait of player of index

shorthands

port_rank_pl 
 => port_pl ranked_player()

displays the portrait of the player of a certain rank

Scripts – Event instructions (audio, effects, music)

play_fx
show a portrait fx (sweat drop, anger thingy, shake etc). will be automatically cleared when changing portrait
these will stack so you can mix severalshorthands
fxp 
 => play_fx ""

fxp_clear
remove all current portrait fx

play_music
plays the song

shorthands

music 
 => play_music ""

set_next_music
set the song to be played next

shorthands

music_next 
 => set_next_music ""

set_map_music
sets the song to be played on the map

shorthands

map_music 
 => set_map_music ""

set_next_map_music
set the song to be played next on the map

shorthands

map_music_next 
 => set_next_map_music ""

music_interrupt
instantly pauses the overworld music and instantly stops the “event music”.

music_fadeout
stops the event music with a fadeout

music_pause
pauses the event music

music_resume
resumes the paused event music

play_snd
plays the sound effect
this sound interrupts the previous event sound

shorthands

sfx 
 => play_snd ""

play_snd_ducked
(UNDER CONSTRUCTION)
plays a sound just like the play_snd command but
the music ducks this quickly and intensely

shorthands

dsfx 
 => play_snd_ducked ""

Scripts – Event instructions (stats, items, jobs, rewards, etc.)

add_stat ,
updates the stat with the value of (note comma separating the two expressions)
will display a message box notifying the player of the change
e.g.
add_stat "vio", 5+rand(3)

adds 5-7 to the stat VIO

shorthands

+vio 
 => add_stat "vio", 
 +tou 
 => add_stat "tou", 
 +mag 
 => add_stat "mag", 
 +sne 
 => add_stat "sne", 
 +soc 
 => add_stat "soc", 
 +coo 
 => add_stat "coo", 
 
 +rst 
 => add_stat rand_entry(stats), 
 updates a random stat

add_item
gives the player a specific item

shorthands

+item 
 => add_item ""

rem_item
removes the item if it exists in the players inventory

shorthands

-item: 
 => rem_item ""
 NOTE: colon after -item differentiates it from -item below

rem_item_type
removes an item of a specific type from the player’s invetory, if it exists

shorthands

-item
 => rem_item_type "all"
 NOTE: lack of colon differentiates it from -item:
 -weapon
 => rem_item_type "weapon"
 -armor
 => rem_item_type "armor"
 -relic
 => rem_item_type "relic"
 -magic
 => rem_item_type "magic"
 -gear
 => rem_item_type "gear"

add_exp
updates the player’s EXP value with the value of and displays a message notifying the player of the change

shorthands

+xp 
 => add_exp 

add_hp
updates the player’s HP with the value of and displays a message about this.
if HP drops below 0, the event ends immediately

shortands

+hp 
 => add_hp 

add_status
adds the status to the player

shorthands

+s 
 => add_status ""

rem_status
removes the status from the player if he has it
no textbox is shown if the player doesn’t have the status effect

shorthands

-s 
 => rem_status ""

status_clear
removes all the status effects from the players
automatically shows a textbox for every status removed

set_job
changes the players job to bypassing all normal requirements

shorthands

+job 
 => set_job ""

give_reward
gives the player a random item from the category in

shorthands

 +reward 
 => give_reward ""
 
 +reward: #jobarea
 gives equipment tagged for the specific job the player currently is. If a new job is added, equipment must be tagged, or this function will crash the event.

Scripts – Event attributes

Event Attributes
These look like instructions but are interpreted during compilation and added to an event as attributes freq
is a number typically from 2-8, or it can be rare (1), common (5), or uncommon (3)
sets how frequently an event appears

group
sets which group an event belongs to
all events except those special or starter attributes must have a group
valid groups are:

  • good (something good happens)
  • bad (something bad happens)
  • event (random chance events)
  • snok (only appears for the player in last place)
  • quest (events that start quests)

loc
sets which location the event should appear in
an event can have multiple loc attributes and then it will appear in all those locations
valid loc are:

  • road (generally very low risk and rewards, no quests)
  • town (generally very low risk and rewards, no quests)
  • flowers (generally find jobs)
  • forest (generally find cash)
  • ruins (generally find equipment)
  • runestones (generally find spells)
  • mountain (generally high risk and high rewards)

diff
sets difficulty of the event
can a single integer, or two integers separated by -, e.g. 0 – 3 (spaces are not necessary; negative integers are not accepted)
the first region is 0, the final region is 3

special
marks this event as special, it will not appear as a random event

pvp
marks this event as a pvp event, it will not appear as a random event if the player has disabled pvp events

enchantment
sets the event as special and marks it be used for enchant events
will be interpreted as a string and used as the name of the enchant event

enchantment_diff
sets the tier of the area this enchantment would spawn in
0 is the default and means the current space when spawned in an event or a random space
if it is randomly placed by proceeding to a new act

enchantment_unremovable
makes this enchant event unremovable by other enchants (such as golden road)
put this after the enchantment: portion in the event that is created to make it unremovable

starter
a possible starter quest that happens before the game
automatically sets event as “special” as well

lastplace_only
event can only randomly spawn for someone in last place

notfirst_only
event can only randomly spawn for someone in not in first place

first_only
event can only randomly spawn for someone in first place

notlast_only
event can only randomly spawn for someone not in last place

not_in_quests
prevents a random event from being chosen if a quest with a q_ev found in is currently active
e.g.

not_in_quests {event_1, event_2}

event ids are checked to make sure events with those ids actually exist

Note that when regular random quests are created in the games random events that event is already getting prevented from being picked again for as long as the quest remains on the quest log

Scripts – String filtering

Strings in certain message boxes are “filtered”, this means they can contain certain variables
These are enclosed in brackets
Any available script variable can be used and displayed in this wayThere are also some special values: displays the name of the current location displays the name of the current quest location, if any, otherwise there will be warning total number of turns of the game, same as total_turns number of turns left, same as turns_left number of players in game name of player 1 name of player 2 name of player 3 name of player 4 name of first ranked player name of second ranked player name of third ranked player name of fourth ranked player

E.g.

box We are currently in ...

May display “We are currently in Freaky Forest…” in the message box.

Scripts – About events and event groups

A player who has been in last place for 3 consecutive turns (or 4 turns when there are only two players), and is a minimum of 2 levels behind the leading player, automatically gets a Snok event if one is available at that location.

All events have a cooldown of 8 turns before any player can draw them again. Quests have a cooldown of 25 turns.

The castle and darklair locations have a special case; they only contain the events defaultcastle and defaultdarklair respectively.

When a player gets a random event, the event group is chosen first, and then a specific event is chosen within that group.

The Clairvoyant skill has a chance of rerolling the event group once if the Bad group was drawn. The Lucky status forces the Good or Quest group to be drawn, and the Unlucky status forces the Bad group to be drawn.

This is the frequency of each group of random events when exploring/loitering on each location type per region:

Location Region Event Good Bad Quest Waste Battle Snok Road 1 24 34 3 2 37 1 Road 2-4 20 22 15 10 33 1 Town 1 45 45 5 5 1 Town 2-4 35 35 20 10 1 Flowers 1 25 25 5 35 10 1 Flowers 2-4 25 25 20 20 10 1 Forest 1 15 15 5 32 33 1 Forest 2-4 15 15 13 24 33 1 Ruins 1 15 20 5 38 22 1 Ruins 2-4 15 20 10 33 22 1 Runestones 1 15 20 5 38 22 1 Runestones 2-4 15 20 10 33 22 1 Mountain 1-4 15 15 13 24 33 1

Data formats – Common

Data specified in square […] brackets are optional, and it is not an error to leave them out. Some default value will be used instead.

Values specified as <…> means those values should be defined by you. The brackets should not be included in the actual data file.

E.g., if a specification says , you could write my_very_cool_resource_id in the data file.

Data formats – Resources

Mod file: resources.txt
(define all resources in this file)
File comments allowedResources are loaded when needed, that is, if a resource is defined but never used, it will not get loaded.

All paths should be considered local to the root folder of the mod.

Resource ids can in some cases override “hardcoded” resources, ie. those that come built-in with the game. This can be done for e.g. any texture referenced by scripts, or enemy sprites. To always use a certain built-in resource, reference it as res:/

Format:

[Textures]
 tex  {
 path: 
 }

Note: Valid file formats are png and jpg

[Sprites]
 sprite  {
 path: 
 [pixels_per_unit: ]
 [pivot_x: ]
 [pivot_y: ]
 }

Notes: Same file formats as for textures

[Music]
 music  {
 path: 
 [loop_left: 

Notes:

The song will loop if loop_left is a smaller value than loop_right.
The ‘next:’ variable only matters if this song is used as the overworld song.
When a new act begins the game checks the ‘next:’ variable for what song to switch to.

Example:

tex TestMod_apamouth {
 path: textures/apa_mouth.png
 }
 
 sprite TestMod_Sprite1 {
 path: textures/sprite1.png
 pixels_per_unit: 75
 pivot_y: -70
 }

Data formats – Paperdoll

Mod file: paperdoll.txt
(define all new doll parts in this file)
File comments allowedAdds new selectable mouths, hairstyles, etc., for the player sprites

Format:

  {
 gfx: 
 [tag: ]
 }

Available that can be selected:

  • hair_back – piece of hair rendered behind head
  • head – the sprite’s basic head shape
  • mouth – the mouth
  • eyes – eyes
  • hair_front – piece of hair rendered in front of the head

Notes:
Tags are an optional feature that determine which parts that are incompatible with one another.
Currently only used for hairs. If a hair_front part has a tag, a hair_back needs to have the same tag in order to be used with that hair_front. Otherwise it will be skipped when trying to select it in the menu.

Example:

head apafrog {
 gfx: TestMod_apahead
 }
 eyes apaeyes {
 gfx: TestMod_apaeyes
 }
 mouth apamouth {
 gfx: TestMod_apamouth
 }

Data formats – Scenario

Mod file: scenarios.txt
(define all new scenarios in this file)
File comments allowedDefines new scenarios that can be selected in the game menu.

Format:

{
 name: ""
 [desc: ""]
 start_event: