A singleton ModeController component for a game UI/flow. It stores selected game mode and language, manages master audio volume, loads scenes for selected modes or arbitrary paths, toggles language, and provides localized UI/game text via a switch expression.
using Sandbox;
public enum GameMode
{
SumoPush,
NextbotRun
}
public enum GameLanguage
{
English,
Russian
}
public sealed class ModeController : Component
{
public static ModeController Instance { get; private set; }
[Property] public GameMode SelectedMode { get; set; } = GameMode.SumoPush;
[Property] public GameLanguage CurrentLanguage { get; set; } = GameLanguage.Russian;
private float _masterVolume = 1.0f;
[Property]
public float MasterVolume
{
get => _masterVolume;
set
{
_masterVolume = MathX.Clamp( value, 0f, 1f );
ApplyMasterVolume();
}
}
[Property] public SceneFile SumoScene { get; set; }
[Property] public SceneFile NextbotScene { get; set; }
protected override void OnAwake()
{
Instance = this;
ApplyMasterVolume();
}
private void ApplyMasterVolume()
{
var masterMixer = Sandbox.Audio.Mixer.Master;
if ( masterMixer != null )
{
masterMixer.Volume = _masterVolume;
}
}
public void SelectMode( GameMode mode )
{
MusicManager.StopAllMusic();
SelectedMode = mode;
switch ( mode )
{
case GameMode.SumoPush:
if ( SumoScene != null )
Game.ActiveScene.Load( SumoScene );
else
Game.ActiveScene.LoadFromFile( "scenes/onemore.scene" );
break;
case GameMode.NextbotRun:
if ( NextbotScene != null )
Game.ActiveScene.Load( NextbotScene );
else
Game.ActiveScene.LoadFromFile( "scenes/OneMoreS2.scene" );
break;
}
}
public void LoadSceneDirect( string path )
{
if ( string.IsNullOrEmpty( path ) ) return;
MusicManager.StopAllMusic();
Game.ActiveScene.LoadFromFile( path );
}
public void ToggleLanguage()
{
CurrentLanguage = CurrentLanguage == GameLanguage.Russian ? GameLanguage.English : GameLanguage.Russian;
}
public string GetText( string key )
{
bool isRu = CurrentLanguage == GameLanguage.Russian;
return key switch
{
"game_title" => "ONE MORE PUSH",
"game_tagline" => isRu ? "СЕЗОН 2 • БИТВА НА АРЕНЕ" : "SEASON 2 • ARENA BRAWL",
"title" => isRu ? "ВЫБЕРИТЕ РЕЖИМ" : "SELECT GAME MODE",
"subtitle" => isRu ? "Выберите арену или режим и отправляйтесь в бой!" : "Choose an arena or mode and jump into action!",
"tab_all" => isRu ? "ВСЕ РЕЖИМЫ" : "ALL MODES",
"tab_pvp" => isRu ? "PVP АРЕНЫ" : "PVP ARENAS",
"tab_pve" => isRu ? "ВЫЖИВАНИЕ" : "SURVIVAL",
"tab_sandbox" => isRu ? "ПОЛИГОН" : "SANDBOX",
// Sumo
"sumo_title" => "SUMO PUSH",
"sumo_tag" => isRu ? "ГЛАВНЫЙ" : "FEATURED",
"sumo_desc" => isRu ? "Битва на выживание! Толкай врагов и ботов с сужающейся арены, пока она не упала в лаву." : "Survival brawl! Push enemies and bots off the shrinking platform before falling into lava.",
// Nextbot
"nextbot_title" => "NEXTBOT RUN",
"nextbot_tag" => isRu ? "ХОРРОР" : "SURVIVAL",
"nextbot_desc" => isRu ? "Убегай от безумных некстботов! Спасай поверженных союзников и выживай." : "Flee from ruthless nextbots! Rescue downed teammates and survive.",
// Construct
"construct_title" => "CONSTRUCT S2",
"construct_tag" => isRu ? "СЕЗОН 2" : "SEASON 2",
"construct_desc" => isRu ? "Легендарная карта Construct с физикой, паркуром и свободным боем. Новые возможности!" : "Legendary Construct map with full physics, parkour and open brawl. New season!",
// Nextbot Flat
"nextbot_flat_title" => "NEXTBOT FLAT",
"nextbot_flat_tag" => isRu ? "ХАОС" : "CHAOS",
"nextbot_flat_desc" => isRu ? "Открытое поле Flatgrass с толпой свирепых некстботов. Для любителей максимальной скорости!" : "Open Flatgrass arena swarmed by nextbots. For players who love pure adrenaline!",
// Top-Down
"topdown_title" => "TOP-DOWN PUSH",
"topdown_tag" => isRu ? "АРКАДА" : "ARCADE",
"topdown_desc" => isRu ? "Аркадная битва с видом сверху! Новая динамика контроля, обзор всей арены и быстрые стычки." : "Arcade top-down perspective! Fresh tactical feel, full arena view and fast-paced clashes.",
// Sandbox
"sandbox_title" => "SANDBOX ARENA",
"sandbox_tag" => isRu ? "ПОЛИГОН" : "TRAINING",
"sandbox_desc" => isRu ? "Тренировочная песочница: разминайся, проверяй способности, физику и оружие без ограничений." : "Training sandbox: warm up, test abilities, physics and weapons without round pressure.",
// Duel
"duel_title" => "DUEL ARENA",
"duel_tag" => isRu ? "ДУЭЛЬ 1V1" : "1V1 DUEL",
"duel_desc" => isRu ? "Компактная арена для напряжённых дуэлей один на один с обратным отсчетом и быстрым рестартом." : "Compact arena for intense 1v1 showdowns with dynamic countdown and fast restarts.",
// UI Actions
"quick_play" => isRu ? "В БОЙ!" : "QUICK PLAY",
"play_btn" => isRu ? "ИГРАТЬ" : "PLAY",
"launch_btn" => isRu ? "СТАРТ" : "LAUNCH",
"lang_btn" => isRu ? "RU" : "EN",
"settings_btn" => isRu ? "НАСТРОЙКИ" : "SETTINGS",
"exit_btn" => isRu ? "ВЫХОД" : "EXIT",
"settings_title" => isRu ? "НАСТРОЙКИ ИГРЫ" : "GAME SETTINGS",
"volume_label" => isRu ? "Общая громкость" : "Master Volume",
"controls_title" => isRu ? "Управление" : "Keybindings",
"ctrl_move" => isRu ? "WASD — Перемещение" : "WASD — Movement",
"ctrl_action" => isRu ? "ЛКМ / E — Толкнуть / Действие" : "LMB / E — Push / Interact",
"ctrl_space" => isRu ? "Пробел — Прыжок" : "Space — Jump",
"ctrl_shift" => isRu ? "Shift — Спринт" : "Shift — Sprint",
"ctrl_rmb" => isRu ? "ПКМ — Специальная способность" : "RMB — Special Ability",
"close_btn" => isRu ? "ЗАКРЫТЬ" : "CLOSE",
"skip_btn" => isRu ? "ПРОПУСТИТЬ >>" : "SKIP >>",
// News Panel
"news_title" => isRu ? "СОБЫТИЯ И РЕЖИМЫ" : "EVENTS & MODES",
"news_tag_live" => isRu ? "ОНЛАЙН" : "LIVE",
"news_item1_title" => isRu ? "Режим Nextbot Run готов!" : "Nextbot Run is Live!",
"news_item1_desc" => isRu ? "Беги, спасай друзей и уворачивайся от некстботов в ночных доках." : "Flee, rescue allies and evade nextbots in the dark docks.",
"news_item2_title" => isRu ? "Сезон 2: Construct Арена" : "Season 2: Construct Arena",
"news_item2_desc" => isRu ? "Новая масштабная карта с физическими объектами и паркуром." : "New expansive map featuring interactive physics and parkour.",
"news_item3_title" => isRu ? "Классический Sumo Push" : "Classic Sumo Push Arena",
"news_item3_desc" => isRu ? "Главная соревновательная арена с аномалиями и разрушением." : "Main competitive arena with hazards and shrinking tiles.",
"news_item4_title" => isRu ? "Аркадный вид сверху" : "Top-Down Arcade Mode",
"news_item4_desc" => isRu ? "Оцени физические битвы с высоты птичьего полёта." : "Experience physics battles from a top-down camera view.",
// Loading
"loading_title" => isRu ? "ЗАГРУЗКА ЛОКАЦИИ..." : "LOADING ARENA...",
"loading_sub" => isRu ? "Инициализация физического мира и спавн сущностей..." : "Initializing physics world and spawning entities...",
"tip_label" => isRu ? "СОВЕТ:" : "TIP:",
"tip_sumo" => isRu ? "Следи за мигающими плитками платформы — они обрушатся в первую очередь!" : "Watch for flashing arena tiles — they will collapse first!",
"tip_nextbot" => isRu ? "Держись на расстоянии и используй углы зданий, чтобы сбить преследователя со следа!" : "Keep distance and use building corners to shake off pursuers!",
"tip_construct" => isRu ? "Используй высоту зданий и краны для тактического преимущества над противником!" : "Use building heights and cranes to gain high ground advantage!",
"tip_flat" => isRu ? "Постоянно двигайся! На открытом поле некстботы видят тебя отовсюду." : "Keep moving! On flat terrain, nextbots have clear line of sight.",
"tip_topdown" => isRu ? "Смотри по сторонам — вид сверху даёт полный обзор тыла и ловушек!" : "Keep an eye all around — top-down view gives full coverage of flanks!",
"tip_sandbox" => isRu ? "Здесь можно протестировать любые способности и силу толчка в спокойствии." : "A stress-free ground to test all push forces and abilities.",
"tip_duel" => isRu ? "Арена небольшая: нападай первым и не давай сопернику занять центр!" : "Small arena: take the initiative and claim center stage!",
_ => key
};
}
}