Startup Sequence
From main() to the main menu, step by step, as of 2026-11-10.
The files involved are src/GalaxyEggbertCNA/main.cpp (entry point and flags),
GalaxyEggbertGame.cpp (constructor), GalaxyEggbertGameLoad.cpp
(LoadContent()), GalaxyEggbertGameUpdate.cpp (the first updates) and
GalaxyEggbertGameMissions.cpp (title scene, missions). The host class is
GalaxyEggbertGame, a
Microsoft::Xna::Framework::Game from CNA.
1. main()
main() only calls RunGame() inside a try. An escaping exception
is printed (GalaxyEggbertCNA: fatal exception: ...) and rethrown, because in the
browser it would otherwise arrive as a bare pointer with no text. On Android CNA's
Entrypoint.hpp renames main() so the Java side can start it.
RunGame() first does the platform-specific preparation:
- Android:
RedirectStdioToLogcat()andPrepareAndroidAssets()(AndroidAssets.cpp); it returns 1 if the assets cannot be prepared. - Web:
Editor::ApplyCampaignEdits("worlds3d", CampaignOriginalsDir())lays the player's in-browser edits of shipped worlds over the page's packedworlds3d/before anything loads a world (see World Loading).
2. The player's folder: ChooseUserFolder()
On desktop builds the folder for savedata.txt, resume.txt, demos/ and customworlds/ is chosen before the game object exists:
--user DIRon the command line, else- the environment variable
GALAXY_USER_DIR(the test scripts use their run folder), else - CNA's
StorageDeviceroot for the application name "Galaxy Eggbert" (~/.local/share/Galaxy Eggbertor$XDG_DATA_HOMEon Linux,%LOCALAPPDATA%\Galaxy Eggberton Windows).
In the default case the files an earlier build kept in the working folder are copied over once
(Game::CopyOldUserFiles(), only if the new folder has no savedata.txt;
nothing is moved or overwritten). Game::SetUserFolder() records the choice
(UserFolder.hpp). If no folder can be created the game keeps the working folder. The
web build keeps /save and Android its private storage; this step is skipped there.
3. Constructing GalaxyEggbertGame
The constructor (GalaxyEggbertGame.cpp):
- sets the window title to "Galaxy Eggbert";
- reads
GALAXY_PERF=1(timing output) andGALAXY_MODEL_CULL=0(disable model culling); - creates the
GraphicsDeviceManagerand selects theHiDefprofile (the screenshot and golden-capture paths useGetBackBufferData, a HiDef operation); - loads
savedata.txt(saveData_.Load(), SaveData) and applies its full-screen preference; - subscribes to CNA's
Keyboard::KeyDownEXTfor ordered key presses: demo key events, the editor's command keys and text entry, demo names, and typed cheat letters in Play.
Members such as Sound, Hud, InputPad, WorldRuntime, InteractionSystem and WorldEditor are plain value members, constructed with the game.
4. Command-line flags
RunGame() then scans argv and switches modes on the game object. All flags as of 2026-11-10:
| Flag | Effect |
|---|---|
--user DIR | The player's folder (step 2). |
--mission N | Skip the menus and start mission N in Play (EnableStartMission). |
--spawn x,y,z[,yawDeg] | With --mission: place Blupi at that raw-grid position and yaw. |
--galaxy | With --mission: play the selected player's own galaxy, with its progress. |
--autoplay SCRIPT | Play the mission by an autoplay script (Autoplay); the process exits with 2 if the script cannot be loaded, otherwise with the autoplay result. |
--record-demo FILE, --demo-ticks N, --demo-title TEXT | Record a main-menu demo (used by tools/record_demo.sh). |
--verify-demo FILE | Replay a demo and compare its end (tools/verify_demos.sh). |
--golden-capture | Deterministic screenshots of world 999 for tests/golden/. |
--golden-capture-trace | Deterministic movement trace for tests/golden/golden_trace.txt. |
See Running the Game and Configuration for the environment variables.
5. Run() and LoadContent()
game->Run() enters CNA's loop. As in XNA, CNA's Game::DoInitialize()
creates the graphics device, then calls Initialize(), which calls
LoadContent(). GalaxyEggbertGame does not override
Initialize(); everything happens in LoadContent()
(GalaxyEggbertGameLoad.cpp), synchronously, in this order:
- A first world.
worldRuntime_.LoadFromVwrFile("worlds3d/world001.vwr"), the main hub. If it is missing the function prints a hint ("run the binary from its own build directory") and returns: the game needs its data next to the executable. - Texture scale. 1x or 2x for this run, decided once: the Setup's "Textures" setting,
GALAXY_TEXTURES, or Auto (2x with Ultra effects on a display at least 1000 px tall). Web and Android always use 1x. - The terrain sheet.
Content/icons/object-m.png(oricons2x/): tile coverage is classified from its alpha (TileCoverage.hpp), brick edges and clear texels of opaque tiles are filled, and a padded, mipmapped copy is built for the TileAtlas. Average tile colours and water tints for the 3D effects are taken from it. - The world's presentation.
RebuildWorldPresentation(): background picture, TerrainRenderer meshes, block models (see World Loading). Then the terrain and grass effects (textures3d/grass_top.png). - 2D layers.
hud_.LoadContent()andinputPad_.LoadContent()load their own sheets (text.png,pad.png, menu backgrounds). - Object sheets for billboards:
element.png,explo.png,blupi.png,blupi1.png. - 3D models. Blupi from
avatars3d/blupi/avatar.skinnedmodel.jsonwith itsclips.txtand face textures, or the fox placeholder inavatars3d/blupi_placeholder/if the real model is absent (without any model the camera stays first-person). Then the object model library:avatars3d/objects/index.txt, and per model itsicons.txt(into theObjectModelTable),materials.txt, measured BigDecor shapes, spark textures and sign decals. - Blupi's start.
PlaceBlupi()at the world's spawn cell, or (0, 1, 0). - Sound.
sound_.LoadContent()loads whichever ofContent/sounds/sound000.wavtosound092.wavexist (Sound); sound on/off, effects volume and the jump-button side are restored fromSaveData.
The WorldEditor has no loading step; it builds what it needs when it is opened.
6. The first frames: Wait, title scene, menu
The game starts in the Wait phase (GamePhase,
include/GalaxyEggbert/Def/GamePhase.hpp). Each Update() runs a fixed
1/60 s step:
- Title scene. While in
Wait(and later in the main menu and the editor's world list) the game requests the title scene.LoadTitleScene()loadsworlds3d/title.vwrintoWorldRuntime(replacing the hub loaded above), rebuilds the presentation, puts a fresh Blupi at the world's spawn facing the camera, and marks the scene active.UpdateTitleScene()animates the world, lets Blupi idle and sways the camera 7 degrees either way over 14 seconds. Iftitle.vwris missing the plain screens are used. - Wait. The original's 5-second loading gauge, now purely cosmetic (
kWaitDurationSeconds = 5.0f): loading already finished inLoadContent(). When it ends, the game readsresume.txt(ReadResumeLog()) and goes toResumeif there is an interrupted mission or saved progress, otherwise toInit, the main menu. - Resume. "Continue" replays the interrupted mission from its recorded start (
BeginResume(), ResumeLog) or, failing that, loads the saved mission (LoadMission(saveData_.GetMissionNumber())). See Save Data & Resume. - Main menu (
Init). Play callsLoadMission(1)(the main hub) and entersPlay; Galaxy callsStartGalaxy()(Your Own Galaxy); Editor opens theWorldEditor's world list; Setup entersMainSetup; Demo, Help, Fullscreen/Window and Exit do what they say. 40 seconds without input in the settled menu start the demos (Demos & Recordings).
7. The --mission shortcut
With --mission N the menus never appear. On the first Update() (GalaxyEggbertGameUpdate.cpp):
if (startMission_ != 0)
{
SetPhase(GalaxyEggbert::Def::GamePhase::Play, /*bypassFade=*/true);
if (startGalaxy_) { galaxyGamer_ = saveData_.GetSelectedGamer(); saveData_.SetGalaxyMode(true); ... }
LoadMission(startMission_);
startMission_ = 0;
if (startSpawnSet_)
{
PlaceBlupi(startSpawnX_ - WorldRuntime::kWorldCenterX, startSpawnY_,
startSpawnZ_ - WorldRuntime::kWorldCenterZ);
blupi_.SetYaw(startYawDegrees_ * 3.14159265f / 180.0f);
...
}
}
The golden-capture modes do the same with the fixed showcase world, LoadMission(999).
Once in Play with the mission loaded, StartResumeLog() records the
mission's start (build, world path and hash, seed, Blupi's position, settings) and input recording
begins; an armed demo recording starts at the same moment.
Related pages
- World Loading (what
LoadMission()does) - Game Loop, GalaxyEggbertGame
- Running the Game, Configuration, Platform Support