Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rework the matchmaker lobby (autolobby) #6479

Merged
merged 85 commits into from
Nov 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
85 commits
Select commit Hold shift + click to select a range
8bf0529
Update annotations
Garanas Oct 15, 2024
914a3d9
Create a standalone and efficient map preview
Garanas Oct 15, 2024
6a535f3
Initial setup with a working preview
Garanas Oct 17, 2024
5fb02fc
First working setup that actually launches into the game
Garanas Oct 17, 2024
beedc76
Separate file for the controller
Garanas Oct 17, 2024
6924eca
Add documentation
Garanas Oct 18, 2024
2c662e0
Remove test function
Garanas Oct 18, 2024
417eb09
Remove old copyright statement
Garanas Oct 18, 2024
320f9f4
Add documentation
Garanas Oct 18, 2024
5473f88
Document behavior of GpgNetSend
Garanas Oct 18, 2024
10a49a2
Add remaining messages to the server
Garanas Oct 18, 2024
6c3c65a
Remove the old autolobby classes module
Garanas Oct 18, 2024
24a7aa4
Add a connection matrix to visualize the status quo
Garanas Oct 19, 2024
ce10a6b
Check support for up to 8 players
Garanas Oct 19, 2024
2abdc11
Use `~=` instead of `not`
Garanas Oct 19, 2024
9607e7e
Remove the wait for hot reload
Garanas Oct 19, 2024
e57b4e8
Make use of `ReusedLayoutFor`
Garanas Oct 19, 2024
a4f4c09
Clean up code
Garanas Oct 19, 2024
7d2d564
Rework messages
Garanas Oct 19, 2024
d1da9f4
Better document the use of the peer identifier
Garanas Oct 19, 2024
5be5fff
Add support for player colors based on the start position.
Garanas Oct 19, 2024
4d00504
Add a comment
Garanas Oct 19, 2024
fbe4183
Introduce a mapping from the peerId to an index
Garanas Oct 19, 2024
d41177b
Add documentation
Garanas Oct 19, 2024
45a5747
Fix prefetch not working properly
Garanas Oct 19, 2024
fb26d78
Introduce a delayed-joining of the lobby
Garanas Oct 19, 2024
1be791b
Improve management of peer indices
Garanas Oct 20, 2024
dd2613e
Add an initial delay before we populate the connection matrix
Garanas Oct 20, 2024
b67ba7e
Fix for peer to index functionality
Garanas Oct 20, 2024
10877ea
Keep track of the lobby creation/hosting/joining parameters
Garanas Oct 20, 2024
2ca02b3
Move GpgNetSend statement to the controller
Garanas Oct 20, 2024
9d86ee4
Create rejoin functionality
Garanas Oct 20, 2024
f5d430a
Always blip the interface when a message is received
Garanas Oct 20, 2024
07ee763
Do not add the interface to the trashbag of the controller
Garanas Oct 20, 2024
6c865fa
Remove reload testing code
Garanas Oct 20, 2024
19a3fa7
Make it crash-happy for 4z0t
Garanas Oct 20, 2024
5e7b21a
expand the matrix
Garanas Oct 20, 2024
e9670d3
Introduce sharing of local launch status
Garanas Oct 22, 2024
a64bba3
Set depth of `reprsl` to 2 by default
Garanas Oct 22, 2024
360fe25
Rename to 'Ready' instead of 'Ready for launch'
Garanas Oct 22, 2024
5823e21
Setup with working reconnect
Garanas Oct 22, 2024
0acd515
Remove LOG statement
Garanas Oct 22, 2024
e3ca5a9
Various tweaks all over
Garanas Oct 22, 2024
4350d0f
Rewrite test logic
Garanas Oct 22, 2024
fa733a9
Fix annotation issues
Garanas Oct 22, 2024
1482163
Reduce time for rejoin to kick in
Garanas Oct 22, 2024
58cf87b
Reduce the update frequency of the status message
Garanas Oct 23, 2024
7259a1f
Improve documentation of server communication
Garanas Oct 25, 2024
4226f96
Improve documentation
Garanas Oct 25, 2024
2e80516
Re-introduce sending player options to the server
Garanas Oct 25, 2024
879f8a1
Extend launch status messages
Garanas Oct 25, 2024
19bff39
Always log the message we send to the server
Garanas Oct 25, 2024
61a3d7d
Simplify the mapping of a peerId to an index for the UI
Garanas Oct 26, 2024
8c4ce67
Remove code that is not used
Garanas Oct 26, 2024
fa9a3d6
Add message validation to perform basic checks of the format of a mes…
Garanas Oct 26, 2024
24fdbd3
Fix functions not being pure
Garanas Oct 26, 2024
f043921
Cleaning up of logic
Garanas Oct 26, 2024
0e1edb5
Undo changes to the launch script
Garanas Oct 26, 2024
5e0547d
Improve annotations
Garanas Oct 26, 2024
d302a3e
Add annotations for scenario save file
Garanas Oct 26, 2024
e42abe8
Add documentation
Garanas Oct 26, 2024
38844a9
Merge branch 'develop' into feature/autolobby
Garanas Oct 27, 2024
53d8a5a
Apply the map utils pull request
Garanas Oct 27, 2024
179ad59
Fix issue with hot reload
Garanas Oct 27, 2024
bfa9d1d
Process feedback of Askaholic
Garanas Oct 27, 2024
c79983e
Send the disconnect message to the server
Garanas Oct 27, 2024
bd8f664
Fix a typo
Garanas Oct 27, 2024
232660e
Improve documentation
Garanas Oct 27, 2024
f621a31
Remove debug code
Garanas Oct 27, 2024
750e51e
Fix typo
Garanas Oct 27, 2024
1922ac6
Show what row/column is of the local client in connection matrix
Garanas Oct 27, 2024
d36e0a7
Add faction-spawn locations to map preview
Garanas Oct 30, 2024
788db99
Fix issue with hot reload
Garanas Oct 31, 2024
577f2e1
Document `SetColorMask`
Garanas Oct 31, 2024
70d37a5
Improve annotations of `StringSplit`
Garanas Oct 31, 2024
bc3be44
Add additional utility functions
Garanas Oct 31, 2024
92ab7f4
Setup for a panel with brackets
Garanas Oct 31, 2024
8df32fb
Revert "Setup for a panel with brackets"
Garanas Nov 19, 2024
523072b
Add brackets
Garanas Nov 19, 2024
e991a71
Disable the rejoin functionality
Garanas Nov 19, 2024
35d23f7
Remove debug code to not launch the game
Garanas Nov 19, 2024
cca7d0b
Removing logging and the like
Garanas Nov 19, 2024
4a1da1e
Merge branch 'develop' into feature/autolobby
Garanas Nov 19, 2024
b62a26a
Remove debugging code
Garanas Nov 19, 2024
10a916d
Add a snippet
Garanas Nov 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions changelog/snippets/features.6479.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
- (#6479) Rework the in-game matchmaker lobby from the ground up

From a user perspective the matchmaker lobby now has a map preview and a connection matrix. The map preview can help the players to understand what they'll be gating into. The connection matrix can help players to understand what source (a player) is connected to what source (another player). The diagonal represents what sources (other players) the local client is connected to. When you receive a message from a peer then it blinks the corresponding box in the matrix.

From a developers perspective the matchmaker lobby is now maintainable. You can now start the matchmaker lobby locally through your development environment. This allows you to run the matchmaker lobby as if you would find a match in the client. The matchmaker lobby is build from the ground up with maintainability in mind. It now supports a hot reload-like functionality for the interface. This allows you to change the interface on the go, without having to relaunch the game.

All taken together this is still very much a work in progress and we would love to hear the feedback of the community. We welcome you on Discord in the dev-talk channel.
13 changes: 7 additions & 6 deletions engine/User.lua
Original file line number Diff line number Diff line change
Expand Up @@ -624,9 +624,9 @@ end
function GpgNetActive()
end

---@param cmd string
---@param ... any
function GpgNetSend(cmd, ...)
---@param command string
---@param ... number | string
function GpgNetSend(command, ...)
end

---
Expand Down Expand Up @@ -709,14 +709,15 @@ end
---@alias UILobbyProtocols "UDP" | "TCP" | "None

--- For internal use by `CreateLobbyComm()`
---@param lobbyComClass fa-class
---@generic T
---@param lobbyComClass T
---@param protocol UILobbyProtocols
---@param localPort number
---@param maxConnections number
---@param playerName string
---@param playerUID? string
---@param natTraversalProvider? userdata
---@return UILobbyCommunication
---@return T
function InternalCreateLobby(lobbyComClass, protocol, localPort, maxConnections, playerName, playerUID, natTraversalProvider)
end

Expand Down Expand Up @@ -918,7 +919,7 @@ end

--- Start a background load with the given map and mods.
--- If `hipri` is true, this will interrupt any previous loads in progress.
---@param mapname string
---@param mapname string # path to the `scmap` file
---@param mods ModInfo[]
---@param hipri? boolean
function PrefetchSession(mapname, mods, hipri)
Expand Down
104 changes: 82 additions & 22 deletions engine/User/CLobby.lua
Original file line number Diff line number Diff line change
@@ -1,28 +1,86 @@
---@meta

---@class moho.lobby_methods : Destroyable


---@class moho.lobby_methods : Destroyable, InternalObject
local CLobby = {}

--- "0", "1", "2", but also "32254" and the like.
---@alias UILobbyPeerId string

---@alias GPGNetAddress string | number

---@alias UILobbyProtocol 'UDP' | 'TCP'

---@alias UIPeerConnectionStatus 'None' | 'Pending' | 'Connecting' | 'Answering' | 'Established' | 'TimedOut' | 'Errored'

---@class Peer
---@field establishedPeers string[]
---@field id string
---@field establishedPeers UILobbyPeerId[]
---@field id UILobbyPeerId # Is -1 when the status is pending
---@field ping number
---@field name string
---@field quiet number
---@field status string
---@field status UIPeerConnectionStatus

--- A piece of data that is one can send with `BroadcastData` or `SendData` to other player(s) in the lobby.
---@class UILobbyReceivedMessage : table
---@field SenderID UILobbyPeerId # Set by the engine, allows us to identify the source.
---@field SenderName string # Set by the engine, nickname of the source.
---@field Type string # Type of message

--- A piece of data that is one can send with `BroadcastData` or `SendData` to other player(s) in the lobby.
---@class UILobbyData : table
---@field Type string # Type of message

--- All the following fields are read by the engine upon launching the lobby to setup the scenario.
---@class UILobbyLaunchGameOptionsConfiguration
---@field UnitCap any # Read by the engine to determine the initial unit cap. See also the globals `GetArmyUnitCap`, `GetArmyUnitCostTotal` and `SetArmyUnitCap` to manipulate it throughout the scenario.
---@field CheatsEnabled any # Read by the engine to determine whether cheats are enabled.
---@field FogOfWar any # Read by the engine to determine how to manage the fog of war.
---@field NoRushOption any # Read by the engine to create the anti-rush mechanic.
---@field PrebuiltUnits any # Read by the engine to create initial, prebuilt units.
---@field ScenarioFile any # Read by the engine to load the scenario of the game.
---@field Timeouts any # Read by the engine to determine the behavior of time outs.
---@field CivilianAlliance any # Read by the engine to determine the alliance towards civilians.
---@field GameSpeed any # Read by the engine to determine the behavior of game speed (adjustments).

---@class UILobbyLaunchGameModsConfiguration
---@field name string # Read by the engine, TODO
---@field uid string # Read by the engine, TODO

---@class UILobbyLaunchObserverConfiguration
---@field OwnerID UILobbyPeerId # Read by the engine, TODO
---@field PlayerName string # Read by the engine, TODO

---@class UILobbyLaunchPlayerConfiguration
---@field StartSpot number # Read by Lua code to determine start locations
---@field ArmyName string # Read by the engine, TODO
---@field PlayerName string # Read by the engine, TODO
---@field Civilian boolean # Read by the engine, TODO
---@field Human boolean # Read by the engine, TODO
---@field AIPersonality string # Read by the engine iff Human is false
---@field ArmyColor number # Read by the engine, is mapped to a color by reading the values of `lua\GameColors.lua`.
---@field PlayerColor number # Read by the engine, is mapped to a color by reading the values of `lua\GameColors.lua`
---@field Faction number # Read by the engine to determine the faction of the player.
---@field OwnerID UILobbyPeerId # Read by the engine, TODO

--- All the following fields are read by the engine upon launching the lobby.
---@class UILobbyLaunchConfiguration
---@field GameMods UILobbyLaunchGameModsConfiguration[] # ModInfo[]
---@field GameOptions UILobbyLaunchGameOptionsConfiguration # GameOptions
---@field Observers UILobbyLaunchObserverConfiguration # PlayerData[]
---@field PlayerOptions UILobbyLaunchPlayerConfiguration[] # PlayerData[]

--- Broadcasts information to all peers. See `SendData` for sending to a specific peer.
---@param data CommunicationData
---@param data UILobbyData
function CLobby:BroadcastData(data)
end

--- Connect to a new peer. The peer will now show up in `GetPeer` and `GetPeers`
---@param address GPGNetAddress # includes the port
---@param name string
---@param uid string
function CLobby:ConnectToPeer(address, name, uid)
---@param peerId UILobbyPeerId
function CLobby:ConnectToPeer(address, name, peerId)
end

---
Expand All @@ -34,18 +92,18 @@ function CLobby:Destroy()
end

--- Disconnect from a peer. The peer will no longer show in `GetPeer` and `GetPeers`.
---@param uid string
function CLobby:DisconnectFromPeer(uid)
---@param peerId UILobbyPeerId
function CLobby:DisconnectFromPeer(peerId)
end

--- Eject a peer from the lobby. The peer will no longer show in `GetPeer` and `GetPeers`.
---@param targetID string
---@param peerId UILobbyPeerId
---@param reason string
function CLobby:EjectPeer(targetID, reason)
function CLobby:EjectPeer(peerId, reason)
end

--- Retrieves the local client identifier.
---@return number
---@return UILobbyPeerId
function CLobby:GetLocalPlayerID()
end

Expand All @@ -60,9 +118,9 @@ function CLobby:GetLocalPort()
end

--- Retrieves a specific peer
---@param uid string
---@param peerId UILobbyPeerId
---@return Peer
function CLobby:GetPeer(uid)
function CLobby:GetPeer(peerId)
end

--- Retrieves all peers
Expand All @@ -80,14 +138,16 @@ function CLobby:IsHost()
end

--- Joins a lobby hosted by another peer. See `HostGame` to host a game.
---
--- Is not idempotent - joining twice will generate an error.
---@param address GPGNetAddress
---@param remotePlayerName? string | nil
---@param remotePlayerUID? string
function CLobby:JoinGame(address, remotePlayerName, remotePlayerUID)
---@param remotePlayerPeerId? UILobbyPeerId
function CLobby:JoinGame(address, remotePlayerName, remotePlayerPeerId)
end

---
---@param gameConfig GameData
---@param gameConfig UILobbyLaunchConfiguration
function CLobby:LaunchGame(gameConfig)
end

Expand All @@ -98,16 +158,16 @@ function CLobby:MakeValidGameName(origName)
end

--- Creates a unique, alternative player name if that is required
---@param uid string
---@param peerId UILobbyPeerId
---@param origName string
---@return string
function CLobby:MakeValidPlayerName(uid, origName)
function CLobby:MakeValidPlayerName(peerId, origName)
end

--- Sends data to a specific peer. See `BroadcastData` for sending to all peers.
---@param targetID string
---@param data CommunicationData
function CLobby:SendData(targetID, data)
---@param peerId UILobbyPeerId
---@param data UILobbyData
function CLobby:SendData(peerId, data)
end

return CLobby
6 changes: 6 additions & 0 deletions engine/User/CMauiBitmap.lua
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,10 @@ end
function CMauiBitmap:UseAlphaHitTest(doHit)
end

--- Defines the color mask to be applied to bitmap during rendering (white images will get this color for example).
--- Introduced by [binary patch #42](https://github.com/FAForever/FA-Binary-Patches/pull/42)
---@param color string
function CMauiBitmap:SetColorMask(color)
end

return CMauiBitmap
2 changes: 2 additions & 0 deletions engine/User/CUIMapPreview.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ end

---
---@param textureName string
---@return boolean
function CUIMapPreview:SetTexture(textureName)
end

---
---@param mapName string
---@return boolean
function CUIMapPreview:SetTextureFromMap(mapName)
end

Expand Down
64 changes: 63 additions & 1 deletion lua/GameColors.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,66 @@
--******************************************************************************************************
--** Copyright (c) 2024 Willem 'Jip' Wijnia
--**
--** Permission is hereby granted, free of charge, to any person obtaining a copy
--** of this software and associated documentation files (the "Software"), to deal
--** in the Software without restriction, including without limitation the rights
--** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
--** copies of the Software, and to permit persons to whom the Software is
--** furnished to do so, subject to the following conditions:
--**
--** The above copyright notice and this permission notice shall be included in all
--** copies or substantial portions of the Software.
--**
--** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
--** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
--** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
--** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
--** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
--** SOFTWARE.
--******************************************************************************************************

-- When launching a lobby each player has a configuration. This configuration has the
-- fields `ArmyColor` and `PlayerColor`. The values of these fields are numbers. This
-- module is responsible for converting the integer-based player and army colors
-- into a hex-based color string that the engine understands.

local WarmColdMapping = {
-- 1v1
11, -- "ff436eee" (11) new blue1
01, -- "FFe80a0a" (01) Cybran red

-- 2v2
12, -- "FF2929e1" (12) UEF blue
02, -- "ff901427" (02) dark red

-- 3v3
14, -- "ff9161ff" (14) purple
03, -- "FFFF873E" (03) Nomads orange

-- 4v4
15, -- "ff66ffcc" (15) aqua
05, -- "ffa79602" (05) Sera golden

-- beyond 4v4, which we'll not likely support any time soon.
08,
19,
07,
05,
13,
16,
17,
04
}

--- Maps the start location of a player into a a warm vs cold color scheme. Read the
--- introduction of this module for more context.
---@param startSpot number
---@return number
MapToWarmCold = function(startSpot)
return WarmColdMapping[startSpot]
end

--- Determines the available colors for players and the default color order for
-- matchmaking. See autolobby.lua and lobby.lua for more information.
GameColors = {
Expand All @@ -7,7 +70,6 @@ GameColors = {
-- Default color order used for lobbies/TMM if not otherwise specified. Tightly coupled
-- with the ArmyColors and the PlayerColors tables.
LobbyColorOrder = { 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 }, -- rainbow-like color for Fearghal
TMMColorOrder = { 11, 01, 12, 02, 14, 03, 15, 05, 08, 19, 07, 05, 13, 16, 17, 04 }, -- warm vs cold

-- If you end up working with this file, suggestion to install the Color Highlight extension:
-- - https://marketplace.visualstudio.com/items?itemName=naumovs.color-highlight
Expand Down
2 changes: 1 addition & 1 deletion lua/maui/bitmap.lua
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ local ScaleNumber = import("/lua/maui/layouthelpers.lua").ScaleNumber
Bitmap = ClassUI(moho.bitmap_methods, Control) {
---@param self Bitmap
---@param parent Control
---@param filename Lazy<FileName>
---@param filename? Lazy<FileName>
---@param debugname? string
__init = function(self, parent, filename, debugname)
InternalCreateBitmap(self, parent)
Expand Down
1 change: 0 additions & 1 deletion lua/shared/color.lua
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,6 @@ end

--- Map of named colors the Moho engine can recognize and their representation
---@see EnumColorNames()
---@type table<EnumColor, Color>
EnumColors = {
AliceBlue = "F7FBFF",
AntiqueWhite = "FFEBD6",
Expand Down
3 changes: 3 additions & 0 deletions lua/system/utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,9 @@ function StringJoin(items, delimiter)
end

--- "explode" a string into a series of tokens, using a separator character `sep`
---@param str string
---@param sep string
---@return string[]
function StringSplit(str, sep)
local sep, fields = sep or ":", {}
local pattern = string.format("([^%s]+)", sep)
Expand Down
Loading
Loading