Gameplay

Core mechanics, enemies, collectibles, and progression.

Core Gameplay Loop

Galaxy Eggbert is a 3D platformer. The player controls Blupi — a small character — through voxel worlds, collecting treasures, picking up keys and power-ups, avoiding enemies and hazard tiles, and reaching the level exit.

  1. Select a gamer slot (1, 2, or 3) on the gamer-select screen.
  2. Navigate Blupi through the 3D world.
  3. Collect all treasures for a bonus life.
  4. Collect any keys required to unlock doors (tracked in HUD).
  5. Avoid patrol enemies, hazard tiles (Lava, Spike, Crusher), and fall deaths.
  6. Reach the level exit (type 7 object) to advance to the next world.
  7. After world 5, progression wraps back to world 1.
  8. Losing all lives returns to the gamer-select screen; saves reset to 3 lives, world 1.

Player Character (Blupi)

Implemented in src/GalaxyEggbert/Game/Blupi.hpp and Blupi.cpp.

Physics Constants

ConstantValueNotes
kGravity−22.0 units/s²Applied every frame to Y velocity
kJumpSpeed10.0 units/sInitial Y velocity on jump
kMoveSpeed5.5 units/sHorizontal movement speed
kTurnSpeed180 °/sRotation speed (LEFT/RIGHT keys)
kHalfW0.35 unitsHalf-width for AABB collision
kHalfH0.70 unitsHalf-height for AABB collision
Terminal velocity−30 units/sY velocity clamped
Fall death thresholdY < −10 unitsTriggers death + respawn

Animation States

State (BlupiAction)Triggered when
StopOn ground, no horizontal input, not turning
MarchOn ground, horizontal speed > 0.1
TurnOn ground, not moving, pressing LEFT or RIGHT
JumpIn air, Y velocity > 0 (rising)
AirIn air, Y velocity ≤ 0 (falling)

Animation frames are looked up from Tables::GetBlupiIcon(action, scaledPhase), which maps to the blupi.png sprite sheet (600×2040 px, 60×60 tiles, 10 columns × 34 rows). The animation ticks at 1/3 game-tick rate to match the original 20 fps timing.

Respawn Invincibility

After any respawn (fall death, tile hazard, or enemy hit), Blupi has 2 seconds of invincibility. During this time the sprite flashes (visible/invisible every 0.1 s). Tile hazards and enemy hits are skipped while the timer is active.

Lives and Death

Collectibles

Object TypeNameEffect
ObjectType5TreasureCounts toward treasure total; bonus life when all collected
ObjectType6Extra-Life EggCounts as collected item
ObjectType30DrinkCounts as collected item
ObjectType49Red KeyKey collected (tracked in HUD)
ObjectType50Green KeyKey collected
ObjectType51Blue KeyKey collected
ObjectType25Shield Orb5 seconds of invincibility
ObjectType13HelicopterGrants shield (vehicle boarding placeholder)

Hazards

Tile Hazards

Block TypeIcon IDEffect
Lava68Kills Blupi on contact (removes 1 life)
Spike373Kills Blupi on contact
Crusher317Kills Blupi on contact

Tile hazard detection is performed in GalaxyEggbertGame::UpdatePlay() each frame when Blupi is on the ground and neither the shield nor respawn invincibility is active.

Fall Death

Falling below Y = −10 world units triggers a death. The spawn point is fixed to the position encoded in the level file's blupiPos= header field.

Enemies

Object TypeNameBehavior
ObjectType2Patrol Enemy APatrols linearly between two points; kills on contact
ObjectType3Patrol Enemy BSame patrol, different sprite
ObjectType4BulldozerPatrol using bulldozer sprite; kills on contact
ObjectType16SpiderPatrol; kills on contact
ObjectType17FishPatrol (water sections); kills on contact
ObjectType20BirdPatrol; kills on contact
ObjectType33Blupit TankPatrol; kills on contact

All patrol enemies use linear movement between posStart and posEnd. If a patrol enemy's start equals its end (stationary in level file), a default ±2 tile X patrol range is applied. Contact detection uses a 0.85 unit radius check.

Moving Platforms

ObjectType1 is a moving platform lift. It moves linearly between two endpoints. When Blupi is within 0.85 units horizontally and 1.5 units vertically of the platform center, the platform's XZ movement delta is applied to Blupi's position via Blupi::ApplyExternalDelta().

The Level Exit

ObjectType7 is the level exit goal marker. When Blupi's position is within 0.85 units of the exit, Decor::WasExitReached() returns true, the win sound plays, and the game transitions to the Win phase, then loads the next world.

World Progression

Game Phases (Screens)

PhaseScreenNotes
InitGamer-select / main menuKeys 1/2/3 select slot; S opens settings; ESC quits
PlayActive gameplayMain game state
PausePause overlayESC resumes; S opens settings
WinLevel completeAny key advances to next world
LostGame overAny key returns to gamer-select
MainSetupSettings (from main menu)S toggles sound; ESC returns
PlaySetupSettings (during pause)S toggles sound; ESC returns