# Bos Wars Scripting API: Save Game and Replay Files

Bos Wars FAQ PREV NEXT LUA Index

DefineAiPlayer Log Missile Player ReplayLog SaveGame Selection SetGroupId SlotUsage StratagusMap Unit

## Intro - Introduction to saved games and replay logs

Saved games are Lua scripts that call the functions described below. The engine generates calls to these functions when it saves a game. When the saved game is loaded back, those calls restore its state.

Replay logs are Lua scripts to which the engine writes the commands of human players during a game. You can later replay the log and watch the game again. If a bug crashes the engine, the log may help you reproduce the bug under a debugger or verify that it has been fixed. The replay log does not contain any commands made by AI players, because the engine assumes that the AI will behave the same way each time the log is replayed. For that reason, replay logs are typically not compatible between different versions.

## Functions

### DefineAiPlayer(player-number, properties)

Define an AI player. Saved games use this function; map setup files should not.

player-number
  Number of the player, counting from 0.
properties
  Properties of the AI player. This list consists of tags and associated values. These tags are available:
  "ai-type", string
    Identifier of the AI type. Matches the Ident field of the table parameter of DefineAiType.
  "script-debug", boolean
    Obsolete since r5923 (2004-01-01): The debug flag no longer affects the engine, and scripts cannot read it.
    Whether to display the executed AI script commands. The AiDebug and AiDebugPlayer functions also control this flag.
  "sleep-cycles", integer
    The number of the game cycle on which the AI will wake up from AiSleep, or 0 if not sleeping.
  "force", {force, properties}
    Defines a group of units that should attack or defend together, to overwhelm the enemy. The value must be a list that contains two elements:
    force
      Number of the force. 0 - 9 is currently supported.
    properties
      Properties of the force. This list consists of subtags and possibly values. Some subtags do not allow a value and the others require a value. These subtags are available:
      "complete"
        The force does not need more units. This is the opposite of "recruit".
      "recruit"
        The force needs more units. This is the opposite of "complete".
      "attack"
        The force is attacking.
      "defend"
        The force is defending a unit that was attacked. After the enemies are dead, the force should return home.
      "role", string
        Obsolete since r5923 (2004-01-01): Roles of forces no longer affect the engine, and scripts cannot read them.
        The role of the force, as set with AiForceRole.
      "types", {[count, unit-type-name]...}
        How many of each unit type should be in the force. This is set with AiForce.
      "units", {[unit-number, unit-type-name]...}
        List of units currently in the force. The type names are ignored on load.
      "state", integer
        Attack state.
      "goalx", integer
        Attack point X tile map position.
      "goaly", integer
        Attack point Y tile map position.
  "needed", {[resource-type-name, amount]...}
    FIXME
  "need-mask", {resource-type-name...}
    FIXME
  "last-can-not-move-cycle", integer
    FIXME
  "unit-type", {[unit-type-name, count]...}
    FIXME
  "building", {[unit-type-name, made, want]...}
    FIXME
  "repair-building", integer
    FIXME
  "repair-workers", {[building-unit-number, count]...}
    Number of workers that failed trying to repair a building.

For an example of DefineAiPlayer, please look in any save file. No example is provided in this document because Lua scripts for maps should not call DefineAiPlayer.

### Log()

Parses a log entry and appends it to an internal list. This function is used in both replay logs and saved games.

- Replay logs mainly consist of calls to the Log function. After the engine has executed all of these calls, it starts actually replaying the entries from the internal list.
- Each saved game contains Log calls for all the log entries from the beginning of the game to the time it was saved. When the game is loaded, the engine copies these entries to a new replay log and then begins appending any new entries to that. This way, the replay log will start from the beginning of the game, even if the game was saved and loaded multiple times.

#### Example

    Log({ GameCycle = 10420, UnitNumber = 252, UnitIdent = "unit-assault",
      Action = "move", Flush = 1, PosX = 113, PosY = 104, SyncRandSeed = 614148735 })

### Missile(tag, value, tag, value, ...)

Adds a missile on the map.

The function supports these tag-value pairs:

"type", missile-type-name
  The type of the missile. Declared with DefineMissileType.
"local"
  This missile is marked as local, and it's visible only to the player. This is used for instance for cursor marks on the map. The "local" tag is unusual in that no value follows it. Either "local" or "global" must be specified.
"global"
  This missile is marked as global, and it's visible to all players. The "global" tag is unusual in that no value follows it. Either "local" or "global" must be specified.
"pos", {x, y}
  The current position of the missile. Coordinates are in pixels, not tiles. For example: "pos", {4500, 3450}
