Commands and interface
Two ways for a player to talk to your script: a slash command typed in the chat, and a button on the screen. Two ways for the script to talk back: the log, and the w4/ui package.
Slash commands
game.Command adds a command to the chat:
game.Command("wave", "<n>", "Sends n waves now", func(p player.ID, args string) {
game.Printf("%v asked for %s waves", p, args)
})The four arguments are the name, a hint for the arguments, a line of help, and the function to call. A player types /wave 3, and your function gets the player (a player.ID) and the rest of the line, "3". Turning that into a number is up to you (strconv.Atoi).
- The name is made lower case. It may hold letters, digits and
-. A name with anything else is ignored. - The hint and the help appear in
/helpand in the list that opens as you type. Players complete a name with Tab. - Registering a name twice replaces the earlier command.
argsis at most 4096 bytes.- Register commands in
mainor inMapInit.
Elements, ids and players
Every ui element has an id and a player. Call the same function again with the same id and player, and it replaces the element. That is how you change a score: call ui.Text again.
The player is one of the twelve (player.Red and so on), or player.Everyone. See Players and owners. Each player can get their own text, their own buttons and their own quests.
Where things go
Position is an anchor plus two offsets. The anchors are the corners, the edges and the centre: ui.TopLeft, ui.Top, ui.TopRight, ui.Left, ui.Center, ui.Right, ui.BottomLeft, ui.Bottom, ui.BottomRight.
The offsets go inwards from the anchor. From a left anchor, x goes right. From a right anchor, x goes left. From a top anchor, y goes down. From a bottom anchor, y goes up. Units are pixels of a 1080-pixel-tall screen, scaled to the real one, so a layout looks the same at 1080p and 4K.
Text
ui.Text(player.Everyone, "title", "Welcome", ui.Top, 0, 20, ui.Size(26), ui.Color("ffd27a"))ui.Size(px) sets the text size, 18 is the usual. ui.Color("rrggbb") sets the colour in hex, with or without a leading #.
Buttons
ui.Button(player.Everyone, "hello", "Say hello", ui.Bottom, 0, 120, func(p player.ID) {
game.Printf("%v clicked", p)
})The function gets the player who clicked. It runs inside the simulation like every other handler. If you call ui.Button again with the same id, the new one replaces the old one, click function included.
Panels
ui.Panel(player, id, anchor, x, y, w, h) draws a box, w by h pixels. Other elements go inside it with the ui.In option, and their anchor and offsets then refer to the panel:
ui.Panel(player.Everyone, "shop", ui.Bottom, 0, 130, 300, 90)
ui.Text(player.Everyone, "shop.title", "Shop", ui.Top, 0, 10, ui.In("shop"))Hide, show, remove
ui.Hide(player, "shop") // off the screen, kept
ui.Show(player, "shop") // back
ui.Remove(player, "shop") // gone for goodA panel takes what is inside it along. Use the same player you made the element for.
Quests
ui.Quest(player.Everyone, "survive", "Survive", "Hold out for ten minutes")
// later
ui.QuestDone("survive") // stays in the panel, in green
ui.QuestFailed("survive") // stays in the panel, in redQuests appear in the quest panel in the column on the right, under the top bar. A quest has a title and one line saying what to do. Calling ui.Quest again with the same id changes the text and makes it active again. QuestDone and QuestFailed take only the id, and do nothing for an id that was never added.
Floating text
A line of text over a place on the map, which rises and fades away by itself. It is the thing for damage numbers, "+10 gold" and "Level up!":
event.OnUnitDamaged(func(u, attacker game.Unit, amount float64) {
ui.FloatTextOver(player.Everyone, u, fmt.Sprintf("-%.0f", amount), ui.Color("ff4444"))
})
ui.FloatText(player.Red, "Wave 3", 0, 0, ui.Size(40), ui.Seconds(4)) // only the red player, at the middle of the mapFloatText(player, text, x, y, options...) takes a position in world units from the middle of the map, like a unit's. FloatTextOver uses where a unit stands now, and the text stays there when the unit walks on. ui.Size, ui.Color and ui.Seconds change the look; the usual life is two and a half seconds. The text is a picture only: it has no id, you cannot change or remove it, and nothing in the game changes. A text longer than 200 characters is cut.
A player can hide it all
Ctrl H or /hideui hides the whole interface, yours included, for a screenshot. Opening the chat brings it back.
Why it is safe for multiplayer
Interface calls are presentation. The game shows each element to the players it is for and sends clicks back to the script. Nothing in the simulation depends on whether an element is on a screen.
More
The map interface tutorial builds a shop with a button and a command. The reference is package game and package ui.
Not built yet: images, bars, text input and tooltips on map elements.