From 0fffa21ff1152760a926ddf0e33ded1e95f62a96 Mon Sep 17 00:00:00 2001 From: para Date: Mon, 23 Dec 2024 03:15:16 -0800 Subject: [PATCH] Refactors, Introduce GameManager, Lobby work, Docs --- Assets/scenes/minimal.scene | 41 ++++++++++++++++++------- Docs/game-design.md | 48 ++++++++++++++++++++++++++++++ code/Client.cs | 7 +++-- code/GameManager.cs | 22 ++++++++++++++ code/LobbyManager.cs | 25 ++++++++++++++++ code/NetworkManager.cs | 8 ++--- code/RoundConfiguration.cs | 9 ++++++ code/UI/{Hud.razor => Lobby.razor} | 15 +++------- lucker_party.sbproj | 20 +++++++++++-- lucker_party.sln.DotSettings.user | 6 ++++ 10 files changed, 170 insertions(+), 31 deletions(-) create mode 100644 Docs/game-design.md create mode 100644 code/GameManager.cs create mode 100644 code/LobbyManager.cs create mode 100644 code/RoundConfiguration.cs rename code/UI/{Hud.razor => Lobby.razor} (53%) diff --git a/Assets/scenes/minimal.scene b/Assets/scenes/minimal.scene index bcf89cf..5772c4d 100644 --- a/Assets/scenes/minimal.scene +++ b/Assets/scenes/minimal.scene @@ -49,22 +49,41 @@ "Components": [ { "__type": "LuckerParty.NetworkManager", - "__guid": "66cfc3ad-f9a2-49fa-b72b-cf0498aadfad", - "ClientGroup": { - "_type": "gameobject", - "go": "3a8c9a1d-2623-4041-bb55-40bce397cd02" - } + "__guid": "beaf09d7-3c2d-4ce3-9607-24ee3b4e5617" + } + ] + }, + { + "__guid": "c1903bc9-6a9f-41b5-bed7-b4fb2d50fcde", + "Flags": 0, + "Name": "Game Manager", + "Enabled": true, + "Components": [ + { + "__type": "LuckerParty.GameManager", + "__guid": "053898a9-71a7-48a7-9ebc-3c57d6ec5ca4" + } + ] + }, + { + "__guid": "076002c4-f60b-4ccc-8306-416e80d700df", + "Flags": 0, + "Name": "UI Root", + "Enabled": true, + "Components": [ + { + "__type": "Sandbox.ScreenPanel", + "__guid": "f6380618-4c54-4bdc-9dee-ab8705b685cf", + "AutoScreenScale": true, + "Opacity": 1, + "Scale": 1, + "ScaleStrategy": "ConsistentHeight", + "ZIndex": 100 } ] } ] }, - { - "__guid": "3a8c9a1d-2623-4041-bb55-40bce397cd02", - "Flags": 0, - "Name": "Clients", - "Enabled": true - }, { "__guid": "97cb86cc-36d4-46cf-8506-c1bc373ed142", "Flags": 0, diff --git a/Docs/game-design.md b/Docs/game-design.md new file mode 100644 index 0000000..f2bf98b --- /dev/null +++ b/Docs/game-design.md @@ -0,0 +1,48 @@ +# Game Design + +This document details how Lucker Party is intended to work by describing how the game flows from start to finish. + +But right now it's just a brainstorming document for the technical architecture. + +## Terms + +- **Lobby** - The initial game state where players get ready to play a Round. +- **Round** - A number of minigames played back-to-back. A Round starts when the Host starts the game from the Lobby. +- **Minigame** - An individual custom game that all players score points in. +- **Player** - an active member of the round. Players can get points and will be included in the Round stats +- **Spectator** - A Client that's not an active member of the round. The minigame can choose what controls the Spectator + receives to interact with the scene. + +## Lobby + +### Creation + +When the lobby is initially created by the host, a Lobby UI is presented to the host and anyone else who joins +thereafter. + +### Lobby UI + +The Lobby UI shows: + +- The list of Clients +- Game Settings + - Number of minigames +- Client Settings + - Color - This player's visual tint for identification in the mini games +- A Start Game button + +When the Start Game button is pressed a countdown starts, and after the first minigame starts + +## Round Manager + +Manages the current Round. Starting, stopping, triggering minigames from the manager, etc. + +Think of the Round Manager as the orchestrator of the set of minigames for the round. + +The round manager has different states that is passes through from start to finish of a Round. Some ideas that aren't +implemented yet: + +- Countdown before the first minigame +- Starting a minigame +- Pausing a minigame +- Receives signal from the Minigame that it has finished \ No newline at end of file diff --git a/code/Client.cs b/code/Client.cs index 967dcf7..453a48a 100644 --- a/code/Client.cs +++ b/code/Client.cs @@ -1,4 +1,4 @@ -using LuckerParty.UI; +using System; namespace LuckerParty; @@ -10,9 +10,10 @@ public sealed class Client : Component { public Connection Connection { get; set; } + public string Name => Connection.DisplayName; + public DateTimeOffset ConnectionTime => Connection.ConnectionTime; + protected override void OnStart() { - GameObject.AddComponent(); - GameObject.AddComponent(); } } diff --git a/code/GameManager.cs b/code/GameManager.cs new file mode 100644 index 0000000..6529887 --- /dev/null +++ b/code/GameManager.cs @@ -0,0 +1,22 @@ +namespace LuckerParty; + +/// +/// Manages the Game state, which right now is either Lobby or Round. +/// Maintains the lifecycle of the Lobby and Round Managers. +/// +public sealed class GameManager : Component +{ + public enum State + { + Lobby, + Round + } + + public State CurrentState { get; private set; } = State.Lobby; + + protected override void OnStart() + { + // Start Lobby + GameObject.AddComponent(); + } +} diff --git a/code/LobbyManager.cs b/code/LobbyManager.cs new file mode 100644 index 0000000..20f93f2 --- /dev/null +++ b/code/LobbyManager.cs @@ -0,0 +1,25 @@ +using LuckerParty.UI; + +namespace LuckerParty; + +public sealed class LobbyManager : Component +{ + private PanelComponent _panelComponent; + + protected override void OnEnabled() + { + var screenPanel = Scene.Directory.FindByName( "UI Root" ).First(); + _panelComponent = screenPanel.AddComponent(); + } + + protected override void OnDisabled() + { + _panelComponent.Destroy(); + _panelComponent = null; + } + + public interface ILobbyEvent : ISceneEvent + { + void OnStartGame( RoundConfiguration roundConfiguration ); + } +} diff --git a/code/NetworkManager.cs b/code/NetworkManager.cs index f657a01..81beb34 100644 --- a/code/NetworkManager.cs +++ b/code/NetworkManager.cs @@ -13,12 +13,12 @@ public sealed class NetworkManager : Component, Component.INetworkListener /// /// A GameObject used for organizational grouping of Clients /// - private GameObject ClientGroup { get; set; } + private GameObject _clientGroup; public void OnActive( Connection channel ) { // Set up the Client GameObject - var gameObject = new GameObject( ClientGroup ) { Name = $"{channel.DisplayName} ({channel.SteamId})" }; + var gameObject = new GameObject( _clientGroup ) { Name = $"{channel.DisplayName} ({channel.SteamId})" }; _clientMap.Add( channel, gameObject ); var client = gameObject.AddComponent(); client.Connection = channel; @@ -41,11 +41,11 @@ public sealed class NetworkManager : Component, Component.INetworkListener protected override void OnAwake() { - ClientGroup = new GameObject( Scene.Root ); + _clientGroup = new GameObject( Scene.Root ) { Name = "Clients", NetworkMode = NetworkMode.Object }; } protected override void OnDestroy() { - ClientGroup.Destroy(); + _clientGroup.Destroy(); } } diff --git a/code/RoundConfiguration.cs b/code/RoundConfiguration.cs new file mode 100644 index 0000000..0f3d642 --- /dev/null +++ b/code/RoundConfiguration.cs @@ -0,0 +1,9 @@ +namespace LuckerParty; + +/// +/// Contains configuration for a Round, usually created by the host in a Lobby. +/// +public class RoundConfiguration +{ + public uint NumberOfMinigames { get; set; } +} diff --git a/code/UI/Hud.razor b/code/UI/Lobby.razor similarity index 53% rename from code/UI/Hud.razor rename to code/UI/Lobby.razor index 8548b51..3740027 100644 --- a/code/UI/Hud.razor +++ b/code/UI/Lobby.razor @@ -1,27 +1,20 @@ +@namespace LuckerParty.UI @using System @inherits PanelComponent -@namespace LuckerParty.UI -
Hello, @_name
+
This is the Lobby
@code { - - private string _name; - - protected override void OnAwake() - { - base.OnAwake(); - _name = GameObject.GetComponent().Connection.DisplayName; - } + public List Clients { get; set; } /// /// the hash determines if the system should be rebuilt. If it changes, it will be rebuilt /// protected override int BuildHash() { - return HashCode.Combine( _name ); + return HashCode.Combine( Clients ); } } diff --git a/lucker_party.sbproj b/lucker_party.sbproj index 7371b11..8e2dec2 100644 --- a/lucker_party.sbproj +++ b/lucker_party.sbproj @@ -1,7 +1,7 @@ { "Title": "Lucker Party", "Type": "game", - "Org": "local", + "Org": "concoshut", "Ident": "lucker_party", "Schema": 1, "IncludeSourceFiles": false, @@ -22,6 +22,22 @@ "PerMapRanking": false, "LeaderboardType": "None", "CsProjName": "", - "StartupScene": "scenes/minimal.scene" + "StartupScene": "scenes/minimal.scene", + "Compiler": { + "RootNamespace": "LuckerParty", + "DefineConstants": "SANDBOX;ADDON;DEBUG", + "NoWarn": "1701;1702;1591;", + "WarningsAsErrors": "", + "TreatWarningsAsErrors": false, + "Nullables": false, + "Whitelist": true, + "ReleaseMode": "Debug", + "AssemblyReferences": [], + "IgnoreFolders": [ + "editor", + "unittest" + ], + "DistinctAssemblyReferences": [] + } } } \ No newline at end of file diff --git a/lucker_party.sln.DotSettings.user b/lucker_party.sln.DotSettings.user index 81f1856..1c5d4b1 100644 --- a/lucker_party.sln.DotSettings.user +++ b/lucker_party.sln.DotSettings.user @@ -1,16 +1,22 @@  ForceIncluded + ForceIncluded ForceIncluded + ForceIncluded ForceIncluded ForceIncluded ForceIncluded ForceIncluded + ForceIncluded + ForceIncluded ForceIncluded ForceIncluded ForceIncluded ForceIncluded ForceIncluded ForceIncluded + ForceIncluded + ForceIncluded ForceIncluded ForceIncluded <AssemblyExplorer>