"origin-pos", {x, y}
  The starting position of the missile. Coordinates are in pixels, not tiles. For example: "origin-pos", {4505, 3455}
"goal", {x, y}
  The position of the missile's destination. Coordinates are in pixels, not tiles. For example: "goal", {4510, 3460}
"frame", integer
  Current sprite frame of the missile; complicated behavior. A negative integer generally means the actual frame number is -1 - integer and the sprite should be mirrored in the X direction; but the effect depends on the Flip parameter of DefineMissileType.
"state", integer
  Current state of the missile. Used for a simple state machine, dependand on the missile class.
"anim-wait", integer
  FIXME: Document this.
"wait", integer
  Wait this number of game cycles until the next state or animation of this missile is handled. This counts down from the Sleep parameter of DefineMissileType to 0.
"delay", integer
  Number of game cycles left until the missile is first shown on the map. Please see Delay in DefineMissileType.
"source", unit-reference-string
  Number of the owner of the missile. Normally the one who fired the missile. Used to check units, to prevent hitting the owner. Also used for kill and experience points, and for giving the owning player score.
"target", unit-reference-string
  Number of the missile's target. Normally the unit which should be hit by the missile.
"damage", integer
  Damage done by missile. Units next to it can receive some reduced splash damage, this is the full damage.
"ttl", integer
  Time to live in game cycles of the missile, if it reaches zero the missile is automatically removed from the map. If -1 the missile lives for ever and the lifetime is handled by other means.
"hidden"
  This marks the missile as hidden, until the missile class decides to show it again. The "hidden" tag is unusual in that no value follows it.
"step", {current-step-integer, total-step-integer}
  The progress of the missile along its movement path. Generally, current-step-integer starts from zero when the missile is launched, and it then increases until it reaches total-step-integer, at which point the missile hits its target. The Speed parameter of DefineMissileType is the rate of increase, and the value of total-step-integer is the distance between the source and the target. However, some missile classes may use these values differently.

#### Example

    Missile("type", "missile-small-fire", "global", "pos", {1168, 1960}, "origin-pos", {1168, 1960}, "goal", {-16, -24},
      "frame", 0, "state", 0, "anim-wait", 0, "wait", 8, "delay", 0,
      "source", "U003B", "damage", 0, "ttl", -1, "step", {0, 0})

### Player()

Used when loading games.

#### Example

    Player(0,
      "name", "Player",
      "type", "person", "ai-name", "ai-spacious",
      "team", 2, "enemy", "_XXX_____", "allied", "_________", "shared-vision", "_________",
      "start", {19, 19},
      "production-rate", {"energy", 414, "magma", 174,},
      "stored-resources", {"energy", 600000, "magma", 120000,},
      "storage-capacity", {"energy", 600000, "magma", 120000,},
      "ai-disabled",
      "unit-limit", 200, "building-limit", 200, "total-unit-limit", 400,
      "score", 18730,
      "total-units", 48,
      "total-buildings", 79,
      "total-resources", {23339092, 9312165,},
      "total-razings", 69,
      "total-kills", 219,
      "color", { 0, 0, 164 })

### ReplayLog()

Describes how the game was started. This function is used in both replay logs and saved games.

- When replaying a log, the engine starts a new game in the same way.
- When loading a saved game, the engine copies this information to a new replay log.

#### Example

    ReplayLog( {
      Comment1 = "Generated by Bos Wars Version 2.6.0",
      Comment2 = "Visit http://www.boswars.org for more information",
      Comment3 = "$Id: replay.cpp 9589 2009-05-30 18:09:56Z jim4 $",
      Date = "Sun Mar 21 21:26:57 2010",
      Map = "Four against four on the island.",
      MapPath = "maps/4on4.map/presentation.smp",
      MapId = 444351,
      Type = 1,
      LocalPlayer = 0,
      Players = {
    	{ Name = "Player", Team = -1, Type = -1 },
    	{ Name = "Computer", Team = -1, Type = -1 },
    	{ Name = "Computer", Team = -1, Type = -1 },
    	{ Name = "Computer", Team = -1, Type = -1 },
    	{ Name = "Neutral", Team = -1, Type = -1 },
    	{ Name = "Neutral", Team = -1, Type = -1 },
    	{ Name = "Neutral", Team = -1, Type = -1 },
    	{ Name = "Neutral", Team = -1, Type = -1 },
    	{ Name = "Neutral", Team = -1, Type = -1 }
      },
      Resource = 3,
      NumUnits = -1,
      Difficulty = 3,
      NoFow = false,
      RevealMap = 0,
      GameType = -1,
      Opponents = -1,
      MapRichness = -1,
      Engine = { 2, 6, 0 },
      Network = { 2, 6, 0 }
    } )

