Skip to content

Scenario file format

Chris Oelmueller edited this page Apr 6, 2013 · 1 revision

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.

Parameters

  • 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.

Specifying events

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.

Actions & 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]

Scenario actions

Scenario conditions

Example scenario file

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!

Proposals for syntax improvments

Events

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).

Minor proposals:
  • Events and maybe even actions and conditions could have human-readable names, to help the writers and as builtin doucumentation

Referring to things ingame

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)

Expressions for comparisons

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.

String database

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 ]

Linear ordering

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:

Linear order

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.

Dependency graph

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]}  

Actions

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"]]

Conditions

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
Clone this wiki locally