Assets & Tools
What the game loads, where each asset comes from, and the scripts that produce the generated ones (as of 2026-11-10).
avatars3d/**, tools/data/blocks.csv, BoltPaths.hpp, GlueStrands.hpp,
LavaSurfaceData.hpp, textures3d/grass_top.png, worlds3d/*.vwr and plans/inventory/*.md are all generated.Runtime assets
| Directory | Contents | Source |
|---|---|---|
Content/icons/ | Sprite sheets: object-m.png (terrain tiles), element.png (objects), explo.png (explosions, big decor), blupi.png, blupi1.png, pad.png, button.png, text.png, jauge.png; .xml sidecars for three of them | Copied from Mobile Eggbert |
Content/backgrounds/ | 28 sky pictures decorNNN.png (region ids 0-31; 005, 014, 017 and 023 have none) and the screens: init, wait, pause, win, lost, setup, trial, gear, speedyblupi, blupiyoupie, plus galaxyeggbert.png (Galaxy's logo on the Setup screen, added 2026-11-08) | Copied from Mobile Eggbert; the logo is Galaxy's |
Content/sounds/ | 93 WAV files, one per sound channel (Audio & Music) | Copied from Mobile Eggbert |
Content/music/ | 10 OGG tracks, 27 MB | The original's MIDI, rendered by tools/music/render_music.py |
Content/demos/ | demo001.gdemo-demo010.gdemo, the main menu's ten demos (Demos & Recordings) | Recorded in the game (tools/record_demo.sh) |
Content/icons2x/, Content/backgrounds2x/ | Optional sheets at twice the size, loaded only when a file is exactly twice its 1x one (TextureScale.hpp) | In the repository since 2026-11-10: 9 icon sheets and 39 backgrounds, re-rendered from the Ray Dream scenes where that passed verification, otherwise an edge-padded Lanczos upscale of the 1x pixels. Never used on the web or Android |
avatars3d/blupi/ | Blupi: skinned model, 68 clips, face textures, clips.txt; vehicles/ holds the helicopter, jeep, overcraft, skateboard and tank | Ray Dream scenes via tools/rd4_to_gltf/ |
avatars3d/objects/ | 121 model directories listed in index.txt, each with its parts, skeleton, clip, icons.txt and materials.txt | Ray Dream scenes via tools/rd4_to_gltf/ |
avatars3d/terrain/ | 145 relief files (.gtr) and index.txt, which maps 158 tile icons to them | Ray Dream scenes via tools/terrain_relief/ |
avatars3d/blupi_placeholder/ | A fox model, used only when avatars3d/blupi/ is missing | Khronos glTF sample "Fox" (third-party) |
textures3d/grass_top.png | The grass seen from above (64 × 64, tiles seamlessly) | tools/textures/grass_top.py, from the leaves of tile 107 |
worlds3d/ | 81 .vwr worlds: the title scene, the campaign, world998 (gallery) and world999 (showcase) | tools/worlds/*.py with tools/worldkit.py; world999 by GenerateSampleWorld3D (Campaign & Worlds) |
worlds/ | Five original-format level files | Copied from Mobile Eggbert; read by the world generators and QA scripts, not by the game |
The game opens every asset relative to its working directory. A desktop build copies Content/, worlds3d/,
textures3d/ and avatars3d/ next to the executable after each link (changed files only). The web build packs
Content/icons, backgrounds, sounds, demos, worlds3d, textures3d and
avatars3d into its .data file and serves Content/music/ beside the page. Android packs the same
directories into the APK (without the 2x sheets) and, before the game starts, copies them to internal storage when they are
missing or come from an older build (AndroidAssets.cpp).
The tile sheet object-m.png
Every terrain block's texture is an icon of this sheet, and a block's type number is its icon number. The sheet is
1301 × 1431 pixels: 64-pixel tiles with a 1-pixel gap before each (a pitch of 65), 20 columns by 22 rows, so 440 slots,
icons 0-439. Icon n starts at pixel (1 + 65 × (n mod 20), 1 + 65 × ⌊n / 20⌋).
BlockTypes::tileUV() (include/GalaxyEggbert/BlockTypes.hpp) adds a half-texel inset so filtering never samples
the neighbouring tile. The block registry has 441 entries (0-440); icon 440 lies outside the sheet, a known gap that
VerifyTileUvBounds tracks.
For the terrain the game builds a padded copy in memory (1920 × 2112: each tile with a 16-pixel border of its own edge
texels, a pitch of 96) and mipmaps it, so distant floors do not shimmer (TileAtlas). It also
classifies every tile by its alpha channel as opaque, cut-out or translucent (TileCoverage.hpp), which picks the pass the tile is
drawn in (Rendering).
Models from the original scenes: tools/rd4_to_gltf/
The original's sprites were rendered from Ray Dream Designer / Studio scenes. This toolchain reads those scenes, rebuilds
their geometry, and checks each result against the sprites. Its README.md records every verified convention of the format.
rd4.py,primitives.py,freeform_mesh.py,geometry.pyandscene.pyparse the ASCII scenes and build cones, spheres, cylinders, free-form surfaces and deformers.rd4_to_gltf.pyconverts one animated scene into a skinned glTF (gltf.pywrites it), one joint per scene object.scene_render.py,render_cna.pyandverify_sprites.pyrender with the original game camera and compare with the sprite icons by silhouette IoU (intersection over union).export_cna_avatar.pyruns CNA's own converter (tools/avatar_asset_pipeline/convert_avatar.pyin the CNA repository) to write CNA'sSkinnedModelEXTdirectory, then fixes winding and per-part colours and textures.
- Blupi:
match_icons.pyfinds the scene frame each icon ofblupi.pngcame from;build_clip_library.pymakes one clip perBlupiController::AnimState, playing its icon table at 20 frames a second. Command lines are inavatars3d/blupi/README.md. Compare a rebuild clip by clip before replacing anything. - Objects:
tools/rd4_to_gltf/objects.txthas one line per object (sheet, icon range, scenes, options such asyaw=,tone=,min_iou=).build_object_library.pyandexport_objects.pywriteavatars3d/objects/<name>/with itsicons.txtand rewriteindex.txt;calibrate_tone.pysuggests colour tones;procedural_materials.pywritesmaterials.txt. Commands are inavatars3d/objects/README.md. - Special cases:
sign_decals.py,dynamite_sparks.py,electro_sparks.py,top_texture.py,saw_upper_half.py,lower_spheres.py.
These tools need sibling checkouts: the original scenes (speedyblupi-data), Mobile Eggbert's sheets and CNA. Without them
you can still build, play and test the game, but not regenerate models.
Terrain reliefs: tools/terrain_relief/
tiles.txt says which scene belongs to which tile icon (reviewed by eye); match_tiles.py ranks candidate scenes;
build_relief.py keeps each scene's front half, decimates it to about 700 triangles with headless Blender
(blender_decimate.py), cuts it along the cell's edges, textures it with the tile's sprite and writes
avatars3d/terrain/*.gtr and index.txt. reliefs.txt holds per-model options. Tiles without a scene stay textured cubes.
Other generators
| Tool | Writes |
|---|---|
tools/music/render_music.py | Content/music/musicNNN.ogg from the original MIDI (libfluidsynth, ffmpeg) |
tools/bolt/bolt_paths.py | src/GalaxyEggbert/Game/BoltPaths.hpp: the lightning's centre lines from icons 305-307 |
tools/glue/glue_strands.py | src/GalaxyEggbert/Game/GlueStrands.hpp: the glue death's strands |
tools/a3d/a3d.py, lava_surface.py | src/GalaxyEggbert/Game/LavaSurfaceData.hpp: the lava's wave from the original Amapi shapes |
tools/textures/grass_top.py | textures3d/grass_top.png |
tools/DumpBlockDefinitions.cpp | tools/data/blocks.csv for the Python world checkers (VerifyBlockDefinitionsCsv fails when it is stale) |
Inventories: python3 tools/model_parity.py > plans/inventory/model_parity.md, tools/asset_inventory.py
(plans/inventory/assets.md; --check reports a stale file, and on 2026-11-07 it was stale), and the ledgers
plans/audit/asset_sources.csv and render_representation.csv (how each block icon and object is drawn).
Provenance and licences
docs/provenance/ is an inventory with evidence, taken on 2026-11-07; it is not legal advice and decides nothing.
In short:
- The repository is GPLv3 (
LICENSE); this website (web/) carries its own MIT licence. - Sprites, backgrounds, sounds and the five level files are copies of Mobile Eggbert's (MIT); the original game is by Daniel Roux and EPSITEC SA. The repository records no grant from the original's authors for the media as such.
- The models are generated from the original Ray Dream scenes, which the repository labels "GPLv3, © Daniel Roux & EPSITEC SA".
- The music's MIDI source and the soundfont used for rendering are not recorded.
- The fox placeholder's rig and animation are CC BY 4.0 and need attribution (recorded in its README).
- Engine dependencies are sibling checkouts, not vendored: CNA (Ms-PL), cna-engine, easy-gl, sharp-runtime (MIT), SDL3 and SDL3_mixer (zlib).
The open questions are listed in docs/provenance/README.md and licences.md; per-asset detail is in
original-game-material.md, generated-assets.md and third-party.md.