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.

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.

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.
(c) 2002-2007 by The Bos Wars Project