# SOTS1 — UI Screen Map & High-Level Flow **Build analysed:** `sots.gob` / `sots_local_en.gob` dated 2010-04 (Complete Collection + Argos Naval Yard data set) driven by `Sword of the Stars.exe` 1.8.1 (GOG 2017 rebuild). So this is the *final* SOTS1 UI surface, not the 2006 launch one — cut/legacy remnants are called out in §5. **Method (Ghidra-free):** the brief assumed a tree of per-screen `GUI/**/*.script` layouts. **That tree does not exist.** The whole archive holds exactly four `.script` files (`GUI/BorderSprites.script`, `GUI/StarMap/Lines.script`, `TechTree/TechTreeDisplay.script`, `Models/Planets/PlanetResources.script`), none of which is a widget layout — SOTS1 screens are **built in C++ on the `Mars` control framework**. The map below is therefore reconstructed from five independent evidence layers that all agree with each other: | Layer | Source | Size | |---|---|---| | Texture folders | `GUI/**` in `list_sots.gob.txt` | 396 files in 19 folders, named per screen | | Sprite table | `GUI/SpriteTable.csv` | ~1,950 sprites; names are `__` | | String tokens | `Locale/EN/Strings.csv` | 5,200 rows in ~200 prefixes; prefix = screen/dialog | | UI sound hooks | `Sounds/sound_ui.csv` | 50 events, several screen-specific | | Class names | `classes-game.txt` (1,404) / `classes-mars.txt` (194) | ~300 `*Panel/*Dialog/*Screen/*View/*List` types | | Layout constants | `Data/globals.txt`, `Data/tutorial.txt` | panel widths/colours, tutorial page list | `Manual.pdf` (87 pp, in `sots-game/`) was used only as a cross-check of the flow; its TOC matches the screen list below 1:1. --- ## 1. The UI framework (`Mars`) Engine side (`classes-mars.txt`): - **Containers:** `Control` → `Panel`, `Dialog` (+`DialogUnderlay`), `DockablePanel`, `ClipPanel`, `ListPanel`, `ScrollPanel`(Game), `PanelManager`/`IPanelManager`, `Frame`/`ModelFrame`. - **Widgets:** `Button`, `TextButton`, `IconButton`, `IconToggleButton`, `LCRButton` (left/centre/right 3-slice), `MicroButton`, `ToggleMicroButton`, `CheckBox`/`CheckBoxBase`/`CheckBoxList`, `DropDownList` (+`ListUnderlay`), `EditView`/`IEditView`, `ListBox`, `ListView`/`IListView`, `ListFramework` (+`Item`, `ClipPanel`), `ListColumn`, `TextListBase`, `Scrollbar`, `GradientSlider`, `TextView`/`TextViewBase`/`BulkTextPanel`, `Picture`, `Menu`/`IMenu`, `Movie` (Bink), `ProgressPainter`, `Font`/`ScalingFont`/`FontDictionary`, `GUIResources`. - **Drag & drop:** `IDropSource` / `IDropData` / `IDropTarget` — used by the fleet manager, build queue, defence manager, combat reserves and lobby slots (`UI_DRAG_START/STOP` sound). - **Sprites:** `Sprite`, `SpriteTable` (+`SpriteTableRowParser`). The table header documents the **9-slice convention**: `CORNER` (flipped), `VEDGE`/`HEDGE` (stretched), `CENTER`. Generic skins: `MARS_BUTTON_*`, `MARS_LCRBUTTON_*`, `MARS_SCROLLBAR_*`, `MARS_LIST_*`, `MARS_SLIDER`, `MARS_CHECKBOX`, `MARS_ARROW_BUTTON`, `MARS_FUZZY_BORDER` — all cut from `GUI/StarMapElements.tga` / `StarMapBorders.tga` / `Arrows.tga` / `fuzzyedge.tga`. - **Sound:** `UISoundCSVRowParser` reads `sound_ui.csv` (button click/rollover, list open/close, tree expand, dialog query/ok/cancel, exit-screen, etc.). - **Scripts:** `Script`/`IScriptable` parse the brace-block format; `Mars::Sprite` reads `BorderSprites.script` (the blue main-menu dialog border, 11 sprites from `GUI\MainMenu\MenuBorder.tga`). Game-side generic UI (`classes-game.txt`): `Screen`, `ScreenBar` (+`ToggleList`), `TitleBar`, `PropSheet`/`PropPage`, `MessageBoxA`, `EditMessageBox`, `PlayerMessageBox`/`PlayerMessage`, `PieChartPanel`, `StatsGraphPanel`, `MoviePanel`, `ImageCheckBox`/`PlayerImageCheckBox`, `StackedSliderEditCombo`, `HealthIconPanel` (`Crosses.tga`/`xpoints.tga` danger/warning/good), `Rotator`, `MutexScreen`, `AutoJoin`/`AutoJoinBackground`. Layout constants live in `Data/globals.txt` (`PANEL_SEPARATION 5`, `STATUSPANEL_MIN_WIDTH 480`, `BUDGETBAR_WIDTH 150`, `DESIGN_SIDEBAR_WIDTH 200`, `DESIGN_DESIGNLIST_WIDTH 180`, `EVENTSTICKER_OVERLAP 10`, popup/main-menu colours, all `COMBATHUD_*` model/marker settings) — i.e. what little is data-driven is *tuning*, not layout. --- ## 2. Screen catalog Format: **Screen** — evidence (textures / sprites / tokens) → key labels → `Game::` classes → underlying subsystem. ### 2.1 Front end | # | Screen | Evidence | Key labels | `Game::` UI classes | Subsystem | |---|---|---|---|---|---| | F1 | **Splash / intro** | `GUI/SplashArt/Frontend/Title/{gamespy_splash_A,kerberos_splash_B}.tga`; `UI_KERBEROS_SPLASH` (gui_growl.wav); `Movies/sotsintro.bik` | — | `IntroView`, `IntroViewCameraCtl`, `IntroCameraInfo`, `MainMoviePanel`, `IntroOverlay::MainMenuPanel` | `Mars::AppStartup`, `Mars::Movie` | | F2 | **Main menu** (3-D nebula backdrop) | `GUI/MainMenu/{Title,IntroA-C,NebulaA-F}.tga`, `FrontEnd_Buttons.tga` (`MAINMENU_BUTTON`), `MenuBorder.tga` (`MAINMENU_DIALOGBG`), `BorderSprites.script`; `MAINMENU_BTN_*` | Profiles · Single Player · Host Multi-Player · Join Multi-Player · Load Game · Tutorial · Options · Credits · Cinematics · Exit; MOTD | `MainMenuPanel`, `MainMenuMOTD` (+`ClipPanel`), `MOTD` | MOTD fetched from `www.kerberos-productions.com/motd` | | F3 | **Profile manager** | `PROFILEMAN_*`; `GUI/Achievements/*.tga` (56 badges); `Badges/`, `Avatars/` sprite sets | Create/Delete/Switch profile; Species / Played / Won / Lost; Badges Unlocked; "Highest Progression Wars Stage" | `ProfileManagerPanel`, `ProfileInfoPanel`, `CreateProfileDialog`, `DeleteProfileDialog`, `SwitchProfileDialog`, `PlayerAvatarSet`, `PlayerBadgeSet`, `PlayerColorSet` | `Profiles/Profile_*.ini`, `lastprofile.dat` (from string-intel) | | F4 | **Options** | `OPTIONS_*` (38), `FILTER_*`, `HOTKEYS_*` (20), `KEYID_*` (113), `KEYMOD_*`; `Data/options.txt` (volume test sounds) | Audio (master/SFX/speech/GUI/music, channels, freq, bitrate, hardware) · Display (adapter, resolution, fullscreen, object/shader/texture detail, filtering, stars, brightness, particle distance) · Input / Key Bindings (tabs General/Strategy/Combat) | `OptionsPanel`, `AudioOptionsPanel`, `DisplayOptionsPanel` (+`InGameCheck`), `HotKeysPanel`, `HotKeysPropSheet`, `HotKeysPage`, `HotKeyList` | ini keys `adapter,width,height,fullscreen,antialiasing,brightness,MusicVolume…`; **key bindings are read-only in UI** ("can be changed in the profile ini file") | | F5 | **Credits** | `GUI/Credits/{bink,gamespy}.tga`; `Data/credits.txt` (in *local* gob) | — | `CreditsPanel` | — | | F6 | **Tutorial** | `Data/tutorial.txt` (page 0 = 7 videos `Movies/Tutorial/01-setup…07-combat.bik`; pages 1–14 text+image); `GUI/Tutorial/page*.tga` (pages 9–11 live in `sots_local_en.gob`); `TUTORIAL_*` | Tutorial · Combat · Strategy Screen · Research · Design · Build · Moving · Node Travel · Hiver Gates · Fleet Information · Planet Info · Colonizing · Special Functions · Final Notes | `TutorialPanel` (+`VideoButtonPanel`) | also a playable scenario `Scenarios/Tutorial/Tutorial.txt` ("Basic Tutorial") | | F7 | **Cinematics** | `MAINMENU_BTN_MOVIES`; `Movies/{amocintro,antiquarians,bobintro,lhintro,sotsintro}.bik` | Cinematics | `MoviePanel` | Bink (`binkw32.dll`) | | F8 | **Game-mode chooser** | `GUI/MainMenu/ChooseGameButtons.tga` (`GAMESETUPOPTIONS_ICON_{CUSTOM,SCENARIO,SINGLEPLAYER,INTERNET,LAN,BG}`); `GAMESETUPFE_*` | Custom / Scenario × Single Player / LAN / Internet; titles "Play Single Player", "Host Multiplayer", "Join Multiplayer", "Load Game" | `GameSetupOptions`, `GameSetupOptions_CheckBox` | — | | F9 | **Game setup (custom)** | `GUI/GameSetup/GameSetupElements.tga` (icons AI/Player/Options/Timer/Money; **30 star-map shape icons**; 6 species); `GAMESETUP_*` (59), `MAPSHAPE_*` (25); `Maps/*.csv` custom maps; `UI_GAMESETUP_ROLLOVER/CONFIRM` | Star Map Setup (shape, Star Density, Number of Stars, Distance ly, Size, Resources, Suitability) · Available Species · Economic/Research Efficiency · AI Easy/Normal/Difficult · Initial Treasury/Colonies/Technologies · Options: Alliances, Random Encounters %, Lobby/Player Passwords, Teams (+Grouped), Win Ratio · Time: Strategic Turn Length, Combat Turn Length, Combat Query Time Limit (+per-additional-round) · Create Game / Cancel Game | `GameSetupPanel`, `CustomSetupPanel`, `CustomSetup_Maps`, `GameSetup_AI/LSE/MapSelect(+Impl)/MapView(+IconOverlay)/Money/Name/Option/Options/Player/Species/Time`, `CustomMapRowParser`; legacy `OldGameSetupPanel` | `StrategyGameCreateParams`, `StrategyGameParams`, `StrategyTimerParams`, `StarMapParams`, `Data/Strategy/starmap.txt`, `RealSpace.csv` | | F10 | **Scenario setup** | `GUI/GameSetup/Scenario_Set_A…H.tga` (16 scenario images; `Set_C` is in the local gob); `SCENARIO_*` (149) | Description / Rules / Objectives pages; 14 scenarios: Jewels of the Crown, Hungry Children (HiverInvasion), Upstart Apes (key `EARTHVSTARKAS`), Holy Lands, A New Hope (CivilWar), His Master's Voice, Lords of a Broken Empire, The End of Flesh, Basic Tutorial, Tourney Space, Progression Wars, The Gathering, Land Grab (S/M/L), Antiquarians | `ScenarioSetupPanel`, `ScenarioSetup_Maps`, `GameSetup_ScenarioPages/ScenarioScene/ScenarioSelect`, `ScenarioPageBase`, `ScenarioDescPage`, `ScenarioObjPage`, `ScenarioRulesPage`, `ObjectivesPanel` | `SVScriptObject` → 33 `SVSO*` classes (one per scenario/encounter script) + `Scenarios/*.txt/.csv`, `StrategyScriptParams` | | F11 | **Load game** | `GAMESETUP_LOAD_*`, `GAMELIST_*`, `GAMECARD_*`, `GAMEINFO_*` (12); `SOTS_GAME_{AUTOSAVE,AUTOSAVEBACKUP,REJOINSAVE,ENDTURN_AUTOSAVE,ENDTURN_AUTOSAVEBACKUP}` | Select saved game; card shows Galaxy Type, Stars, Players, Turn, Version, Economy, Research, Turn/Combat Time, Alliances, Encounters, Teams; Delete | `StrategyGameList` (+`Item`), `GameInfoPanel`, `CustomDataTable::StrategyGameLoader` | `StrategyGameLoadParams`, `.sav` | | F12 | **Game browser** (Join MP) | `GAMEBROWSER_*`, `SERVERPAGE_*`, `FILTERDLG_*`, `MANUALJOIN_*`, `CHAT_*`, `CHATCHANNEL_*`, `MATCHINGSERVICE_*`, `NETERROR_*` (21 incl. 6 CD-key), `AUTOJOINERR_*`; `GUI/CrossFireLoad.tga` (`AUTOJOIN`) | Pages LAN / Internet / Internet Chat; server list (Game Name, Players, Ping, Password, Status, Version); Edit/Apply Filter; Join Manually (Favorites); Refresh; Join; `/join addr[:port]` command | `GameBrowserScreen`, `GameBrowserPanel` + nested `LANPage`, `InternetPage`, `ChatPage`, `ServerPage`, `ServerList`, `GameDisplay`, `GamePlayers`, `GBMOTD`, `FilterDialog`, `ManualJoinDialog`, `EnterPasswordDialog`; `AutoJoin`, `AutoJoinBackground`; `ChatMonitor`, `ChatHistoryView` | GameSpy master/chat (IRC-style), NatNeg; `StrategyJoin` (+`ProgressDialog`) | | F13 | **Lobby** (host & join; also the MP *between-turns* room) | `GUI/Lobby/{LobbyBG,LobbyElementsA-C}.tga` (`SLOTPANEL_*`, `SLOT_BUTTON_{PASSWORD,KICK,OPEN,CUSTOMAI,AI}`, `SLOTUSER_{AI,DEAD}`, `SLOTSPECIES_*`, `LOBBY_COLOR_*`, `AVATAR_RANDOM`, `BADGE_RANDOM`); `LOBBY_*` (45), `LOBBYSTATUS_*`, `PLAYERSETUP_*` (17), `HOSTMIG*` (24), `TIMERSDLG_*`, `AIPOLICY_*`, `SYSTEMMSG_*` | Launch / Leave Game / Cancel Game / Ready; slots Open/Closed/AI/password/kick/lock; Player Setup (Name, Species, Color, Badge, Avatar, Team, Settings); Game Status (Strategic round… / Resolving combat… / Querying for combat…, "%s of %s players still playing", "%s battles in progress"); in-progress join ("will enter the game when the next turn begins"); Downloading game data; host migration | `StrategyLobbyScreen` (+`EnterPasswordDialog`, `MOTDDialog`, `PasswordStatus`, `SpeciesInfoPanel`, `TurnInfoPanel`), `SlotPanel`, `LobbySlotPanel`, `SlotDetailsPanel`, `PlayerSetupPanel`, `SpeciesSelectDialog`, `SpeciesDescPanel`, `LobbyChat`, `ChatDialog`, `AIPolicyDialog/Panel`, `SetTimersDialog`, `ServerMigrationStatusPanel` (+`ConfirmAbortDialog`), `ClientMigrationStatusPanel`, `StrategyHost` (+`ProgressDialog`, `ContinueDialog`, `SHMOTD`) | `SNMSlot*` (14 msgs), `SNMJoin*`, `SNMLobbyChat`, `SNMSetTimers`, `SNMSetAIPolicy`, `SNMMakePlayerAI`; `FNM*` chunked file transfer for migration/rejoin; `StrategySessionParams`, `StrategyHostParams` | ### 2.2 Strategy layer (the turn screen and its children) | # | Screen | Evidence | Key labels | `Game::` UI classes | Subsystem | |---|---|---|---|---|---| | S1 | **Strategy map screen** (root of the turn) | `GUI/StarMapElements.tga` (136 sprites), `StarMapBorders.tga` (82), `GUI/StarMap/*` (lines, gate/move icons, `MapFade`, `PlayerColorBand`, `StatusBox`), `StarMap/Lines.script` (MoveLine green/red range segments, NodeLine, DistanceLine, FleetLine with per-drive arrow textures STL/Warp/Stutter/Node/Teleport/Farcast/Flock, GateLine, TradeLine); `Star.tga`, `disc.tga`, `ring.tga`, `piegradient.tga`; `UICSTR_*` strategic hotkeys | camera orbit/zoom; Home System; Focus/Zoom; Select Next/Prev Colony / Idle Fleet / Trade Sector | `StrategyMapScreen` (+`DebugOverlay`), `StarMapPanel`, `StarMapCameraPanel`, `StarMapEdgePanel`, `MiniStarMapPanel`, `StarMapNode`, `StarMapLine`, `StarMapNodeLine`, `StarMapLinePainter`, `NodeLinePainter`, `NodeLineDesc`, `FleetLine`, `GateLine`, `TradeLine`, `TradeLinePainter`, `TradePainter`, `TradeSectorPainter`, `StrategyClient`/`StrategyClientData` | `StarSystem`, `ClientNodeGraph`/`ServerNodeGraph`, `NodePath`/`NodeRoute`/`SimpleNodePath`, `StrategySim` | | S1a | **Screen chrome** (bottom bar, status panel, empire bar, ticker) | sprites `SCREENBAR_*`, `SCREENBAR_EXIT`, `ENDTURN_*` (LCR button), `EXITSCREEN`, `TICKER_*`, `EMPIRE_OPENBTN` (`BudgetButton.tga`), `EMPIREBUDGET_*` / `EMPIRE_SLIDER_*`; `GUI/Bar_Buttons.tga` (`BARBUTTON_{POLMAP,TRADE,RESEARCH,DESIGN,BUILD,DIPLOMACY,INTEL,RANKINGS,EVENTS,TECHTREE,POPULATIONS,OLDTRADE,OLDALLIANCE}`), `ticker_buttons{,2,3}.tga` (`BARBUTTON_{CHAT,INFO,FLEETLINES,STARS,OBJECTIVES,SENSORNET,SURRENDER,TOGGLE,ENEMYNODES}`); `STRATEGY_END_TURN`, `STATUS_*`, `PLAYERSTATUS_*`, `TOOLTIP_BARBUTTON_*` (14), `COMMON_BUDGETBAR_LEFT/RIGHT` | End Turn / Game Over / Eliminated; Exit; savings↔research slider; status list NAME / STATUS / ROUNDS / TIME REMAINING with per-player status (Playing, Done, Querying, Staging, Fighting, Eliminated, AI) and alliance indicators; buttons Ranks / Diplomacy / Intel Analysis / Empire Civilian Settings; toggles Chat, Star Brightness, Fleet Lines, Objectives, Political Map, Trade View, Sensor Network, Enemy Node Paths, Galactic Axes, Options | `ScreenBar` (+`ToggleList`), `StatusPanel` (+`PlayersPanel`), `EmpireBar`, `EventsTickerPanel`, `ObjectivesPanel`, `ObjectiveListView(Item)`, `PlayerIconList` (+`Clipper`), `ChatControl`, `ChatEditControl`, `ChatInputControl`, `ChatHistoryPanel`/`ChatHistoryPanel2`, `ChatMessageListPanel`, `PlayerNotePanel`/`PlayerNoteButton` (`StickyNoteElements.tga`, `NOTEPAD_*`), `QuitStrategyGameDialog` (`STRATDLG_*`), `SaveGameDialog`/`SaveGameMessageBox` (`SAVEGAMEDLG_*`), `SurrenderDialog` (+`PlayersOverlay`, `ConfirmDialog`) | `TurnCommands`, `StrategyTurnInfo`, `SNMEndTurn`, `SNMTurnInfo`, `SETurnEnd*`; `PlayerNotes` | | S2 | **System / planet panel** (selected star) | `GUI/SystemPanels.tga` (`SYSINFO_*`, `POPMAN_*_ICON`), `StarMap/SystemUI/*` (`SatRing`, `HomeSystem`, `Unexplored`, `SystemCaps`, asteroid ring, `PC_Insert`), `SYSINFO_*` (18), `SYSSUM_*` (24), `STATIONSUM_*`, `STATIONTYPE_*` (Command/Science/Repair/Sensors/Trade/Habitat); `ClimateHazard`/`Overharvest`/`SystemBudget` slider skins | Name, Owner, Size, Resources, Climate Hazard, Population (Imperial/Civilian/Slaves), Infrastructure, Industrial Output, Income, Gates, Defenses; **five sliders**: Overharvest, Construction↔Trade, Terraforming, Infrastructure, Ship Construction; buttons Research / Design / Build, Abandon, Manage Civilians / Slaves / Defenses, View Enemy Defenses, Notes; "Stations at %s" Activated/Deactivated/Under Construction | `SystemViewPanel`, `SystemSummaryPanel` (+`Overlay`), `SystemSummaryList`, `StrategySystemInfo`, `SystemRateSliders`, `SystemTradeSlider`, `ClimateControl`, `ClimateHazardBar/Slider`, `PopulationSlider`, `SpeciesSlider` (+`Overlay`), `StationSummaryPanel/Popup`, `StationDetailsPanel`, `StationIcons`, `SensorInfoPanel`, `ConfirmAbandonColonyDialog` | `StarSystem`, `Planet`, `ServerSystem`/`ClientSystem`, `SystemParams`, `Station`, `Population`, `SystemBuildQueue` | | S3 | **Fleet panel** (fleets at selected system / sector / deep space) | `StarMap/FleetUI/RoundButton.tga`, `system_tab_fleet_icons.tga` + `UserHUDElements.tga` (`FLEETCARD_ICON_*` per race + Refugees/Artifact), `ACTION_ICON_*` (16 small + 16 large from `SystemUI/*.tga`), `GUI/RefuelElements.tga` (`SUPPORT_*`); `FLEETINFO_*` (15), `FLEETFILTER_*` (19), `FLEETSORT_*`, `FLEETDETAILS_*`, `FLEETMENUITEM_*`, `SHIPACTION_*` (15), `ACTIONDLG_*` (30), `MOVEWARNING_*` (17), `MISC_FLIGHTPLAN_*`, `SUPPORT_*`/`REFUEL_`/`REPAIR_`; `UI_AUTO_REFUEL/REPAIR` | "Fleets at %s / in %s / nearby"; Manage Fleets · Move · Special (Colonize, Deploy Gate, Mine, Refine, Dump Ore, Refuel, Repair, Stop, Scuttle, Build, Build/Deploy/Extract Spy, Colony/Mining Trap, Dismantle Trap, Transfer Slaves, Flag as Guard/Raider); Add To New Fleet / Split Ships / Add Note; filters (In Transit, Recent Combat, With Colonizers/Refineries/Miners/Repair/Tankers/Gate/CnC/NodeBore/Freighters/Slave/Police/Construction/Flagships/Deep Scans); move warnings (node range, gate capacity, node-bore path limits, trade-sector node rules) | `StrategyFleetInfo` (+`FleetMenuSource`, `FleetListDropTarget`), `FleetList` (+`Column`, `IconColumn`, `TextColumn`, `NoteColumn`, `Item`), `FleetListHeader`, `FleetShipList` (+`FleetsClipPanel`, `ShipsClipPanel`), `FleetSummaryPanel`, `PlayerFleetsPanel`, `MoveDestinationMenu`, `ConfirmMoveFleetDialog`, `ShipCmdDialog`, action dialogs `ColonizeDialog`, `GateDialog`, `RefineDialog`, `MineDialog`, `DumpOreDialog`, `DumpSlavesDialog`, `ScuttleDialog`, `StopDialog`, `BuildSpyDialog`, `DeploySpyDialog`, `PickupSpyDialog`, `SetColonyTrapDialog`, `SetMiningTrapDialog`, `ClearTrapDialog`; `SupportPanel`, `RefuelPanel`, `RepairPanel`, `SupportControl/Slider`, `RefuelAvailCell`, `RepairAvailCell`, `SupportAvailCell` | `StarFleet`, `StarShip`, `FlightPlan` (+`Waypoint`), `Can*` predicate functors (`CanColonize`… `CanSetTrapFtor`), `SpyCraft`, `ClientSpyManager` | | S4 | **Fleet manager** | `GUI/FleetManager/*` (per-race `*_Destroyer.tga`, `*_ShipIcons.tga`, `StationsDrones_ShipIcons.tga`, `Defence_Sat.tga`), sprites `FLEETMAN_*`, `FLEETLIST_*`; `FLEETMAN_*` (8), `RESERVESSORT_*`, `SHIPSET_*`, `PLAYERFLEETS_*`, `TOOLTIP_FLEETLISTBTN_EDITLAYOUT` | Manage Fleets; First Wave / Reinforcements / Squads; Command Cost / Command Quota; Rename Fleet; "Fleet Layout Not Available"; Edit Layout | `FleetManagerPanel` (+`ButtonOverlay`, `DialogUnderlay`, `RenameFleetDialog`, `FleetMenuSource`), `FleetLayoutPanel`, `FleetLayoutGrid`, `ReservesList`, `ReserveQueueBox`, `ShipList` (+`ShipItem`), `ShipSetPanel` (+`BucketList`), `ShipAssignmentPanel`, drop plumbing `FleetManager_{FleetList,Layout,Reserves}DropTarget`, `ShipDropSource/Data`, `ReservesDropSource/Data/Target` | `FleetLayout`, `Reserves`, `FleetNameGenerator` | | S5 | **Defense manager** | `DEFMAN_ARROW` (`Arrows.tga`), `SYSINFO_ICON_DEFSATS*`; `DEFENCEMAN_*`, `DEFMAN_*`, `UICSTR_OPEN_DEFENCEMAN` | Manage Defences; Command Quota/Cost; "Show Neighbors (by distance)"; right-drag to rotate fleet; Remove Fleet | `DefenceManager` (+`MapDropTarget`), `DefenceMap`, `DefenceLayout`, `DefenceFleetAssignment`, `DefenceFleetRotator`, `DefenceSummary`, `DefenceObject`, `DOFleet/DOPlanet/DOStation/DODefSat`, `DefenceDropSource/Data` | `DefencePlatform`, `DefenceManager` (sim side) | | S6 | **Population manager / Empire population / Slave manager** | `POPMAN_*` (21), `GLOBALPOPMAN_*`, `SLAVEMAN_*`, `CONFIRM_*_CIVRATIOS_*`; `POPMAN_TITLE_ICON`, `GLOBALPOPMAN_TITLE_ICON` | Current/Maximum (Combined) Population, Combined Civilian Population, Climate Control, Morale, Morale Events; Empire: Maximum Civilians Per System, Apply Empire Settings; Slave Manager: Output, Death Rate | `PopulationManager`, `PopulationControl`, `PopulationGroup`, `PopulationSummary` (+`Overlay`), `MoraleEventsPanel`, `MoraleEventList`, `GlobalCiviliansControl`, `GlobalPopulationManager`, `CivilianRatios`, `SpeciesRatios`, `ConfirmCivilianRatiosDialog`, `ConfirmApplyCivilianRatiosDialog`, `SlaveManagerPanel` (+`SpeciesControls`) | `Population`, `Morale`/`MoraleEvent` (`MESTR_*` 38 morale strings), `PrisonerHold`, `Plague`/`ZuulInfestation` | | S7 | **Build screen** | `BUILD_*` (21), `SHIPBUILD_*`, `BUILDERROR_*` (22), `TOOLTIP_BUILDPANEL_REMOVE_ORDER`; sprites `BUILD_ORDERINC/DEC`; globals `DESIGN_SIDEBAR_WIDTH` ("build/design screens") | Build; Available Designs; Add To Queue; Build Queue; Financial Details (Treasury, Fleet Maintenance current/queued/total); Ship Details (structure, turrets, speed, range, costs, "%s in service / built / destroyed"); construction-ship build ("Construction Ships:") | `BuildPanel` (+`MiniBudgetPanel`, `MiniEmpirePanel`, `PreviewPanel`), `BuildQueuePanel`, `BuildOrderListPanel` (+`Item`), `BuildOrderDropSource/Data/Target`, `ShipBuildPanel`/`IShipBuildPanel`, `BuilderList`, `DesignList` (+`PerClassList`), `ShipPreviewPanel`, `ShipStatsPanel` | `BuildQueue`, `ShipBuildQueue`, `ShipBuildOrder`, `SystemBuildQueue`, `CanBuild`, `SEBuildCompleted/Cancelled` | | S8 | **Design screen** | `GUI/WeaponIcons{,_2}.tga` + `WeaponIconPlacements.txt` (362 KB icon atlas map), `WeaponIconOutline.tga`, `WeaponTitle.tga` (`WEAPONLIST_TAB_*`), `SHIPDESIGN_GROUP_BUTTON0-2`; `DESIGN_*`, `DESIGNERR_*`, `DESIGNCLASS_*` (Destroyer/Cruiser/Dreadnought/Station/Rider), `SHIPSTATS_*` (16), `WEAPONLIST_*`, `SECTIONNAME_*` (283) / `SECTIONDESC_*` (202); `UI_DESIGN_SECTION_CHANGED/WEAPON_ROLLOVER/WEAPON_SELECTED` | Ship Designs; section picker (command/mission/engine); Weapon Layout / Weapon Groups; Ship Stats (Savings/Construction cost, Armor, Mass, Range, Speed, Tactical/Turning Speed, turrets S/M/L/Special); Save Design / Remove Design; errors "Mismatched Sections", "AI Control Sections Disabled Due To AI Rebellion" | `ShipDesignPanel`, `SectionConfigPanel`, `SectionOverlay` (+`OptionIcon`), `WeaponPanel`, `WeaponPanel2`, `WeaponListPanel`, `WeaponSelectPanel_List/Tab`, `WeaponIconButton`, `WeaponGroups`, `WeaponGroupControls`, `WeaponControls`, `DesignInfoPanel/Popup`, `DesignPreviewPanel`, `DesignErrorPanel`, `TurretStatsPanel`, `SaveDesignDialog`, `RaidDesignPanel`, `ShipDesignCell` | `ShipDesignDef` (+`LegacyGunBank`), `ShipDesign`, `DesignList`, `ShipIconGenerator`, `SEAddDesign/SESyncDesign` | | S9 | **Research screen** (3-D tech tree) | `TechTree/TechTreeDisplay.script` (12 branch models `TechTree_{BAL,BIO,CCC,DRV,EWP,IND,NRG,SLD,TRP,WHD,DRN,XNC}.X`, `Rings.X` background, state colours researched/researchable/researching/hidden), `GUI/ResearchElements.tga` (`TECHINFO_*`, `RESEARCH_*`), `TechTree/ShipArt/*` (`TECHSHIP_*` section icons); `RESEARCH_*` (21), `TECHNAME_*`/`TECHDESC_*` (293 each), `TECHBEN_*`, `TECHERA_*`, `SPRJ_*` (106, 103 of them `SPRJ_BACKENG_*`), `SPECPROJECT_*`, `SPINNERPANEL_*`; `UI_RES_SELECTION/ZOOMIN_ACROSS/ZOOMOUT/COMPLETE/BOOST/SHORT_AMBIENT` | Research; Researching … "%s turns to complete"; Research/Cancel; Boost Research (savings slider, Apply); Special Projects (Start/Cancel Project); History ("Turn %s"); Completed! dialog; Overbudget | `ResearchPanel` (+`DoubleClickPanel`, `TitlePanel`, `BudgetPanel::ResearchPanel`), `TechTreePanel`, `TechInfoPanel`, `TechNamePanel`, `TechDescPanel`, `TechBenefitPanel`, `ResearchListPanel`, `ResearchProjectPanel`, `ResearchHistoryPanel/List`, `ResearchSpecialPanel/Controls`, `ResearchBoostControls`, `ResearchSpinnerPanel`, `ResearchDonePanel`, `TechOptionsList` (+`Item`) | `TechTree`, `TechProject`, `SpecialProject(Impl)`, `BackEngProject`, `MonitorProject`, `JewelsProject`, `TechOfferProject`, `ObservedTech`, `MasterTechList.tech` | | S10 | **Empire summary** (tabbed) | `EMPIRE_TABTITLE_*`, `BUDGET_*` (19), `EMPIREINFO_*`, `STATSGRAPH_*`/`STATSPAGE_*` (`GUI/Graph_buttons.tga` 9 graph types), `EMPIRE_PAGEBTN`, `EMPIRE_ENEMYINCOMING`; `UI_TAB_SELECTED` (gui_overview) | tabs Colonies/Budget · Fleets · Explored Systems · Enemy Colonies · History · Stats · Trade · Spies; Budget: Treasury, Income (Planetary, Trade, Ships, Foreign, Interest), Expenses (Planetary Development, Fleet Maintenance, Research, Aid, Special Projects, Additional), Projected Change/Treasury; graphs Population/Trade/Savings/Colonies/Techs/Battles/Ships/Lost/Killed, "Turns To Display" | `EmpireSummaryPanel`, `EmpireInfoPanel`, `BudgetPanel`, `BudgetPieChartPanel`, `PieChartPanel`, `SystemsPage`, `ExploredSystemsPage`, `EnemySystemsPage`, `EventsHistoryPanel`, `StatsPanel` (+`Overlay`), `StatsGraphPanel`, `StatsLegendPanel`, `TradeSummaryPanel`, `ShipSummaryPanel` | `PlayerTurnStats`, `PlayerTurnHistory`, `GameTurnHistory`, `ShipRecords` | | S11 | **Trade view / sectors** | `GUI/TradePanel_Elements.tga`, `StarMap/TradeDot_Depart.tga`, `TradeLine_Depart.tga`, `STATIONICON_TRADE`; `TRADE_*`, `TRADESECTOR_*`, `TRADEROUTE_*`, `TROUTESTATUS_*` (Inactive/New/Developing/Established/Shutting Down), `SECTORSUMMARY_*`, `FREIGHTERCOUNT_*`, `UICSTR_NEXT/PREV_TRADESECTOR` | Trade Sectors; Sector %s secure/unsecured; Routes, Freighters, Income, Maximum Route Length; Build Freighter; raid targets | `TradeSectorPanel`/`ITradeSectorPanel`, `TradeRoutePanel`, `TradeSectorList`, `TradeSystemList`, `TradeSummaryPanel`, `RaidFleetList/Item`, `RaidSectorList/Item`, `RaidTargets` | `TradeManager`, `ServerTradeManager(Impl)`, `ClientTradeManager`, `TradeSector`, `TradeRoute`, `TradeSystemInfo`, `ServerTradeSector` (+`FreighterWarning`) | | S12 | **Diplomacy screen** (+ Alliance manager, Aid, Joint projects, Intel) | `GUI/Alliance/*.tga` (11 "table" scenes: `DIPTABLE_HOST_*`/`GUEST_*`, `TECHTABLE_*` per race pairing), `DIPRELATION_ARROW`, `PoliticalButtons.tga`; `DIPSCREEN_*` (27), `ALLIANCEDLG_*` (45), `ALLIANCEMAN_*` (22), `GIVEAID_*` (19), `GIVETECH_*` (21), `SURRENDERDLG_*`, `EMPIRESURRENDER_*`, `INTEL_*`, `AIDIP_*` (755 AI diplomacy lines, ~125 per race); `UI_ALLY_SEND_AID`, `UI_ALLIANCE_ACCEPTED/REJECTED/BROKEN` | status War / Ceasefire / NAP / Ally; per-player Savings, Colonies, Homeworld, Hazard, Ships, Sats, Max Class/Power; Give Savings/Research, Compose Message, View Agreements, Demand Surrender; Alliance Manager lists (Alliance Members / Non-Aggressive / Cease Fire / Enemy Players), invites, downgrade dialogs; Aid Manager (per-turn savings/research for N turns); Joint Project (Offer Technology); Intel Analysis (Last Ships Observed, Known Empire Technology); "Research %s to engage in diplomatic relations" | `DiplomacyPanel`, `DiplomacyPlayerCard`, `DiplomacyStats`, `PlayerAlliancesPanel`, `PlayerAllianceControls/Popup`, `AllianceDialogCommon`, `AllianceInviteDialog(Std/Neg)`, `AllianceEventDialog`, `GiveAidPanel`, `GiveAidPlayerPanel` (+`Overlay`), `GiveAidControlPanel`, `TechOfferDialog(Base)`, `TechOffer{Accepted,Cancelled,Rejected,Query,QueryAccepted,QueryRejected}Dialog`, `IntelAnalysisPanel`, `IntelPlayerTab`, `IntelShipList`, `IntelTechList`, `IntelTechIcon` | `AllianceInvite`, `PlayerAid`, `TechOffer`, `AIRelationRecord`, `ObservedDesign/Tech/Weapon`, `SNMAlliance*`, `SNMDemandEmpireSurrender*`, `SNMTechOffer` | | S13 | **Comm system** (structured diplomacy messaging) | `GUI/com_system/{com_system_icons,Com_InnerBorder,TabOutline}.tga` (33 message icons); `COMMSYSPAGE_*`, `COMMTAB_*`, `COMMDEC_*` (26), `COMMREQ_*` (30), `COMMRECIP_*`, `COMMEXP_*`, `COMMMSG_*`, `UIC_BEGIN_COMM`; `UI_CHAT_*` | pages Chat / Compose / Incoming / Outgoing; declarations (I Want, I Saw, I Like/Hate, Curse, Thanks, Sorry, Send System Info/Notes/All Colony Info, Severed alliance…) and requests (Rally/Attack/Defend at, Money, Research, Disposition, Harass X, Stop harassing/mining/colonizing, Sever alliance…); recipients Broadcast/Alliance; expiry ASAP/Never/By turn | `CommSystemPanel` (+`InnerBorderOverlay`), `CommSystem_Builder/Chat/Messages/Viewer`, `CommListPanel`, `CommIconList`, `CommIcon_{Player,Standard,System}`, `CommParamList/Page`, `CommMessageContainer` | `ICommMessage` → `CommDeclare*` (13) / `CommRequest*` (15) / `CommGenericMessage`; `SNMCommMessage`, `SEAIReceiveCommMessage`; `ChatTranslation` + `Locale/EN/ChatTrans.txt` | | S14 | **Rankings** | `RANKINGS_*` (11) | Ranking by Income, Technologies, Colonies, Population, Output, Ships (Built/Lost/In Service/Enemy Killed) | `RankingsPanel` | `PlayerTurnStats` | | S15 | **Political map overlay** | `StarMap/SystemUI/{InfluenceDisc,Core}.tga` (`POLMAP_HALO`, `POLMAP_MILITARY_THREAT`, `STARMAP_SENSOR_RANGE`, `POLMAP_CORE_*`), `PoliticalButtons.tga`; `POLMAP_*`, `UICSTR_TOGGLE_POLMAP_*` | views Political / Alliances / Recent Combats / Military / Sensor Network; "Analyzing Intel…" | `PoliticalMapPanel` | sensor model `SensorShadow`/`SphereSensorShadow`/`SensorJammerShadow` | | S16 | **Events (turn news)** | `GUI/Events/*` (61 tga: per-race `*_tv_events512_1-4`, `special_events512_1-14`, `EventBG`, `EventButtons`, `static_screen`, `*_Victory/_Defeated`, `Draw`, `Progression*`); ~250 `EVENT_*` sprites; `EVENTMSG_*` (415), `EVENTSUM_*` (247), `TOOLTIP_EVENTS_CLOSE`; `UI_NEWS_OPEN/CLOSE/CHANGE` | one "TV" card per event with prev/next; ticker summaries | `EventPanel`, `EventPanel_ForLists`, `EventsDisplayPanel`, `EventsTickerPanel`, `EventsHistoryPanel/List` (+`Item`) | `EventStorage` (+`Event`, `TurnEvents`), `StrategyEvent`, `SystemEvent`, `SETurnEvents`, `SNMGenericEvent` | | S17 | **Spy reports** | `SPY_*`, `SPYSUM_*` (13), `SPYINFO_*`, `SPY_TRADE_BTN`/`SPY_DEFENSE_BTN` sprites | Spy Network (Spies / Spy Reports; statuses Enroute/Active/Detected/Completed/Extracted); Spy Report: Trade Routes / Events / Research / Defenses | `SpyReport`, `SpyReportTrade/Events/TechTree/Defences`, `SpyReportTradeRoute`, `TradeSpyReport`, `EventsSpyReport`, `TechTreeSpyReport`, `DefencesSpyReport` | `SpyCraft`, `ClientSpyManager`/`ServerSpyManager` | | S18 | **Modal turn dialogs** | `ELIMINATEDDLG_*`, `ENDGAMESPLASH_*`, `PROCESSING_TITLE`, `TIMERSDLG_*`, `AIPOLICY_*`, `SPECPROJECT_CONFIRM_*`, `SCENARIO_PROGRESSIONWARS_DLG_*`, `UPSTARTOBJ_*`/`*OBJ_*` scenario objectives | "You have been ELIMINATED!", "You are VICTORIOUS!", "Game ends in a DRAW", Processing…, Game Time Limits, Choose AI Policy (Maintain/Defend/Expand), Generational Convoy | `EndGameDialog`, `EndGameMoviePanel`, `AIProcessingDialog`, `AIRebellionDialog`, `SetTimersDialog`, `AIPolicyDialog`, `ProgressDialog::StrategyHost/Join`, `AdvanceStageFleetQueryDialog`, `SEPostDialog` | `EndCondition`/`IEndConditionFunctor`, `*VictoryFunctor` (12), `AIRebellion` | ### 2.3 Combat layer | # | Screen | Evidence | Key labels | `Game::` UI classes | Subsystem | |---|---|---|---|---|---| | C1 | **Combat setup / encounter query** | `GUI/CombatSetup/*` (15: `CombatElements(_MouseOver)`, `CombatStates(_2)`, 11 `combatcard_*.tga`); sprites `ENCACTION_{OBSERVE,IGNORE,FIGHT,AUTO,FIGHTIF,AUTOPEACE,SURRENDER,SURRENDERAUTO,SURRENDERFIGHT}`, `COMBATSETUP_CARD_*`, 24 `COMBATSETUP_CARD_SCENARIO_*` (one per encounter type: VonNeumann, SlaversRefuel, Pirate, Monitor, Meteor, Derelict, Swarm, PuppetMaster, SystemKiller, TradeRaiders, LarvaQueen, SwarmQueen, Locust, Berserker, CrowRuins, Refugees, Ortgay, VNHome, VNFinsol, GasCloud, TheHerald, Unknown, RebelAI); `COMBATSETUP_*` (23), `ENCOUNTERNAME_*` (24), `COMBATLAUNCH_*`; globals `COMBATSETUP_SYSTEMSUMMARY_TOP`; `UI_COMBAT_STING/WILL_FIGHT/WONT_FIGHT` | "Encounter at %s / in Deep Space / in Nodespace", "Raiders in %s"; per-player choice: Fight Manually · Fight Manually If Opponent Does · Auto Resolve Peacefully · Auto Resolve · Observe · Demand Surrender (Auto/Fight) · Surrender; query timer | `CombatSetupScreen` (+`Overlay`), `CombatSetupDialog` (+`TimerOverlay`), `CardPanel`, `EncounterInfoPanel` (+`Overlay`), `EncounterActionControl`, `EncounterList` (+`Item`), `CombatPlayerList/Item`, `CombatPlayerInvariant` | `EncounterQuery`, `EncounterParams`, `CombatEncounterParams`, `SNMDoEncounterQuery`/`SNMEncounterQueryResults`, `SNMRequestRandomEncounter`, `CombatMissions/Encounter/{DeepSpace,InSystem,NodeSpace}.combat` | | C2 | **Combat loading** | `GUI/Combat/CL_*.tga` (33 faction/encounter loading backdrops), `CL_Elements.tga` (`COMBATLOAD_SCREENHAZE`, `COMBATLOAD_VERSUS`), `GUI/SplashArt/Loading/*` (37 splashes), `LoadScreen_Anim00-03.tga`, `loadbar.tga`; `COMBATLOAD_LOADING`, `COMBAT_WAITINGFORPLAYER/SERVER` | "Loading…", "Waiting for player: %s" | `CombatLoaderPainter`, `CombatLobbyClient` | `CombatLaunchParams`, `SNMHostCombat/JoinCombat/LaunchCombat`, `CombatNetworkServer/Client`, `CNM*` (combat net msgs) | | C3 | **Combat screen (tactical HUD)** — Battle view ⇄ Sensors view | `GUI/Combat/CombatElements.tga` (81 sprites: `COMBATHUD_WEAPONS_*`, `GROUPCON_*`, `RESERVESSURROUND_*`, `BOMBARD*`, `STANCEICON_{PURSUE,AGGRESSIVE,STANDOFF,BREAKOFF,RETREAT}`, `CLOAKBUTTON`, `AEAUTOFIREBUTTON`, `ONLYMYTARGET`, `HOLDFIRE_ALL`, `FACINGICON_{TARGET,BROADSIDE,NAV}`, `PLAYERLIST_{FIGHTING,CEASECOMBAT}_ICON`), `ShipOverlay.tga`, `Models/CombatHud/*.X` (ShipSelectRing, EnemyRing, combat_arrow/Sprint_Arrow waypoints, MissileTargetDrop/point, MouseTargetPoint), `GUI/Mouse/mouse_{default,addselection,forcefire,invalid,moveplane,rotateformation}.tga`; `COMBATHUD_*`, `UICSTR_TAC_*` (45 hotkeys), `TOOLTIP_COMBATBTN_*`, `TOOLTIP_STANCE_*`, `TOOLTIP_FACING_*`, `TOOLTIP_COMBAT_*`, `TOOLTIP_*_CAPACITY` (drones, shuttles, bio/node missiles, hunters), `COMBATOPTIONS_*`; globals `COMBATHUD_*`; exe refs `GUI/Combat/CombatHUD.script`, `SensorHUD.script`, `NoHUD.script` (not shipped) | Battle / Sensors main buttons; Fleet Commands; weapons panel (per-bank toggle/fire/launch, groups 0-2, Select All, Hold Fire); Reserves list; stances (Normal, Pursue, Close to Attack, Stand Off, Break Off to Back Line, Retreat), facing (Face Target / Turn Broadside / Face Heading) for Selection vs Fleet; Cloak/Intangibility, AE Autofire, Fire Only At My Target, Bombard Colony (Population / Civilian / Imperial), Cease Combat; hotkeys Pause, Single-Step, Speed Up/Slow Down Time, Toggle Sensors/HUD/Reserves/Weapon Panel/Ship Overlay/Framerate, Next/Prev Ship/Enemy, Focus, Focus On Reinforcements, All Stop, Clear Targets/Selection, Roll Left/Right, Release Grapple; Select Command Fleet | `CombatScreen` (+`BandboxEventTarget`), `CombatView` (+`Focus/SelectionEventTarget`), `BattleView` (+`CameraCtl`, `DebugOverlay`), `SensorsView` (+`CameraCtl`), `CombatOverlay` (+`SelectionEventTarget`), `CombatOverlay_{BombardButton,FacingButton,PlanetStats,Reserves,StanceButton,Weapons}`, `CombatPeaceButton`, `StanceButtonBase`, `CombatSelection`, `CombatSelectionRing`, `CombatFocus`, `Bandbox`, `GunBankSelection`, `ShipWeapons` (+`GunEventTarget`), `WeaponGroupControls`, `AllGroupControls`, `OneGroupControls`, `ReservesList`, `CombatTitle`, `CombatPlayerList`, `CombatOptionsDialog`, `BombardDialog`, `RequestAsylumDialog`, `ChatControl` | 31 `CombatCommand*` types (ship attack/maneuver/waypoint/facing/stance/hold-fire/cloak/intang/bank toggle/fire once/grapple; fleet stance/facing/hold-fire; reserves pick/move; bombard mode; AE autofire; set player AI; want-end-combat; asylum) → `GameCombatSim` / `Mars::CombatSim`; `Actor`/`Ship`/`ShipBase`/`Station`/`Planet` entities; `TacAI*`; `CombatSim` lockstep (`@SYNC ERROR`) | | C4 | **Combat end & report** | `COMBAT_*` (19: victory/defeat/draw/ceasefire/derelict/VN-mom/asteroids/refugees), `COMBATREPORT_*` (10); `Events/*_Victory.tga` | "You are victorious!", "Round draw.", ceasefire query/success/failure, "Data transmission terminated." (observer); report: Class Name / Total / Lost / Inflicted / Taken, Allies / Enemies, Overall Weapons Damage | `CombatDoneDialog`, `CombatReportPanel`, `CombatReportPanelEx`, `CombatReportPlayerCard`, `CombatReportWeaponItem`, `CombatPlayerStats` | `CombatReport`, `CombatPlayerReport`, `CombatShipReport`, `CombatWeaponReport`, `CombatDamageReport`, `TacReport(Events)`, `EncounterResult(s)` → 20 `*EncounterResult` types, `ClientEncounterResults`, `SNMEncounterResults`, `SNMAllCombatDone` | --- ## 3. Flow ```mermaid flowchart TD Splash[F1 Splash / intro movie] --> Menu[F2 Main menu] Menu --> Profiles[F3 Profile manager] Menu --> Options[F4 Options / Key bindings] Menu --> Credits[F5 Credits] Menu --> Tutorial[F6 Tutorial pages + videos] Menu --> Movies[F7 Cinematics] Menu -->|Single Player / Host MP| Mode[F8 Custom or Scenario] Mode --> Setup[F9 Game setup] Mode --> Scen[F10 Scenario setup] Menu -->|Load Game| Load[F11 Load game] Menu -->|Join MP| Browser[F12 Game browser: LAN / Internet / Chat] Setup --> Lobby[F13 Lobby: slots, player setup, timers, AI policy] Scen --> Lobby Load --> Lobby Browser --> Lobby Lobby -->|Launch → Initializing Game…| Strat subgraph TURN[Strategic turn loop] Strat[S1 Strategy map screen] --> Sys[S2 System panel] Strat --> Fleet[S3 Fleet panel + action dialogs] Fleet --> FM[S4 Fleet manager] Sys --> DM[S5 Defense manager] Sys --> PM[S6 Population / Slave manager] Strat --> Build[S7 Build] Strat --> Design[S8 Design] Strat --> Research[S9 Research tech tree] Strat --> Empire[S10 Empire summary tabs] Strat --> Trade[S11 Trade sectors] Strat --> Dip[S12 Diplomacy / Alliances / Aid / Intel] Dip --> Comm[S13 Comm system] Strat --> Rank[S14 Rankings] Strat --> Pol[S15 Political map overlay] Strat --> Ev[S16 Events] Empire --> Spy[S17 Spy reports] Strat --> Save[Save game / Quit dialog] end Strat -->|End Turn| Wait[Waiting for other players
SETurnEndPending, cancellable] Wait -->|all done| Proc[Server SEProcessTurn:
move, build, research, events] Proc -->|no encounters| NewTurn[SETurnResults / SNMResumePlaying
new turn sound] Proc -->|encounters| Query[C1 Combat setup: encounter query
Fight / Auto / Peace / Observe / Surrender] Query --> Loading[C2 Combat loading] Loading --> HUD[C3 Combat screen: Battle ⇄ Sensors] HUD -->|combat timer or all cease| Done[C4 Combat done + report] Done -->|SNMAllCombatDone| NewTurn Query -->|other players' battles| Wait NewTurn --> Strat NewTurn -->|eliminated / victory| End[S18 End-game splash / movie] End --> Menu Save -->|Quit to Main Menu| Menu Lobby -.->|MP: between rounds, mid-game join, host migration| Wait ``` ### Turn structure (from strings, sound hooks and `SE*`/`SNM*` event names) 1. **Strategic round** (`LOBBYSTATUS_STRATEGY_ROUND`, `PLAYERSTATUS_PLAYING`). All S-screens are reachable from the map bar at any time; commands accumulate in `TurnCommands`. Optional timer (`GAMESETUP_TIME_STRATEGY`, `StrategyTimerParams`, `SETurnTimeExpired`); timers changeable mid-game (`SNMSetTimers`, "take affect the next turn"). 2. **End Turn** → `SNMEndTurn`, local state `SETurnEndPending` (status "Done"); can be withdrawn (`SETurnEndCancelled`, `SNMQueryEndTurnDone`). Autosave "(Autosave EndTurn)". In MP the host "collects turn data from other players" for saves (`SAVEGAME_COLLECTING_TURNDATA`). 3. **Processing** (`PROCESSING_TITLE`, `SEProcessTurn`, `SEAIPrepareTurn`, AI `SNMRunAI`): movement (`SEFleetArrived`), builds (`SEBuildCompleted`), research, trade, plague/morale, scenario scripts, then `SETurnResults` + `SETurnEvents`. 4. **Querying round** (`LOBBYSTATUS_QUERYING_ROUND`, `PLAYERSTATUS_QUERYING`): each encounter raises C1 for every involved player (`SNMDoEncounterQuery`); time limit = base + per-additional-round (`GAMESETUP_TIME_QUERYBASE/QUERYEXTRA`). Results `SNMEncounterQueryResults` decide fight vs auto-resolve (`GameCombatSim` headless) vs peace. 5. **Combat round** (`LOBBYSTATUS_COMBAT_ROUND`, `PLAYERSTATUS_FIGHTING`, status column ROUNDS / TIME REMAINING): battles hosted one at a time per host (`SNMHostCombat` → `SNMHostCombatReply` → `SNMLaunchCombat`, clients `SNMJoinCombat`), each bounded by `GAMESETUP_TIME_COMBAT` (`SNMCombatTimeRemaining`). Players not in a battle stay on S1 read-only ("%s battles in progress, %s of %s remaining"). Combat can end early on ceasefire (`CombatCommandSetWantEndCombat`, `CeaseCombatFunctor`) or elimination (`CombatEliminationFunctor`) or expiry (`CombatExpiredFunctor`). Results → C4 → `SNMEncounterResults`. 6. **Resume** (`SNMAllCombatDone` → `SNMResumePlaying`/`SEResumePlaying`, `UI_LAST_PLAYING` = gui_newturn.wav, `SELastPlaying`): new turn number, S16 events appear, loop to 1. 7. **Exit conditions:** `EndCondition` functors per scenario; `ELIMINATEDDLG`, `ENDGAMESPLASH` (win / other player wins / team wins / draw), `EndGameMoviePanel`; bankruptcy elimination after `BANKRUPTCY_ELIMINATION_TURNS 10`. 8. **MP side-paths:** join in progress (`LOBBY_INPROG_*`: joiner parks in F13 until next turn, `SNMSlotInsertClient`), leaver replaced by AI per `AIPOLICY`, host leaves → host migration + `FNM*` file push of the autosave (`HOSTMIG_*`), "(Rejoin)" save. --- ## 4. Sound-hook → screen index (`sound_ui.csv`) | Event | Screen | |---|---| | `UI_KERBEROS_SPLASH` | F1 | | `UI_GAMESETUP_ROLLOVER/CONFIRM` | F9/F10 | | `UI_DRAG_START/STOP` (gui_playerslot) | F13 slot drag, S4/S5/S7 drops | | `UI_CHAT_*` | F12 chat, S1a chat, S13 | | `UI_RES_*` | S9 | | `UI_DESIGN_*` | S8 | | `UI_AUTO_REFUEL/REPAIR` | S3 support panels | | `UI_POLITICAL_CLOSE` | S15 | | `UI_NEWS_*` | S16 | | `UI_TAB_SELECTED` (gui_overview) | S10 | | `UI_ALLY_*` / `UI_ALLIANCE_*` | S12 (`UI_ALLY_RECEIVE_AID` marked "not in code yet") | | `UI_COMBAT_STING/WILL_FIGHT/WONT_FIGHT` | C1 | | `UI_LAST_PLAYING` (gui_newturn) | turn rollover | | `UI_EXIT_SCREEN`, `UI_DIALOG_*`, `UI_LIST_*`, `UI_TREE_*`, `UI_BUTTON_*` | generic | --- ## 5. Surprises, hidden/debug, cut features 1. **UI is not data-driven.** Only 4 `.script` files exist and none is a layout. The exe nevertheless references `GUI/Combat/CombatHUD.script`, `SensorHUD.script` and `NoHUD.script` (string-intel §3) — absent from both gobs and from the loose install. Since `gobio` has a `NativeFileSystem` fallback, these are most likely optional dev overrides for compiled-in HUD defaults. **Consequence for reimplementation:** screen layouts have to be recovered from code (Ghidra targets: the `*Panel` constructors and `Mars::PanelManager`), not from data. 2. **Debug overlays and dev toggles left in:** `DebugOverlay::StrategyMapScreen`, `DebugOverlay::BattleView`; `Lines.script` `DEBUG_UseSimpleLine / DEBUG_LockDestination / DEBUG_ForceOutOfRange / DEBUG_ReloadOnFleetChange` (hot-reload of the line script); hotkeys `UICSTR_TAC_FRAMERATE` ("Toggle Framerate") and `UICSTR_TAC_SINGLE_STEP`; `DemoApp` and `MutexScreen` classes; `ForceSingleCore` ini key. 3. **Legacy / cut screens:** `OldGameSetupPanel`; sprites `BARBUTTON_OLDTRADE` and `BARBUTTON_OLDALLIANCE` (pre-ANY trade & alliance buttons replaced by S11/S12); `ChatHistoryPanel2`, `WeaponPanel2`, `CombatReportPanelEx` (v2 rewrites kept beside v1); `Scenario_Set_D/E.tga` carry images for **`SCENARIO_KINGOFTHEHILL`** and **`SCENARIO_SLAVEMASTER`** which have no strings and no `Scenarios/*.txt` — cut scenarios; "Upstart Apes" is internally `EARTHVSTARKAS`; `SUPPORT_REPAIR_AVAIL/REQ` are empty strings. 4. **Localized gob carries UI art:** `Scenario_Set_C.tga` (Holy Lands + Tutorial images), `Tutorial/page9-11.tga` and `Data/credits.txt` are only in `sots_local_en.gob` — a loader that only mounts `sots.gob` will miss sprites the table references. 5. **GameSpy is dead and the 2017 build knows it:** `MATCHINGSERVICE_UNSUPPORTED` "Online support for Sword of the Stars is no longer available" + "players can still connect manually" — F12 degrades to LAN/manual IP; CD-key strings (`NETERROR_CDKEY_*`, `STARTUPERROR_CDKEY_*`) survive. 6. **Standalone dedicated server** ships (`sots_server.exe`, `Dedicated Server Launchpad.exe`) with its own error vocabulary `SERVERERROR_*` (ini-section driven: map file, allowed species, defaults) — the strategy server is separable from the client UI, which is good news for a reimplementation split. 7. **Achievement/badge system predates Steam:** 56 `GUI/Achievements/*.tga`, `PlayerBadgeSet`, `PROFILEMAN_BADGES_*`, badge sprites `BADGE_*_GW100` — stored in the local profile. 8. **Sticky-note system:** per-system player notes (`PlayerNotePanel`, `StickyNoteElements.tga`, "Added by: %s, Turn %s") that can be *sent to other players* via `CommDeclareShareSystemNotes`. 9. **Alien-language chat translation:** `ChatTranslation` + `Locale/EN/ChatTrans.txt`; diplomacy is gated on translator tech (`DIPSCREEN_NEEDTRANS`). 10. **Easter eggs:** `MADE_UP_STRING` = "Hang in there, Space Cowboy. You can play the game soon. Finish reading that manual."; `SVSOEasterEgg`/`SVSOSimpleEasterEgg` encounter scripts and an AI task `AITKillEasterEgg`; rebel-AI names Guardian/Chandra/Dillinger/Daystrom/Knight/Singularity/Dyson/Spengler. 11. **Key bindings are display-only** in F4 (`HOTKEYS_DISCLAIMER`); remapping is by editing the profile ini. 12. **The lobby doubles as the MP waiting room** between turns and for mid-game joiners — it is a persistent screen, not just a pre-game one. --- ## 6. Where to dig next (Ghidra hand-off) - `Game::Screen` / `Game::ScreenBar::ToggleList` — the screen switcher; find the enum behind `BARBUTTON_*` order. - `Game::StrategyMapScreen` ctor — instantiates most S-panels; cross-ref `STATUSPANEL_MIN_WIDTH` etc. from `globals.txt` to locate layout code. - `Game::CombatScreen` / `CombatOverlay_*` — check for the `CombatHUD.script` load path to confirm the compiled-default-plus-override theory. - `SETurnEndPending` → `SNMEndTurn` → `SEProcessTurn` → `SNMDoEncounterQuery` → `SNMAllCombatDone` → `SNMResumePlaying` — the turn state machine, already fully named by RTTI.