HubDoors
The hubs' progression logic on a 3D world: which doors and gold bars open, which signs show "completed", and where Blupi stands when he arrives.
Location
| Header | include/GalaxyEggbert/HubDoors.hpp |
|---|---|
| Source | src/GalaxyEggbert/HubDoors.cpp |
| Namespace | GalaxyEggbert (free functions and small structs, no class) |
| Icons used | BlockTypes.hpp: HubDoor = 182, GoldDoor = 183, MissionSign1 = 174 (to 181), WorldSelect1 = 158 / WorldDone1 = 166 (worlds 1-8), WorldSelect9 = 309 / WorldDone9 = 310, WorldSelect10 = 411 / WorldDone10 = 416 (worlds 10-14) |
Purpose
The campaign is organised as in the original: a main hub (mission 1) with a sign per world, world
hubs (missions 10, 20, ... 120) with a sign and a door per mission. The original game finds doors
and signs by scanning left and right along a row of its 2D map
(Decor::SearchDoor(), SearchGold(), SearchWorld(),
AdaptDoors()). HubDoors does the same on a 3D World:
it looks along X and Z at the same height. It depends only on the world model, so it is unit-tested
without a window.
Cells are raw grid coordinates (the world's own, not the render space).
Public API
Verified in HubDoors.hpp as of 2026-11-10.
| Declaration | Description |
|---|---|
struct HubCell { int x, y, z; } | A cell, with ==. |
struct HubArrival { HubCell cell; float yaw; } | Where Blupi starts and the yaw he faces (BlupiController convention: he moves along (sin yaw, −cos yaw)). |
struct MissionDoor { HubCell door; HubCell sign; } | A world hub's door and the mission sign it belongs to. |
FindMissionDoors(world, sign) | For mission sign 1-8 (icons 174-181): every HubDoor one or two cells from one of that sign's cells along X or Z, at the same height. |
FindGoldDoors(world) | All gold bars in the order the main hub opens them, one per completed world: lowest first, then from +X, then from +Z (the original scans from the map's bottom right). |
FindWorldSigns(world, worldIndex) | The cells of world 1-14's sign, in either its normal or its completed icon. |
CompletedWorldSignIcon(icon) | The completed version of a world sign icon, or the icon unchanged. |
ArrivalBesideSign(world, sign) | The first free cell with a floor under it beside the sign (order −X, +X, −Z, +Z), facing the sign. |
struct HubAdaptation { goldDoors; completedSigns; missionDoors; } | What to open or change. |
AdaptHubDoors(world, mission, unlocked, cheatDoors) | Decides it. unlocked(index) reads the save's door table: in the main hub index 180 + world, in a world hub mission + sign. cheatDoors (the opendoors cheat) opens everything. Mission 1: one gold bar per completed world and the completed worlds' signs. A world hub (mission % 10 == 0): the doors of every unlocked mission, in sign order. Any other mission: nothing. Doors already opened are gone from the world, so a second call finds only those still shut. |
ArrivalPastDoor(world, door, sign) | The free, floored cell beyond an opened door on the side away from its sign, facing the door. |
How the game uses it
GalaxyEggbertGame::LoadMission() calls its own AdaptHubDoors(missionNumber)
wrapper right after building the world's presentation
(src/GalaxyEggbertCNA/GalaxyEggbertGameMissions.cpp):
const auto adapted = GalaxyEggbert::AdaptHubDoors(
terrain, missionNumber, [this](int index) { return saveData_.IsMissionDoorUnlocked(index); },
cheatDoors_);
for (const auto& gold : adapted.goldDoors)
InteractionSystem::OpenDoor(worldRuntime_, gold.x, gold.y, gold.z, sound_);
for (const auto& sign : adapted.completedSigns)
terrain.setBlock(x, y, z, Worlds::Block::make(CompletedWorldSignIcon(terrain.getBlock(x, y, z).type())));
for (const auto& door : adapted.missionDoors)
{
InteractionSystem::OpenDoor(worldRuntime_, door.door.x, door.door.y, door.door.z, sound_);
if (const auto past = GalaxyEggbert::ArrivalPastDoor(worldRuntime_.GetWorld(), door.door, door.sign))
arrival = past;
}
Opened doors slide up as the hub appears. In a world hub Blupi then starts past the last door
opened; in the main hub he starts beside the sign of the world he last played
(SaveData::GetLastWorld(), ArrivalBesideSign()). The same function runs
again when the opendoors cheat is toggled. Details: World Loading.
Tests
tests/GalaxyEggbert/HubDoorsTests.cpp:MissionDoorsAreOneOrTwoCellsBesideTheirSign,GoldDoorsOpenLowestFirstThenFromPlusX,AdaptHubDoorsOpensWhatIsUnlockedAndEverythingWithTheCheat,WorldSignsAndTheirCompletedIcons,ArrivalsFaceTheSignOrTheDoor.- The autoplay playthroughs of the hubs (Testing) cover it end to end.