Reference · Updated 2552.10.23.16.45
Game Types
What a match is played as (Slayer, Team Slayer), how the host's choice gets from the lobby into the match, and how the match counts down, scores and ends. The design reasons are in
What a match is played as (Slayer, Team Slayer), how the host's choice gets from the lobby into the match, and how the match counts down, scores and ends. The design reasons are in MultiplayerPlan.md §6; this is how it is built.
#1. A game type is a data asset
USLGameTypeDefinition: a primary asset (typeSLGameType) holding aDisplayName, aDescription, an
optional Icon, a SortOrder and the rules, FSLGameTypeSettings.
- Where they live:
/Game/SystemLink/Game/GameTypes, the only folderDefaultGame.iniscans. An asset saved
anywhere else is not found.
- Adding one is a new asset, never a screen edit. The lobby lists every definition it finds, ordered by
SortOrder; the first is the one a new lobby opens on.
The shipped types:
| Asset | Teams | Kill goal | Notes |
|---|---|---|---|
GT_Slayer | off | 25 | Free-for-all |
GT_TeamSlayer | on | 50 | Red against Blue |
GT_TestTeamSlayer | on | 3 | For testing a whole match quickly. Not for players |
GT_TestSlayer | off | 3 | Free-for-all to 3, for quick playtests. Not for players |
#The rules: FSLGameTypeSettings
A plain struct rather than an asset, so the same block can come from a shipped definition now and from a player's saved custom type later (SL-46), and travel to the match either way.
| Setting | Default | Effect |
|---|---|---|
bTeams | off | Red against Blue. Off is a free-for-all: everyone on no team, everyone else an opponent |
KillGoal | 25 | The score that wins: a player's in a free-for-all, a team's in a team game |
CountdownSeconds | 5 s | How long everyone waits at their spawn, able to look but not move or shoot. 0 starts at once |
It starts with only what Slayer needs. Friendly fire, respawn, loadout and modifiers join it as they are built.
#2. From the lobby into the match
- The host picks in the lobby.
ASLLobbyGameState::SetSelectedGameTypeis server only and replicates the - a free-for-all puts everyone on no team
- a team game keeps everyone already on a side and balances the rest
choice. Before anyone's lobby redraws, it moves everyone to the new type's teams (SLTeams::ApplyGameType):
- Start (
ASLLobbyGameMode::TravelToSelectedMap) hands the type and the number of players in the lobby,
split-screen guests included, to USLMatchSettingsSubsystem, then hard travels with ?listen.
- Why a game instance subsystem: a hard travel rebuilds the game mode, the game state and every PlayerState.
The game instance is the one thing that survives it. The subsystem is server side only; clients learn the rules from the match's replicated state.
- The match picks them up.
ASLGameModeBase::InitGameStatecopies the settings ontoASLMatchGameState,
which replicates them. Arriving players get their teams in InitNewPlayer (SLTeams::AssignOnArrival); a team brought from the lobby is ignored in a free-for-all.
- Back in the lobby, it opens on the type the last match used (
GetLastGameTypeId), so the host doesn't have
to pick it again.
A map opened directly, as TestMap is in development, has no lobby and no settings in the subsystem. The match then uses the game mode's SettingsWithoutLobby (teams on), skips the wait and countdown, and never returns to a lobby.
#3. The match
ASLMatchGameState holds the phase, the team scores and the winner, and every machine reacts to them itself.
#Phases (ESLMatchPhase)
| Phase | What players can do |
|---|---|
Countdown | Look, but not move or shoot. First waiting for everyone to load, then counting down |
InProgress | Play |
Over | Nothing: input stops and the score is final |
#Countdown
- Wait for everyone. A lobby-started match begins in
Countdown(WaitForPlayers). Each player controller
reports in once it has a pawn and its loading screen is gone (Server_ReportReadyForCountdown).
- Count down when everyone from the lobby has reported, or after
MaxWaitForPlayers(15 s) if someone is slow
or dropped. StartCountdown ignores a second call, so both can try.
- The end time is replicated, not a count each second, so every machine counts down on its own and stays in
step.
USLCountdownWidgetshows "5, 4, 3, 2, 1" and then "Go!". Place a subclass anywhere in the HUD; it reads
the match state itself, and each split-screen player's HUD shows its own. Its tick and go sounds play once per machine, not once per split-screen player. Waiting for players shows nothing.
Eliminations during the countdown are not scored. A fall out of the world still kills.
#Scoring (SLScoring)
World-free, so the automation tests run it directly.
- A player's score is kills, less suicides and betrayals. Being killed costs nothing.
- A team's score moves with each elimination: a kill is +1 to the killer's team, a suicide −1 to the victim's,
a betrayal −1 to the killer's. It is the team's own tally, so a player who leaves doesn't take their points with them.
- The report's ranking (
RankPlayers): equal scores share a place and the next place skips past them
(1st, 1st, 3rd). Kills, then fewer deaths, only order rows within a tie.
#The end
- The server scores each elimination (
ScoreElimination) afterRecordEliminationhas applied it to the
tallies. When a player (free-for-all) or team reaches the kill goal, the phase goes to Over with the winner and the final results (FSLMatchResults) in the same update, so a client never sees the end before the numbers.
- Every machine ends it locally from
OnRep_Phase: gameplay input stops for its own players, and each reads
who won, or USLAnnouncerSettings::LoseMessage ("You Lose") if they didn't. The announcer's "game over" line plays once per machine.
- The server cancels every ability, so an automatic weapon already firing stops.
- After
ReturnToLobbyDelay(5 s) the host hard travels everyone back to the lobby, where each machine shows
its results until one of its players dismisses them.
The announcer's lines and the losing text are under Project Settings > System Link > System Link Announcer.
#4. Testing
- Automation tests:
SystemLink.Scoring.(player score, team score changes, ranking) andSystemLink.Teams.
(including ChooseForGameType).
- PIE or LAN checks for the live match, with
GT_TestTeamSlayerso it ends at 3: - Changing the game type in the lobby moves everyone's teams, and every player sees the new type.
- Starting from the lobby, everyone waits at their spawn until all have loaded, then sees the same countdown,
- A kill, a suicide and a betrayal move the scores as above.
- Reaching the kill goal stops everyone, shows the winner (or "You Lose"), and returns to the lobby, which opens
- In split-screen, each player gets their own countdown and result, and each sound plays once.
and nobody can move or shoot until "Go!".
on the same game type.