GameManager.cs
// Project: truth
// File: GameManager.cs
// Author: cseliot
// Created: 2026.10.29.07.10.14
// Edited: 2026.10.29.07.38.15
//
// Copyright (c) 2026 KiteLion Games, LLC. All rights reserved.
//
// This source code is the property of KiteLion Games, LLC and may not be
// copied, distributed, modified, or used in any way without prior written
// permission from KiteLion Games, LLC.
//
// Description:
// [Provide a brief description of what this file/class does.]
//
// License:
// This code 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.
using System;
using System.Runtime.CompilerServices;
namespace Sandbox;
public sealed class GameManager : Component
{
public enum GameState
{
Waiting,
PreRound,
InRound,
PostRound,
}
public GameState _gameState;
[Property] public int SEED;
[Property] public GameObject Floor;
[Property] public TextRenderer WorldText;
private float _inRoundMaxTime = 34;
private float _inRoundStartTime;
// private Text
protected override void OnStart()
{
_gameState = GameState.Waiting;
Game.SetRandomSeed( SEED );
}
protected override void OnUpdate()
{
var truthCCs = Scene.GetAllComponents<TruthCC>().ToArray();
if ( truthCCs.Length <= 1 )
_gameState = GameState.Waiting;
// Log.Info("Game State: " + _gameState);
if ( _gameState == GameState.Waiting )
{
WorldText.Text = "Waiting for players ...";
if ( truthCCs.Length > 1)
{
// Log.Info(truthCCs.Length + " player(s) found");
var everyoneReady = true;
foreach ( var truthCC in truthCCs )
{
if ( truthCC.IsReady == false )
{
everyoneReady = false;
break;
}
}
if ( everyoneReady )
{
_gameState = GameState.PreRound;
}
}
}
if ( _gameState == GameState.PreRound )
{
WorldText.Text = "Choosing Random Player ...";
if( Networking.IsHost )
{
var randPlayer = Game.Random.Next( 0, truthCCs.Length );
var truthingPlayerID = truthCCs.ElementAt(randPlayer).Network.OwnerId;
HelperSetModeInRound( truthingPlayerID );
}
}
if ( _gameState == GameState.InRound )
{
WorldText.Text = "" + (_inRoundStartTime + _inRoundMaxTime - Time.Now).FloorToInt();
if( Networking.IsHost)
{
if( truthCCs.Length >= 1 && truthCCs.All( t => t.IsAcceptingTruth || t.PlayerState == TruthCC.EPlayerState.Truthing ) )
HelperSetModePostRound(truthCCs);
else if ( Time.Now - _inRoundStartTime > _inRoundMaxTime )
HelperKillTruthingPlayer(truthCCs);
}
}
}
[Rpc.Broadcast]
private void HelperKillTruthingPlayer( TruthCC[] truthCCs )
{
foreach ( var truthCC in truthCCs )
{
if ( truthCC.PlayerState == TruthCC.EPlayerState.Truthing )
{
// if(truthCC.Network.IsOwner)
// Floor.Enabled = false;
truthCC.GameObject.Tags.Add("notsolid");
truthCC.GameObject.GetComponent<TruthCC>().Destroy();
}
}
}
[Rpc.Broadcast]
private void HelperSetModeInRound( Guid truthingPlayerID )
{
_gameState = GameState.InRound;
_inRoundStartTime = Time.Now;
var truthCCs = Scene.GetAllComponents<TruthCC>().ToArray();
foreach ( var player in truthCCs )
{
if ( player.Network.OwnerId == truthingPlayerID )
player.PlayerState = TruthCC.EPlayerState.Truthing;
else
player.PlayerState = TruthCC.EPlayerState.Voting;
}
}
[Rpc.Broadcast]
private void HelperSetModePostRound( TruthCC[] truthCCs)
{
_gameState = GameState.PreRound;
Log.Info("IN POST ROUND!");
foreach ( var player in truthCCs )
{
player.PlayerState = TruthCC.EPlayerState.Waiting;
player.IsAcceptingTruth = false;
}
}
}