# For developers How the code is organised, how to build and test it, and where the engineering notes are. ## Build Requirements: a **JDK 25** installed (the Gradle toolchain compiles with it; there is no auto-download). Gradle itself and Spotless currently need to run on **Java 21**, e.g. `JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64 ./gradlew …` on Debian/Ubuntu. ```bash ./gradlew spotlessApply build # compile, format, run the tests ./gradlew fatJar # build/libs/llamamod--all.jar java -jar build/libs/llamamod-*-all.jar # launcher java -jar build/libs/llamamod-*-all.jar --editor # the editor alone ./gradlew packageLinux # tar.gz with its own Java runtime ./gradlew packageWindows # zip with LlamaMod.exe + runtime (built on Linux) ./gradlew packageAll # both systems, full and launcher (no editor) edition ``` Details (jlink, launch4j, editions, version and build id): [notes/llamamod-app.md](../notes/llamamod-app.md#build). **Tests that need the game.** Golden and in-game-data tests read the CD folder given by `-Dllamamod.cd=<…/Setup//Cd>` (default: the author's Wine setup); without it they are skipped. Byte-exact round trips over all level WADs (WAD, TRAK, MAP, TEXT, strat code) are the safety net for every format change. ## Code map Package root [`src/main/java/com/eliasmueller/llamamod/`](../src/main/java/com/eliasmueller/llamamod/): | Package | Content | Notes | |---|---|---| | `format` | WAD, TRAK, STPC, MAP, TEXT, collision, COR | [Reference](reference/README.md) | | `format.strat` | strat disassembler, assembler, script view, compiler | [Strats](strats/README.md), [notes/strat-language.md](../notes/strat-language.md) | | `format.stpcmerge` | importing object types between levels (code, models, textures, sounds, texts) | [notes/editor-cross-import.md](../notes/editor-cross-import.md) | | `levelbuild` | Java level builder (`LevelBuilder`, `LevelScript`) | [Levels from scripts](guide/levels-in-code.md) | | `mods` | mod framework (`Mod`, `ModContext`, `ModManager`, options) and the built-in mods | [notes/llamamod-app.md](../notes/llamamod-app.md#mods), `notes/mod-*.md` | | `exe` | patching `groove.exe`: PE image, code caves, a tiny x86 emitter | [notes/llamamod-app.md](../notes/llamamod-app.md#grooveexe-patches-and-code-caves-exeexeimage-exex86) | | `platform` | install from ISO/CD, data folder, config, registry, Wine/Windows launch | [notes/llamamod-app.md](../notes/llamamod-app.md) | | `save` | KSV save games, TestLevel chapters | [Game files](reference/game-files.md#save-games-ksv) | | `ui` | launcher window | | | `editor.model`, `editor.io` | scene model, commands/undo, project format, WAD import/build | [notes/editor-api.md](../notes/editor-api.md), [notes/editor-format.md](../notes/editor-format.md) | | `editor.render` | OpenGL viewport | [notes/editor-render.md](../notes/editor-render.md) | | `editor.ui` | editor shell and plugin API | [notes/editor-ui.md](../notes/editor-ui.md) | | `editor.tools.*` | editor plugins: geometry, objects, environment, textures, catalog (cross-world import), strats, playtest, gltf, help | `notes/editor-tools-*.md`, [notes/editor-playtest.md](../notes/editor-playtest.md) | ## Writing a mod A mod implements [`Mod`](../src/main/java/com/eliasmueller/llamamod/mods/Mod.java): `id`, `name`, `description`, `category` (LEVELS, GAMEPLAY, VISUAL, CHEATS), `options()` and `apply(ModContext)`. `apply` reads files of the game as earlier mods left them (`ctx.read`) and writes replacements (`ctx.write`); `ctx.exe()` gives access to `groove.exe` for patches. Mods are registered in [`ModRegistry`](../src/main/java/com/eliasmueller/llamamod/mods/ModRegistry.java). LlamaMod caches mod outputs and never touches the original files. Good examples: [`mods/testworld/`](../src/main/java/com/eliasmueller/llamamod/mods/testworld/) (a level built in code), [`mods/arena/`](../src/main/java/com/eliasmueller/llamamod/mods/arena/) (level + new strat types, walkthrough: [Arena](strats/arena.md)), [`mods/fog/`](../src/main/java/com/eliasmueller/llamamod/mods/fog/) (data-only change of all levels), [`mods/practice/`](../src/main/java/com/eliasmueller/llamamod/mods/practice/) (exe code caves with hotkeys). Full API: [notes/llamamod-app.md](../notes/llamamod-app.md#writing-a-mod). Every mod should be checked in the running game; [`tools/apptest.py`](../tools/apptest.py) does this unattended on Linux ([Tools](tools.md#testing-in-the-game)). ## The editor manual [`docs/manual/`](manual/index.md) is the editor's user manual **and** its built-in help: the build bundles the folder into the jar (`processResources` in `build.gradle`), the Help window renders it with its own small Markdown converter, and F1 maps editor topics to chapter anchors (`editor/tools/help/context-help.txt`). Rules for that folder: * Only the Markdown subset described at the top of `index.md`; every chapter must be linked from `index.md`; links must stay **inside** `docs/manual` (the help window cannot open other files). * Blocks between `generated:NAME` comments (shortcuts, menus, mod reference) are rewritten from the live program by `ManualTest` – do not edit them by hand. * `./gradlew test --tests '*ManualTest*'` checks links, anchors and images. Maintenance notes: [notes/editor-manual.md](../notes/editor-manual.md). ## Engineering notes [`notes/`](../notes/README.md) is the project's lab notebook: one file per format, editor area and mod, with addresses in `groove.exe`, confidence levels, what was verified in the game and known limits. Process material (agent briefs, review reports) is in [`notes/dev/`](../notes/dev/).