package game
Package game is what a map script can see and do in the game. Everything here runs inside the simulation at fixed steps, so a script is deterministic and will run on a server one day.
Units are handles: a Unit that died or was removed still compares equal to itself, and its methods then do nothing or report it as not alive.
import "w4/game"Functions
Command
func Command(name, args, help string, fn func(p player.ID, args string))Command adds a slash command to the players' chat: "/name args" calls fn with the number of
the player who typed it and the rest of the line. args and help are shown in the chat's list,
like "
Debug
func Debug(a ...any)Debug writes a developer note. It never appears in the chat: it goes to the F12 log (the Debug filter) and, when the player turned on "Debug readout in the corner" or the engine runs with AQUA4_DEV=1, to a small dim readout at the top right that keeps the last three notes for four seconds. The text may switch colours with "[#RRGGBB]" (for the rest of the line) and "[/]" (back to default). It is only a message: the simulation never reads it.
End
func End(outcome string)End says how this mission ended, by a name: "victory", "defeat", or any outcome the map declares for its campaign ("rescued", "spared"). Names are lower-case letters, digits, '_' and '-', at most 32; anything else is ignored, and only the first call counts. A campaign moves on along the edge of that name; the game itself keeps running until the host stops it.
event.OnUnitDied(func(u game.Unit) {
if u.Name() == "Prisoner" { game.End("lost-the-prisoner") }
})Error
func Error(a ...any)Error writes a red "(ERROR)" line to the message stream; colour marks work as in Debug.
func Print(a ...any)Print writes a line to the game's log window (F12), like fmt.Print would. fmt.Println works too: the script's standard output goes to the same window.
Printf
func Printf(format string, a ...any)Printf is Print with a format.
Random
func Random(n int) intRandom is a random whole number from 0 up to, but not including, n (n of 0 or less gives 0). The numbers come from the game's seed, which every player in a match and every replay shares, so they are the same everywhere: use it for anything that changes the game, like loot or where a wave spawns. Go's math/rand and time.Now give the same guarantee here (they are seeded from the game and follow game time), but game.Random says so in its name.
RandomFloat
func RandomFloat() float64RandomFloat is a random number from 0 up to, but not including, 1, from the game's seed like Random.
Time
func Time() float64Time is the game time in seconds.
Warning
func Warning(a ...any)Warning writes an amber "(WARNING)" line to the message stream; colour marks work as in Debug.
Types
Region
type Region struct {
// contains filtered or unexported fields
}Region is an area of the map that the game watches: a rectangle or a circle, in world units from the middle of the map like every position here. Make one with NewRegion or NewCircle and listen for units coming and going with event.OnEnter and event.OnLeave.
The game checks every step who is inside. A unit counts as inside while it is alive; one that dies there leaves the region. Units that are already inside when the region is made do not count as entering.
NewCircle
func NewCircle(x, y, radius float64) RegionNewCircle makes a circle of the given radius with its middle at (x, y).
NewRegion
func NewRegion(x, y, width, height float64) RegionNewRegion makes a rectangle width wide and height tall with its middle at (x, y).
Region.Contains
func (r Region) Contains(x, y float64) boolContains is whether the point (x, y) is inside the region (the edge counts as inside).
Region.Has
func (r Region) Has(u Unit) boolHas is whether the unit is alive and inside the region now.
Region.ID
func (r Region) ID() intID is the region's number, the one event handlers are filed under.
Region.Remove
func (r Region) Remove()Remove stops the game watching the region: no more enter or leave events. Its handlers stay registered but never fire.
Region.Units
func (r Region) Units() []UnitUnits are the living units inside the region now.
Unit
type Unit struct {
// contains filtered or unexported fields
}Unit is a handle to a unit on the map. The zero Unit is no unit.
SpawnUnit
func SpawnUnit(definition string, x, y float64, owner player.ID) UnitSpawnUnit puts a new unit of the definition named definition (its name in the editor's Objects
panel) at (x, y) for player, and returns it. Positions are in world units (128 to a tile)
counted from the middle of the map: (0, 0) is the centre, as in the editor's object fields. When there is no such definition (a
typo, say) the game log says so and the returned unit is not alive: ordering it does nothing.
The same goes for an owner that cannot own a unit (player.Everyone).
SpawnUnitByID
func SpawnUnitByID(definition string, x, y float64, owner player.ID) UnitSpawnUnitByID is SpawnUnit with the definition's id (the uuid in definitions.toml), which survives a rename of the definition.
UnitByID
func UnitByID(id int) UnitUnitByID returns the handle of a unit by its number in the simulation (0 and up). It need not exist; Alive tells.
Units
func Units() []UnitUnits are all the units still on the map, dead ones included until they are removed.
Unit.Alive
func (u Unit) Alive() boolAlive is whether the unit exists and has health left.
Unit.Attack
func (u Unit) Attack(target Unit)Attack orders the unit to attack another until one of them is dead.
Unit.Damage
func (u Unit) Damage(amount float64)Damage hurts the unit by amount health, as a blow from nobody would: it can die of it, and
armour does not count. Damage of 0 or less does nothing. The map hears it in
event.OnUnitDamaged with no attacker.
Unit.GiveItem
func (u Unit) GiveItem(itemID string)GiveItem puts a new item in the unit's inventory (six slots) without a shop and without gold. itemID is the item's id in the editor's items file. Nothing happens when the inventory is full, the item does not exist or the unit is dead; the map hears event.OnItemBought either way it worked. The item's bonuses apply at once.
Unit.Glide
func (u Unit) Glide(vx, vy float64)Glide makes the unit drift at a constant velocity (vx, vy), in world units a second, on top of whatever else it does. It is not an order: Move, Attack and the rest do not stop it, only Glide(0, 0) does (or the unit's death). The game does the moving itself, so it costs the script nothing after this one call. It ignores paths and obstacles but stays on the map. Buildings and dead units are not moved.
Unit.Heal
func (u Unit) Heal(amount float64)Heal gives the unit amount health back, up to its most. A dead unit is not healed.
Unit.Health
func (u Unit) Health() float64Health is the unit's health left.
Unit.ID
func (u Unit) ID() intID is the unit's number in the simulation, stable for the whole game.
Unit.Kill
func (u Unit) Kill()Kill kills the unit where it stands.
Unit.MaxHealth
func (u Unit) MaxHealth() float64MaxHealth is the most health the unit can have.
Unit.Move
func (u Unit) Move(x, y float64)Move orders the unit to walk to (x, y), in world units from the middle of the map.
Unit.Owner
func (u Unit) Owner() player.IDOwner is who owns the unit: one of the twelve players (player.Red and so on), player.Neutral or player.NeutralAggressive.
Unit.RemoveItem
func (u Unit) RemoveItem(slot int)RemoveItem takes the item in a slot (0 to 5) away for good; it does not drop. An empty slot does nothing.
Unit.SetPosition
func (u Unit) SetPosition(x, y float64)SetPosition puts the unit at (x, y) at once, in world units from the middle of the map, without walking. The unit goes on with what it was doing (a walk is planned again from the new place). Buildings and dead units are not moved.
Unit.String
func (u Unit) String() stringUnit.X
func (u Unit) X() float64X is the unit's position in world units from the middle of the map.
Unit.Y
func (u Unit) Y() float64Y is the unit's position in world units from the middle of the map.