-
Notifications
You must be signed in to change notification settings - Fork 0
Scenario file format
Scenarios are saved as yaml files.
File extension is .yaml.
Scenario files are stored in content/scenarios/
.
For an introduction to the yaml language, see wikipedia.
- events: see below
- mapfile: filename of map in
content/maps/
e.g.: development.sqlite - description: Arbitrary long string that is displayed to the user when they select the scenario in the singleplayer menu
- author: The name of the author that created the scenario
- difficulty: A "level" of difficulty that the scenario has.
An event is implemented as a data structure containing
a. conditions that make the event occur and b. actions, that are executed in that case.
Therefore, events is a list of dictionaries (mappings).
Each of those dictionaries has to contain the objects actions
and conditions
.
Both actions and conditions are mappings containing the key type
and
possibly the key arguments
as well.
type
indicates the python function to execute as runtime (conditions
are also functions, that check for something).
arguments
is a list of arguments, that get passed to the function.
Example:
actions:
- {type: win}
conditions:
- type: settlements_num_greater
arguments: [0]
events:
- # comment describing event
actions:
- {type: win} # for each action, you list type and optionally arguments
conditions:
- type: settler_level_greater # same as for actions here.
arguments: [6]
- type: settlements_num_greater # the types correspond to python function calls
arguments: [1]
- type: DUMMY_COND # and are interpreted at runtime
arguments: [5, foo, another_argument, 42.1337] # you can specify a lot of arguments
-
actions:
- {type: lose}
conditions:
- {arguments: [2], type: settler_level_below}
- # hint the player that they are on the right path
actions:
- {arguments: [MESSAGE_ID], type: message} # hope this is obvious
conditions:
- {type: settler_level_greater, arguments: [2]}
# metadata goes here
mapfile: mymapfile.sqlite
author: name
difficulty: easy
description: |
This is a really cool scenario.
Play it!
Events consist of actions and conditions. Once the condition for an action is true, the action will be executed immediately (or as soon the game is able to detect it).
- Events and maybe even actions and conditions could have human-readable names, to help the writers and as builtin doucumentation
This has been avoided so far. Things are identifiable by a numeric worldid, but scenario writers currently cannot set or even see them. Settlements and ships have names, but the user can change them.
As soon as the editor supports scenarios, we could build a map there, that maps scenario identifies to worldobjects of actual objects. This however only works in some limited sense for the game play, since the scenario can only access objects the users built by some logical way (3rd instance of lumberjack)
gt
(greater than) and lt
(less than) handling is not too
beautiful for the user, it is however done like machines do.
We could support actual expressions with syntax similar to
buildings_num_of_type(25) == 2
.
If we do it like that, it should follow:
NUM = [0-9]*
VAR = buildings_num_of_type(25) | settlements_num | ...
TOK = NUM | VAR
COMPARATOR = ">=" | |<" | "==" | "<=" | ">"
EXPR = TOK { COMPARATOR TOK }
// (who thought EBNF is ever good for something ^^)
Parsing can be done safely, check either num or tok, then check order, then evaluate according to operator.
NOTE: handling of parameters of variables possibly should be handled in a better way.
Strings can become pretty long, which makes the file hard to read. Therefore, this at the end of files:
MESSAGES:
INIT_GAME : Yay, you started the game
AFTER_GOLD_MINE_BUILD : |
this deserves
a larger message
AFTER_PORT_BUILD: this has no order
In the text, they could be replaced just like RES or BUILDING currently are:
- action:
type: logbook
arguments: [ INIT_GAME ]
Some scenario writers seem to prefer strict linear ordering at the events, i.e. one can only be triggered once the last one has finished.
This can be implemented easily with a rewriter, i.e, every event will contain this (with autogenerated numbers):
# actions
- arguments: [progress, 61]
type: set_var
# conditions
- arguments: [progress, 59]
type: var_gt
One of these two variations could be helpful here:
The events are currently sorted as list, so this could already be the
order, enabled by a scenario-global attribute linear_order = True
or
strict_order = True
.
One has to consider though that multiple paths are not possible here.
Also side-quests will not work.
Remark: my personal style suggestion is to use implicit linear order, i.e. not specify it, but letting it become apparent by the conditions (e.g. you cannot have 100 settlers if you do not have a warehouse or working food production).
It would also be possible to have a partial ordering, i.e. you give numbers to events, that have to be executed in some order. There could even be blocks of these, if needed:
event_group1:
ordered = True
- conditions:
- type:
arguments..
- type:
- arguments..
event_group_2:
ordered = False
# ...
events:
ordered = False
- event_group1
- event_group2
- other events
Here everything is arbitrary, except the second event in event_group1
has to be executed after the first one.
This might correspond to your way of thinking about your scenario.
One possibility would be to specify events this events depends on for a very flexible handling of conditions. Side-quests are supported by this. It could look like this:
- # first
actions: # ...
conditions: # ...
id: MY_FIRST_EVENT_INVOLVING_AN_ISLAND_BEING_SETTLED
- # second
actions: # ...
conditions:
- {type: after, arguments: [MY_FIRST_EVENT_INVOLVING_AN_ISLAND_BEING_SETTLED]}
- {type: player_number_of_ships_lt, arguments: [2, 1]}
logbook: right now supports this
actions:
- type: logbook
arguments:
- [Headline, "NEW TASK: BUILD FIELDS"]
- [Image, "content/gui/images/background/hr.png"]
- [Label, "regular text goes here"]
- Shortcut notation for a plain Label, same as above
- [Pagebreak]
- |
Text which is pre-formatted and spans over multiple
lines (newlines like this indeed go to a new line)
- [Gallery, ["content/gui/icons/buildmenu/018.png",
"content/gui/icons/buildmenu/019.png"]]
Example:
conditions:
- arguments: [8, 0]
type: buildings_connected_to_warehouse_gt
conditions:
- builings_connect_to_warehouse 8 gt 8
conditions:
- builings_connect_to_warehouse BUILDINGS.SIGNAL_FIRE => 1
conditions:
- player_gold gt 1000