Players and owners

A map has twelve players. Every unit has an owner, which is either one of those players or one of two neutral owners. A script never writes a number for them: the w4/player package has a name for each, of the type player.ID.

Name Meaning
player.Red, player.Blue, player.Teal, player.Purple, player.Yellow, player.Orange, player.Green, player.Pink, player.Gray, player.LightBlue, player.DarkGreen, player.Brown The twelve players, in the order of the Players module
player.Neutral Passive neutrals: critters, shops and the like. They never attack and are never attacked
player.NeutralAggressive Creeps. They attack every player
player.Everyone Not an owner. It means all players, for the calls that show something

The names are the colours the players start with. A map can rename a player in the Players module, and the name player.Red still means the first player. Names, colours and teams are set there. See Players, teams and owners for that side of it.

A variable that holds a player may be called player too, as in func(player player.ID, args string). Inside that function it hides the package, which only matters if you also need player.Red there; the examples on this site use p.

Where a script meets a player

  • game.SpawnUnit(name, x, y, owner) gives the new unit to that owner. player.Everyone cannot own a unit, so the log says so and nothing is spawned.
  • u.Owner() tells you who owns a unit.
  • The function you give to game.Command gets the player who typed the command.
  • The function you give to ui.Button gets the player who clicked.
  • Every ui call takes a player, or player.Everyone. A neutral owner has no screen, so the log says so.
event.OnUnitDied(func(u game.Unit) {
	switch owner := u.Owner(); {
	case owner == player.NeutralAggressive:
		game.Print("a creep died")
	case owner.IsPlayer():
		game.Printf("%v lost a unit", owner)
	}
})

IsPlayer() is true for the twelve players and false for the neutral owners and Everyone. A player.ID prints as its name: Red, Light Blue, Neutral Aggressive.

Per player state

A script has no player objects yet. If you want gold, a score or a level for each player, keep it yourself, for example in a map from player to value:

var score = map[player.ID]int{}

func addScore(p player.ID, n int) {
	score[p] += n
	ui.Text(p, "score", fmt.Sprintf("Score: %d", score[p]), ui.TopRight, 20, 20)
}

This needs fmt, w4/player and w4/ui imported. Because ui.Text takes a player, each player sees their own number.

Teams and gold

A script cannot read the teams or the game's gold yet. Players on the same team never attack each other in the simulation, but the script has to know the teams from the map you made. See What is next.