Comitting lobby code without testing.

This commit is contained in:
Matt F 2026-05-15 14:30:15 -07:00
parent 66f84652dc
commit 60fa58b07f
14 changed files with 1207 additions and 37 deletions

View file

@ -89,30 +89,91 @@ namespace TD.Gameplay
writePerm: NetworkVariableWritePermission.Server
);
// STUBBED — written by the race-pick system (Phase 1.8). None until a race is chosen.
[Tooltip("STUBBED — not written until the race-pick system lands (Phase 1.8).")]
// Race chosen by this player. Written by the lobby system in response to
// SetRaceRpc; carries over scene transitions because PlayerMatchState is
// the player prefab (owned by the connection, persists across scenes).
private readonly NetworkVariable<RaceId> raceSelection = new NetworkVariable<RaceId>(
value: RaceId.None,
readPerm: NetworkVariableReadPermission.Everyone,
writePerm: NetworkVariableWritePermission.Server
);
// Lobby ready-state. Cleared back to false on scene transitions out of
// the lobby (the new lobby session starts everyone un-ready).
private readonly NetworkVariable<bool> isReady = new NetworkVariable<bool>(
value: false,
readPerm: NetworkVariableReadPermission.Everyone,
writePerm: NetworkVariableWritePermission.Server
);
/// <summary>This player's assigned slot in the match. Authoritative once spawned.</summary>
public PlayerSlot Slot => slot.Value;
/// <summary>Display name. Stub until a lobby/name system provides it.</summary>
public string DisplayName => displayName.Value.ToString();
/// <summary>STUBBED. Race chosen by this player. <see cref="RaceId.None"/> until Phase 1.8.</summary>
/// <summary>Race chosen by this player. <see cref="RaceId.None"/> until selected in the lobby.</summary>
public RaceId RaceSelection => raceSelection.Value;
/// <summary>STUBBED. Sets this player's race selection. Called by the race-pick system (Phase 1.8).</summary>
/// <summary>True if this player has marked themselves ready in the lobby.</summary>
public bool IsReady => isReady.Value;
/// <summary>Server-only. Sets this player's race selection.</summary>
public void SetRaceSelection(RaceId race)
{
if (!IsServer) { Debug.LogWarning("[PlayerMatchState] SetRaceSelection called on a client — ignored."); return; }
raceSelection.Value = race;
}
/// <summary>Server-only. Sets this player's ready state.</summary>
public void SetReady(bool ready)
{
if (!IsServer) { Debug.LogWarning("[PlayerMatchState] SetReady called on a client — ignored."); return; }
isReady.Value = ready;
}
// ----- Client → Server lobby RPCs --------------------------------
/// <summary>
/// Client → server: submit a race selection. Owner-only — players can
/// only change their own race. Validates that the caller is the owner
/// of this PlayerMatchState; ignored otherwise.
/// </summary>
[Rpc(SendTo.Server, InvokePermission = RpcInvokePermission.Owner)]
public void SubmitRaceRpc(RaceId race)
{
// Reset ready state when race changes — players shouldn't be "ready"
// with a stale pick.
if (raceSelection.Value != race)
{
raceSelection.Value = race;
isReady.Value = false;
}
}
/// <summary>
/// Client → server: submit ready state. Owner-only. A player can only
/// ready up if they've picked a race; the lobby UI gates this already
/// but the server enforces it as a safety net.
/// </summary>
[Rpc(SendTo.Server, InvokePermission = RpcInvokePermission.Owner)]
public void SubmitReadyRpc(bool ready)
{
if (ready && raceSelection.Value == RaceId.None)
{
Debug.Log($"[PlayerMatchState] Slot {Slot} tried to ready up without a race. Ignored.");
return;
}
isReady.Value = ready;
}
/// <summary>
/// Server-side helper: enumerate every currently-spawned PlayerMatchState.
/// Used by <c>LobbyService</c> to evaluate "are all players ready" and
/// by <c>LobbyController</c> on every peer to render the player list.
/// </summary>
public static IEnumerable<PlayerMatchState> AllPlayers => s_byClientId.Values;
/// <summary>
/// Server-only. Fires on the server immediately after the slot is assigned in
/// <see cref="OnNetworkSpawn"/>. Sibling components (e.g. PlayerBuilderSpawner)