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

Headerinclude/GalaxyEggbert/HubDoors.hpp
Sourcesrc/GalaxyEggbert/HubDoors.cpp
NamespaceGalaxyEggbert (free functions and small structs, no class)
Icons usedBlockTypes.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.

DeclarationDescription
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

Related pages