levelbau – level modding kit for The Emperor's New Groove (PC, 2000)

German title: Ein Königreich für ein Lama. PC port by Argonaut, built on the Croc 2 engine.

This kit came out of an AI-assisted reverse-engineering project. It contains:

  • Format documentation for the level files (*.wad): geometry, collision, object placement, textures, waypoints, visibility zones, and what makes the level exit work.
  • Python tools that read, export and rebuild those files byte-exactly.
  • A level builder (tools/levelbuild.py). You describe a level as a short Python script (boxes, ramps, stairs, fences, trees, sea, objects) and it writes a complete, playable WAD.
  • An example level, "Testwelt" (levels/testwelt.py). It goes into the hidden, empty TestLevel slot (world 9, chapter 1) and has its own geometry, a gallery with every object type on pedestals, an animal pen and a small parkour with a working exit.
  • A debug patch generator (tools/debugviz.py). It makes collision visible in every level, including invisible walls, along with invisible trigger and camera objects.
  • An automated in-game tester (tools/lamatest.py). On Linux it runs the game under Wine on a virtual display, loads the test level, takes screenshots and detects crashes.

Nothing from the game itself is included: no game files, no executable, no decompiled code, no built WADs. Every tool works on your own copy of the game.

Most notes in notes/ are written in German. Any AI assistant can read and translate them, and that is the recommended way to use this kit (see the last section).


Requirements

  • Your own copy of the game. Development used the German CD version. Other language versions should use the same format, but this hasn't been tested.
  • Python 3.8+ with numpy and Pillow. Optional: capstone (disassembler helper).
  • For the automated in-game tests only: Linux, Wine, Xvfb, xdotool, ImageMagick, tesseract with German language data, and PulseAudio (pactl).
  • Optional: Blender (preview renders), and Ghidra (to regenerate the decompile, see below).

The builder and the export tools are plain Python, so they should also work on Windows. The test harness is Linux/Wine-only.

Paths – adjust these

The tools were written for one Linux/Wine setup and some paths are hard-coded at the top of the scripts:

Script Variable Meaning
tools/levelbuild.py WADS folder with the original level WADs (the wads folder of the game CD)
tools/levelbuild.py MODWAD where --install puts the built level (T1L9M001.wad)
tools/debugviz.py CD_WADS same as WADS
tools/lamatest.py PREFIX, LAMA_MOD Wine prefix and the overlay script

The game reads its level data from the CD drive, in the wads folder of the CD. To mod it, make a copy of the CD data (or an overlay of symlinks, see tools/lama-mod), point the CD drive or CDPath at that copy, and put modified WADs into its wads folder.


Folder layout

README.md              this file
notes/                 format documentation and findings (German)
  geometry.md          TRAK/MAP geometry, collision polygons, coordinate spaces, zones, limits
  objects.md           MAP chunk layout, strat (object) entries, waypoints, player start, exit
  strat_types_table.md every object type in every original level, with counts
  textures.md          TEXT chunk: texture pages, RLE16, texture table, animations
  levelbau.md          how to use levelbuild.py, measured player physics, exit logic
  testharness.md       the automated Wine/Xvfb tester
  debugviz.md          debug patch: colour legend, what is shown, limits
  img/                 screenshots and preview renders
tools/
  geomlib.py           core library: WAD, TRAK, STPC models, MAP geometry, TEXT, collision
  geom_export.py       WAD -> OBJ/MTL (+ textures, vertex colours, collision.obj, objects.obj)
  geom_import.py       OBJ -> new geometry inside a WAD copy
  mapchunk.py          MAP chunk parser/writer (byte-exact on all original levels)
  strats.py, strat_table.py, stpcwalk.py, map_dump.py   object types and strat code helpers
  textchunk.py, text_export.py, texsheet.py             textures: export/import PNG, contact sheets
  levelbuild.py        the level builder (see notes/levelbau.md)
  debugviz.py          debug patch generator (collision/trigger visualisation)
  lamatest.py          automated in-game test on a virtual display (Linux/Wine)
  lama-mod             shell script: builds a CD overlay with modded WADs (Wine setup)
  vorschau/            Blender preview render scripts
  disx86.py            small disassembler helper for groove.exe (needs capstone)
  wadtool.py           minimal WAD chunk lister/extractor/replacer (used by several tools)
  cor2png.py, png2cor.py  loading/concept pictures (*.COR, LZ-compressed 640x480) <-> PNG
  asf2wav.py           music (*.ASF, 4-bit ADPCM) -> WAV
