Delayed lobby start (#4184)

Resolves #4169

## Description:

Adds a delayed lobby start option.
Utilizes the same system as for public lobbies.
The default for the option is for lobbies to take 3 seconds to start,
however this can easily be changed.

The current setting is controlled through an enable-disable slider,
however there are multiple other options for how to control this.
For example we could do a slider, an input field, a dropdown etc. And i
dont necessarily know if the currently implemented option is the best.

Furhtermore im not sure if i have used the language file completely
correctly. There is now a duplicate field for both private and public
lobby. However there is not category shared between the two. So i
decided to reuse the field from public for private games, as this
simplified the code a bit.

**Host video**

https://github.com/user-attachments/assets/6f3db6e4-7323-4fad-8544-efb8cef4d969

**Non-host video**

https://github.com/user-attachments/assets/ee02a072-1f42-4dde-a5d9-120fda862eb7

## Please complete the following:

- [X] I have added screenshots for all UI updates
- [X] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory


## Please put your Discord username so you can be contacted if a bug or
regression is found:
FrederikJA
This commit is contained in:
FrederikJA
2026-06-12 12:22:03 -07:00
committed by GitHub
parent d96c055df1
commit 19db66f424
10 changed files with 212 additions and 105 deletions
+8 -5
View File
@@ -51,7 +51,7 @@ export type Intent =
| KickPlayerIntent
| TogglePauseIntent
| UpdateGameConfigIntent
| StartGameIntent;
| ToggleGameStartTimer;
export type AttackIntent = z.infer<typeof AttackIntentSchema>;
export type CancelAttackIntent = z.infer<typeof CancelAttackIntentSchema>;
@@ -85,7 +85,9 @@ export type TogglePauseIntent = z.infer<typeof TogglePauseIntentSchema>;
export type UpdateGameConfigIntent = z.infer<
typeof UpdateGameConfigIntentSchema
>;
export type StartGameIntent = z.infer<typeof StartGameIntentSchema>;
export type ToggleGameStartTimer = z.infer<
typeof ToggleGameStartTimerIntentSchema
>;
export type Turn = z.infer<typeof TurnSchema>;
export type GameConfig = z.infer<typeof GameConfigSchema>;
@@ -281,6 +283,7 @@ export const GameConfigSchema = z.object({
randomSpawn: z.boolean(),
maxPlayers: z.number().optional(),
maxTimerValue: z.number().int().min(1).max(120).nullable().optional(), // In minutes
startDelay: z.number().int().min(0).max(600).nullable().optional(), // In seconds
spawnImmunityDuration: z.number().int().min(0).nullable().optional(), // In ticks
disabledUnits: z.enum(UnitType).array().optional(),
playerTeams: TeamCountConfigSchema.optional(),
@@ -481,8 +484,8 @@ export const UpdateGameConfigIntentSchema = z.object({
config: GameConfigSchema.partial(),
});
export const StartGameIntentSchema = z.object({
type: z.literal("start_game"),
export const ToggleGameStartTimerIntentSchema = z.object({
type: z.literal("toggle_game_start_timer"),
});
const IntentSchema = z.discriminatedUnion("type", [
@@ -510,7 +513,7 @@ const IntentSchema = z.discriminatedUnion("type", [
KickPlayerIntentSchema,
TogglePauseIntentSchema,
UpdateGameConfigIntentSchema,
StartGameIntentSchema,
ToggleGameStartTimerIntentSchema,
]);
// StampedIntent = Intent with server-stamped clientID (used in turns and execution)