- Fix monster attitude enumerator not being reflected in schemas - Store the sound ID for sound names, instead of the index into the sound name array
Blades of Exile New Scenario Format
This document describes, in as much detail as possible, the format of .boes files. Parts of the format are specified by the various XSD schemas in this directory, but the schemas are not a perfect representation of the format - they are a little more restrictive than the game itself accepts, and omit a few complex restrictions that the game enforces.
The Scenario Package
A Blades of Exile scenario is a tarball (ustar) compressed with gzip. The tarball contains the following files:
- scenario/
- header.exs - This file has no function except to allow you to open a scenario that has been unpacked with the scenario editor. It contains the scenario and Blades of Exile version in binary format.
- scenario.xml - Contains most of the global data for the scenario.
- scenario.spec - Contains the definitions of the scenario special nodes.
- terrain.xml - Contains the definitions of scenario terrain types.
- items.xml - Contains the definitions of scenario items.
- monsters.xml - Contains the definitions of scenario monsters.
- towns/
- townN.xml - Contains most of the data for town N.
- townN.spec - Contains the definitions of the special nodes for town N.
- townN.map - Contains the map data for town N.
- talkN.xml - Contains the dialogue nodes associated with town N.
- out/
- outX~Y.xml - Contains most of the data for outdoors sector (X,Y).
- outX~Y.spec - Contains the definitions of the special nodes for outdoors sector (X,Y).
- outX~Y.map - Contains the map data for outdoors sector (X,Y).
- graphics/ - (optional)
- sheetX.png - (optional) Custom graphics sheet ID X.
- objects.png, tinyobj.png, fields.png, trim.png, booms.png, missiles.png, dlogpics.png, staticons.png, teranim.png, talkportraits.png, pcs.png, vehicle.png, termap.png - (optional) Overrides the default graphic sheets of the same name.
- sounds/ - (optional)
- SNDX.wav - (optional) A custom sound with ID X. If X < 100, the sound will override the default sound with the same ID.
- dialogs/ - (optional) - Contains complex dialog definitions used by the scenario. This is currently unused.
If you have a scenario directory with the proper structure, it can be turned into a valid scenario with the following shell command:
tar -zcf scenname.boes scenario
Special Nodes
Scenario special nodes are stored in .spec files in a special "pseudo-assembly" format. The grammar is as follows:
«node-file» -> («comment» | «const-def» [«comment»] | «node-def» [«comment»])*
«const-def» -> def «identifier» = «integer»
«node-def» -> @«opcode» [= «integer»] «data-def»*
«data-def» -> «data-def-unary» | «data-def-binary» | «data-def-ternary»
«data-def-unary» -> goto = «value»
«data-def-binary» -> (sdf | pic) = «value» [, «value»]
«data-def-ternary» -> (msg | ex1 | ex2) = «value» [, «value» [, «value»]]
«value» -> «integer» | «identifier»
An «identifier»
is a sequence of letters, underscores, hyphens, and dollar signs (digits
not permitted). An «integer»
is a sequence of digits. An «opcode»
is a special
identifier; valid opcodes are listed in the file
specials-opcodes.txt.
In addition, nop
is also a valid opcode.
A «comment»
is any sequence of characters starting with the #
character and ending
with a newline.
Note that, although the format supports defined constants using def
, the scenario never
writes defined constants.
Map Data
Map data is stored in .map files in a two-dimensional format. Each line in the file represents one row of terrain in the town or outdoor sector. Individual tiles within a single row are comma-separated. A tile consists of an integer, giving the terrain type on that space, followed by an optional set of modifiers. Most modifiers consist of a special character followed by an integer. A few modifiers consist of only a special character. There can be multiple modifiers of the same type on a single tile.
The list of valid tile modifiers follows:
^ < > v
- Gives the position of a town entrance from one specific direction. (The fourth one there is lowercase V.) Takes no argument. Only valid in town.*
- Specifies that the tile is a wandering monster arrival point. Argument is which point (0-3).:
- Indicates a special node is attached to the space. Argument is the node number.!
- Indicates a sign is attached to the space. Argument is which sign.@
- When used outdoors, indicates a town entrance; argument is the town number. When used in town, indicates a placed item; argument is the index of the placed item entry.&
- Indicates an overlay such as a field, object, or special spot. The argument is a number indicating the type of field (valid values are listed below). It can be used outdoors, but the only valid argument is9
, indicating a special spot.$
- When used in town, indicates a placed creature; argument is the index of the placed creature entry. When used outdoors, indicates a placed special encounter group; argument is the index of the special encounter. (Note: Placed outdoor special encounters are not yet supported.)h
- Indicates a horse that belongs to the party. Argument is the index of the horse in the global list.H
- As above, except the horse does not belong to the party.b
- Indicates a boat that belongs to the party. Argument is the index of the horse in the global list.B
- As above, except the boat does not belong to the party.
General XML notes
All XML documents used in the scenario format require a boes
attribute on their root
node, which should be set to 2.0.0
. This is a way to indicate the format version; if
the format ever changes, the value of this attribute will also be changed.
There are some types that are common:
- Booleans - a boolean is one of the strings "
true
" or "false
". - Points - a point is an element with two attributes,
x
andy
. It has no content. - Rects - a rect is an element with four attributes:
top
,left
,bottom
, andright
. It has no content - Timers - a timer is an element whose content is the node to call, with an attribute
freq
specifying how many moves to wait between calls.
Scenario Header
The scenario.xml file stores most of the global scenario data. The following toplevel tags are required:
<title>
- Contains the scenario name.<icon>
- Contains an integer specifying the scenario icon.<id>
- Contains the scenario's campaign ID.<version>
- Contains the scenario version.<language>
- For future expansion. Currently always contains "en-US".<author>
- Contains information about the scenario author. Requires two sub-elements:<name>
and<email>
.<text>
- Contains basic textual information about the scenario. Can contain any of the following:<teaser>
- (max 2) A short string to be displayed in the scenario selection dialog.<icon>
- Overrides the toplevel<icon>
just for the intro dialog.<intro-msg>
- (max 6) A string to be shown in the intro dialog. If none are present, or all are empty, no intro dialog is shown. The scenario editor wraps the contents of this element in aCDATA
declaration.
<ratings>
- Contains the scenario rating. The following two subtags are required:<content>
- The content rating. Must be one ofG
,PG
,R
,NC-17
.<difficulty>
- The difficulty rating. Must be an integer from 1 to 4.
<flags>
- Contains various scenario flags.<creator>
- Contains information about the program that wrote this scenario. Requires the following subtags:<type>
- Must contain the stringoboe
. If you fork OBoE and change the scenario format, you would use a different string here to let mainline OBoE know that it's incompatible.<version>
- The version of OBoE that the scenario was last edited with.<os>
- The operating system on which the scenario was last edited.
<game>
- Contains the bulk of global information about the scenario.<editor>
- Contains several details of the scenario that aren't relevant to gameplay, but are instead used by the scenario editor to enhance your editing experience.
The <game>
element can have the following child tags, most of which are optional:
<num-towns>
- (required) Indicates how many towns the scenario has.<out-width>
,<out-height>
- (required) Indicates how many outdoor sectors the scenario has.<start-town>
- (required) Specifies which town the player should start in.<town-start>
- (required) Specifies the player's initial position in the start town, as a point.<outdoor-start>
- (required) Specifies which outdoor section the player should start in, as a point.<sector-start>
- (required) Specifies the player's initial position in the starting sector.<on-init>
- Indicates the number of a scenario special node to call when the scenario first starts.<store-items>
- (max 3) Specifies a rectangle from which the player can retrieve items after completing the scenario, as a rectangle with an extratown
attribute that specifies which town the area<town-flag>
- (max 10) Specifies a rule to add the value of an SDF to a town upon entry. The SDF is specified with theadd-x
andadd-y
attributes, and the town number with thetown
attribute.<special-item>
- (max unbounded) Defines one special item. Special items must appear in order, starting with special item ID 0. Special items have the following attributes and subtags:start-with=
- Boolean indicating whether the party starts the scenario with this item.usable=
- Boolean indicating whether the item can be used.special=
- (required only ifusable="true"
) Indicates the special node to call when the special item is used.<name>
- (required) The name of the special item.<description>
- (required) The special item description. The scenario editor wraps the contents of this element in aCDATA
declaration.
<quest>
- (max unbounded) Defines one quest. Quests must appear in order, starting with quest ID 0. Quests have the following attributes and subtags:start-with=
- Boolean indicating whether the party starts the scenario with this quest.<deadline>
- (optional) Specifies the quest deadline (in days) as its content. Supports two optional attributes -waive-if
, an integer specifying the event whose occurrence waives the deadline, andrelative
, a boolean indicating whether the deadline is relative to the day the quest is started.<reward>
- (optional) An empty element specifying the reward for completing the quest, with its two possible attributesgold
andxp
.<bank>
- (optional, max 2) Specifies that the quest belongs to one or two job banks.<name>
- (required) - The name of the quest.<description>
- (required) The quest description. The scenario editor wraps the contents of this element in aCDATA
declaration.
<shop>
- (max unbounded) Defines one shop. Shops must appear in order, starting with shop ID 0. Shops require the following subtags:<name>
- The name of the shop, used by the scenario editor only.<type>
- The type of the shop. Must be one oflive
,dead
,rand
.<prompt>
- The shopping prompt. Must be one ofshop
,heal
,mage
,priest
,spell
,alch
,train
.<face>
- The talking portrait to use in the shop.<entries>
- The actual contents of the shop. It can contain any of the following elements in any order, but no more than 30 in total:<item>
- An ordinary item. The content specifies which item (taken from the scenario's item list). By default, there's an infinite amount of this item; the attributequantity
can specify a different amount, or you can explicitly specifyquantity="infinite"
. You can also use thechance
attribute to make the item appear only sometimes (defaults to 100). Note: If you specify thechance
attribute to be something other than 100, the shop's type needs to be set torand
for it to work properly.<mage-spell>
- A mage spell. The content specifies which item (0-61).<priest-spell>
- A mage spell. The content specifies which item (0-61).<recipe>
- A mage spell. The content specifies which item (0-19).<skill>
- A mage spell. The content specifies which item (0-20).<treasure>
- A random item of a specific treasure class (0-4). Note: If you use this type of entry, the shop's type needs to be set torand
for it to work properly.<class>
- A random item of a specific special class (1-100). Note: If you use this type of entry, the shop's type needs to be set torand
for it to work properly.<heal>
- Healing. Must be one of the following:0
- Restore health to full.1
- Remove poison.2
- Remove disease.3
- Remove acid.4
- Remove paralysis.5
- Uncurse all carried items.6
- Revive petrified character.7
- Revive dead character.8
- Revive obliterated (dust) character.9
- Remove dumbfounding.
<special>
- An item that calls a special node when purchase. Requires the following subtags:<name>
- The name of the entry.<description>
- A description of the entry. The scenario editor wraps the contents of this element in aCDATA
declaration.<node>
- The scenario special node to call.<quantity>
- How many times the item can be purchase (an integer or the special valueinfinite
).<cost>
- How much the item costs to purchase.<icon>
- The item icon to use.
<timer>
- (max 20) A scenario timer.<string>
- (max unbounded) A scenario string. The scenario editor wraps the contents of this element in aCDATA
declaration.<journal>
- (max unbounded) A journal string. The scenario editor wraps the contents of this element in aCDATA
declaration.
(...more to come...)