levels/
  testwelt.py          the example test world
  testwelt_parkour.seq scripted run through the parkour (used with lamatest.py)
  sprunglabor.py       "jump lab": test lanes used to measure jump height/width
re/ghidra_scripts/
  DumpAll.java         Ghidra headless script: decompiles every function to one C file

Quick start

# export a level to OBJ (+ collision and object markers)
python3 tools/geom_export.py /path/to/cd/wads/t1l1m001.wad out_village --collision --objects
#   -> level.obj/.mtl, texture pages, collision.obj, objects.obj, preview images

# build the example test world
python3 tools/levelbuild.py levels/testwelt.py testwelt.wad
python3 tools/levelbuild.py --types               # object types you can place
python3 tools/levelbuild.py --textures tex.png    # texture sheet with the names you can use

# build the debug patch for all levels
python3 tools/debugviz.py --help

Playing the test level

The game has a hidden world 9, TestLevel, with 49 chapter slots, but the retail game ships no data for it. Put your built WAD into the CD's wads folder as T1L9M001.wad. Also add a loading picture T191.COR, for example a copy of another T1xx.COR.

To reach world 9, edit a save file (king0.ksv…king2.ksv, 256 bytes):

  • +0x04/+0x05 = map cursor (world, chapter)
  • +0x3f/+0x40 = current world/chapter
  • +0x42/+0x43 = highest unlocked world/chapter

Set them to world 9, chapter 1.

When you leave through the exit, the game unlocks the next chapter. levelbuild.py --install therefore links chapters 2–49 to the same file, so that picking one on the map doesn't crash.

Debug patch: visible collision and invisible walls

python3 tools/debugviz.py --all debug_wads --src /path/to/cd/wads   # all 33 level WADs
python3 tools/debugviz.py t1l1m001.wad t1l1m001_debug.wad           # a single level
python3 tools/debugviz_check.py debug_wads /path/to/cd/wads         # offline sanity check

Put the resulting WADs into the CD's wads folder in place of the originals, keeping the same file names. On the Wine setup, lama-mod debug an|aus toggles them. The patch only adds render geometry. Collision, objects, waypoints and zones stay byte-identical, so gameplay is unchanged.

Legend (full version in notes/debugviz.md):

Colour Meaning
green / yellow-green wireframe walkable floor / slope
blue wall
orange ceiling / overhang
red, semi-transparent fill invisible collision: invisible walls and floors
magenta lines death plane ("no floor")
violet fill level exit floor (material 16)
other colours special collision materials
Marker Meaning
white arrow player start
violet cube exit
turquoise cube checkpoint
cyan cube camera
yellow cube trigger / cutscene
orange cube force or special zone
gold cube secret zone
grey cube other invisible helper object
pink wire box ambience / music / fog zone

Cubes sit on a stick, and a horizontal line shows the object's facing. Wire boxes show trigger areas.

Status: 19 of 33 levels were loaded in the game without problems. The rest (catacombs/roller coaster world 7, lab world 8, two others) passed the offline check only. Collision of moving objects (platforms, doors) is not shown.


LlamaMod and the level editor

Besides the Python kit, this repository contains LlamaMod (Java 25, Swing; src/), a one-click mod manager for the game on Windows and Linux, and a full 3D level editor built into it. Nothing from the game is included: the wizard installs the game from your own CD/ISO into LlamaMod's data folder, and all mods are built from that copy.

  • Mods – tick mods, click Apply/Play: debug wireframe, Test World, randomizer, fog, mirror mode, intro skip, cheats, practice tools, free camera, boot to level … Mods may change level files and groove.exe (code caves); the original files are never touched. Developer notes: notes/llamamod-app.md, one notes/mod-*.md per mod.
  • Level editor (Level Editor button, or LlamaMod --editor): create new levels from templates, brushes and the base level's tile models and objects, or edit the original levels; import OBJ/glTF meshes and PNG/JPG textures (texture manager, paint-on-faces, animations); waypoints, zones, fog, lights, visibility regions; Play (F5) builds the level and starts the game directly in it (Escape returns to the editor).
  • Sharing: a level is a small .llamalevel file with only your changes. Others import it in LlamaMod (Mods → Levels → Import level) and it is built from their own game copy; new levels appear in the hidden TestLevel world (chapters 1–49).