### SaveGame({SyncHash = x, SyncRandSeed = y, SaveFile = "file"})

Basic outline of the savegame, include hashs for syncrand and where to load the rest of the game information from when loading. More information is planed for implementation, but currently only the above are used.

SyncHash = x
  integer setting the Hash of the current game for Sync Purposes
SyncRandSeed = y
  integer of the next value to be used when calling SyncRand
SaveFile = "file"
  String containing the name of the file to load to get the rest of the gamedata

#### Example

    SaveGame({
    ---  "comment", "Generated by Stratagus Version 2.0",
    ---  "comment", "Visit http://Stratagus.Org for more informations",
    ---  "type",    "single-player",
    ---  "date",    "Mon May 10 19:19:38 2004",
    ---  "map",     "",
    ---  "media-version", "Undefined"---  "engine",  {2, 0, 0},
         SyncHash = 196009203,
         SyncRandSeed = -220040269,
         SaveFile = "data.wc2//campaigns/human/level13h.cm"

    ---  "preview", "/home/devil/.stratagus/wc2/save/current-game.sav.pam",
    } )

### Selection(numselected, unit0, ...)

Define the current selection.

numselected
  How many units are selected.
unitX
  slot number of the unit to add in the selection.

#### Example

    Selection(1, 0)

### SetGroupId(id)

Set the current group id. (Needed for load/save).

id
  new group id.

#### Example

    SetGroupId(0)

### SlotUsage(MaxSlot, [{Slot = Slot1, FreeCycle = Freecycle1}, ..])

Allows reloaded Save games to be replayed in sync by reloading the released units back into the queue they were in when a game was saved.

MaxSlot
  The total Number of slot used.
Slot
  The Slot Number for the unit that was in the release Queue
FreecCycle
  The Cycle that this unit is/was released in

#### Example

    SlotUsage(5, {2, 855})

### StratagusMap(...)

The state of the map, without units. Much of this information is redundant with the map setup file. However, the StratagusMap call also carries information on which parts of the map each player has explored; that is of course not in the map setup.

### Unit()

Needed to save/load games.

#### Example

    Unit(0, "type", "unit-vault", "player", 0,
      "tile", {116, 120}, "refs", 6, "stats", 0,
      "pixel", {0, 0}, "seen-pixel", {0, 0}, "frame", 1, "not-seen", "direction", 0,
      "attacked", 0,
      "current-sight-range", 4, "seen-by-player", "X_______________",
      "seen-destroyed", "________________",
      "seen-state", 0,  "active", "mana", 0, "hp", 1800, "xp", 0, "kills", 0,
      "ttl", 0, "bloodlust", 0, "haste", 0, "slow", 0,
      "invisible", 0, "flame-shield", 0, "unholy-armor", 0,
      "HitPoints", {Value = 1800, Max = 1800, Increase = 0, Enable = true},
      "Mana", {Value = 0, Max = 0, Increase = 0, Enable = false},
      "Transport", {Value = 0, Max = 0, Increase = 0, Enable = true},
      "Training", {Value = 0, Max = 0, Increase = 0, Enable = true},
      "Resource", {Value = 0, Max = 0, Increase = 0, Enable = true},
      "group-id", 0,
      "last-group", 0,
      "value", 0,
      "sub-action", 0, "wait", 2, "state", 2,
      "blink", 0, "rs", 35, "units-boarded-count", 0,"order-count", 1,
      "order-flush", 0,
      "order-total", 4,
      "orders", {
        {"action-still", "flags", 0, "range", 0, "width", 0, "height", 0, "min-range", 0, "tile", {-1, -1},},
        {"action-none", "flags", 0, "range", 0, "width", 0, "height", 0, "min-range", 0, "tile", {0, 0},},
        {"action-none", "flags", 0, "range", 0, "width", 0, "height", 0, "min-range", 0, "tile", {0, 0},},
        {"action-none", "flags", 0, "range", 0, "width", 0, "height", 0, "min-range", 0, "tile", {0, 0},},},
      "saved-order",
        {"action-still", "flags", 0, "range", 0, "width", 0, "height", 0, "min-range", 0, "tile", {-1, -1},},
      "new-order",
        {"action-still", "flags", 0, "range", 0, "width", 0, "height", 0, "min-range", 0, "tile", {-1, -1},}
    )

All trademarks and copyrights on this page are owned by their respective owners.