User guide (English): notes/editor-guide.md. In the editor: Help → Getting started and Help → Shortcut sheet. Technical notes: notes/editor-design.md, editor-api.md, editor-format.md, editor-render.md, editor-ui.md, editor-tools-*.md, editor-playtest.md.

./gradlew build fatJar          # tests + build/libs/llamamod-<ver>-all.jar
./gradlew packageLinux          # build/dist/LlamaMod-<ver>-full-linux-x64.tar.gz (own Java runtime)
./gradlew packageWindows        # build/dist/LlamaMod-<ver>-full-windows-x64.zip (LlamaMod.exe + runtime)
./gradlew packageAll            # both systems, full and launcher (no editor) edition
java -jar build/libs/llamamod-*-all.jar            # LlamaMod
java -jar build/libs/llamamod-*-all.jar --editor   # the level editor alone

The level editor


Key facts

  • The world is made of tiles. TRAK holds about 100–650 small models: render triangles plus collision polygons. MAP places them on a W×H grid (96×96 in the village) with height and rotation. MAP also stores baked vertex colours and a 32-zone visibility table. There is no BSP and no single world mesh.
  • Objects are "strats". These are compiled scripts in the STPC chunk. In MAP, an object's type is simply its byte offset into STPC. A level can therefore only use the object types its own STPC contains. The builder uses the village (t1l1m001) as its base.
  • Coordinates and scale. y points up. Fixed point 20.12 for objects, 4096 = 360° for angles, and render space vs. game space have z mirrored. The llama is about 0.6 units tall, runs about 1.1 units/s, can step up at most about 0.35 and jumps about 1.3 units far with a run-up.
  • The level exit (LevelDoor) is an invisible trigger. It fires only when the llama stands in its grid cell on floor with collision material 16. Its parameters are (tribe, world, chapter) of the next level.
  • Texture pixels are PS1-style 15-bit BGR, RLE16-compressed, on 256×256 pages. The value 0x0000 means transparent.

The parsers rebuild every original WAD byte-for-byte, so they can be trusted as format specs.


Building on this with an AI assistant

This whole kit was made by an AI coding agent (Claude Code) working through the steps below. Any capable assistant that can run code should be able to continue.

  1. Give it the notes first. Ask it to read notes/*.md (they are German; it can translate). They contain offsets, field meanings, confidence levels and pitfalls.
  2. Regenerate the decompile for questions about game logic. Install Ghidra and a full JDK (version 25 for Ghidra 12.x), then run analyzeHeadless <projdir> groove -import groove.exe -scriptPath re/ghidra_scripts -postScript DumpAll.java groove_decomp.c. This writes all functions as C (about 2 MB) for the assistant to search with grep. Loader functions worth knowing: MAP 0x42ac50, TRAK 0x42aac0, STPC 0x42ab50, strat interpreter 0x54d180.
  3. Always test in the game. Have the assistant load and screenshot every build. On Linux, tools/lamatest.py run <wad> <outdir> does this unattended in about 75 s. On Windows, test by hand or adapt the script.
  4. Change one thing at a time and keep the original WADs untouched. The game crashes on inconsistent data: tiles outside the grid, a vertex-colour block that doesn't match the vertex counts, or missing chapters.

Ideas for what to try next

  • Use object types from other levels. You would have to merge and relocate their STPC code and their textures.
  • Import custom textures – done in the level editor (texture manager, import, painting).
  • Make a real visual editor – done: the LlamaMod level editor (see above).
  • Add custom music or sounds (SMPC/AMPC/SRPC are sound banks).

This is a non-commercial fan project, not affiliated with Disney or Argonaut. Please share only tools and your own content, not the game's files.

S
Description
Mod manager and 3D level editor for "The Emperor's New Groove" (PC, 2000): mods, custom levels, object scripts, reverse-engineered formats.
Readme
38 MiB
0 Stars 1 Watchers 0 Forks
2026-11-08 17:40:57 +00:00
Languages
Java 92.8%
Python 6.7%
Shell 0.4%
Assembly 0.1%