The NeL tutorials form a tech tree: a dependency graph rather than a single sequence. Each tutorial names exactly one starts-from parent — the tutorial whose finished code is your starting point — plus any assumes parents whose concepts are referenced but not built upon. Completed tutorials are linked from the tutorials index; this page is the master plan and status tracker.
Legend: ✅ written · 🔨 planned · ⚠ has an engine/tooling side-quest that must be resolved while writing it · 🧱 gated on the asset-tooling side-quests (cannot be built with what loads today).
Buildable today: everything not marked 🧱 runs on assets that already work — procedural content generated in code, loose files from a ryzomcore_graphics checkout (CPath search paths + extension remapping, the pattern the water demo uses), or prebuilt Snowballs/Ryzom game data (landscape zones, collision banks, sound banks). No asset build pipeline or new load management is required for that subset. The 🧱 set is exactly: A2, A3, A5 (TOML sidecar importer), X1 (through its A2 dependency), and W2 (web asset streaming).
Prebuilt data is a bootstrap, not the asset story. Tutorials must not normalize skipping the build pipeline — relying on shipped data sets a pipeline-avoidance precedent, and it hard-blocks anything whose source assets only exist as 3ds Max files. The way out is the headless .max export pipeline (side-quest 5 below): the existing partial .max parser, extended until the 3ds Max dependency is eliminated from the export route entirely. Until that lands, prebuilt data is acceptable scaffolding; every tutorial that uses it should treat the data as a placeholder for assets built from source.
tutorials/<gamename>/ so they stay buildable and playable.ryzomcore_graphics), procedural geometry built in code, and OpenGameArt (license noted per asset). Mesh export via the existing 3ds Max plugin, and — to be built during the implementation rounds — a Blender/OBJ route with a TOML sidecar carrying NeL material/properties metadata, matched to objects by instance name (human-readable, replacing the XML habit for this use case). Ryzom's own .max source assets are reached through the headless .max pipeline (side-quest 5) rather than by consuming prebuilt data.Everyone passes through here.
| Id | Tutorial | Starts from | Status |
|---|---|---|---|
| T1 | Compile NeL — Windows / Linux | — | ✅ |
| T2 | Set up a new personal project | T1 | ✅ |
| T3 | Write a main game loop | T2 | ✅ |
| T4 | Hello World — driver, window, text | T3 | ✅ |
Forks from the trunk before the 3D chain — these are windowless programs, and later branches assume them.
| Id | Tutorial | Starts from | Assumes | Status |
|---|---|---|---|---|
| I1 | Config files & search paths — CConfigFile, CPath |
T3 | 🔨 | |
| I2 | Logging & debugging — displayers, filters, asserts, reports | T3 | 🔨 | |
| I3 | Serialization — IStream, CIFile/COFile, versioning |
T3 | I2 | 🔨 |
| I4 | Console commands & variables — NLMISC_COMMAND, ICommand |
T4 | I2 | 🔨 |
| I5 | Georges data sheets — .typ/.dfn/forms, UFormLoader |
I1 | I3 | 🔨 |
| I6 | Packed sheets — compiling sheets for fast startup | I5 | 🔨 | |
| I7 | Localization — .uxt, CI18N |
I1 | 🔨 | |
| I8 | Threads & async tasks — IThread, CTaskManager |
T4 | I2 | 🔨 |
| I9 | BNP/SNP packaging & streamed packages | I1 | 🔨 ⚠ ties into the web asset story (W2) |
| Id | Tutorial | Starts from | Assumes | Status |
|---|---|---|---|---|
| D1 | Primitives & camera | T4 | ✅ | |
| D2 | Textures & alpha blending | D1 | ✅ | |
| D3 | Scene & shapes | D2 | ✅ | |
| D4 | Scene lighting | D3 | ✅ | |
| D5 | Animation playback | D4 | ✅ | |
| D6 | Particle systems | D5 | ✅ | |
| D7 | Render targets & post effects — RT, fullscreen passes | D2 | 🔨 ref: planar_reflection sample |
|
| D8 | Water surfaces — runtime CWaterShape, envmap water |
D3 | I1 | 🔨 ref: nl_sample_water procedural pools |
| D9 | Planar reflections & replicated render passes — pass API, IStereoDisplay loop |
D8 | D7 | 🔨 ref: nl_sample_water |
| D10 | Instance groups & scenery — village/IG loading | D3 | I1 | 🔨 |
| D11 | Landscape rendering — .zonel, tile banks | D3 | I1 | 🔨 uses prebuilt Snowballs/Ryzom landscape data |
| D12 | Vegetation & micro-vegetation | D11 | 🔨 | |
| D13 | Clusters & portals — indoor culling | D10 | 🔨 | |
| D14 | Character crowds & CLod impostors | D5 | 🔨 optional | |
| D15 | Sky, weather & day-night cycle | D4 | D11 | 🔨 optional |
| Id | Tutorial | Starts from | Assumes | Status |
|---|---|---|---|---|
| A1 | Asset formats & data flow — .shape/.skel/.anim/.ps, search paths, BNP | D3 | I1 | 🔨 |
| A2 | Static mesh from Blender/OBJ — TOML sidecar for NeL material/properties, matched by instance name | A1 | 🔨 ⚠ 🧱 importer tooling to build | |
| A3 | NeL material properties in depth — specular, lightmaps, water flags, the sidecar schema | A2 | 🔨 ⚠ 🧱 sidecar schema grows here | |
| A4 | The .max export route |
A1 | 🔨 plugin docs exist; to be written against the headless .max pipeline (side-quest 5), with the 3ds Max plugin as the legacy reference |
|
| A5 | Skeletons & animation export | A2 | D5 | 🔨 ⚠ 🧱 sidecar extension |
| A6 | Authoring particle systems — Object Viewer / OVQT editor | D6 | 🔨 | |
| A7 | Sourcing assets — Ryzom data, OpenGameArt, licensing | A1 | 🔨 |
| Id | Tutorial | Starts from | Assumes | Status |
|---|---|---|---|---|
| S1 | Playing sounds — UAudioMixer, sample banks, USource |
T4 | I1 | 🔨 uses existing packed sound data |
| S2 | 3D audio in the scene — positioning, listener | D3 | S1 | 🔨 |
| S3 | Music & ambience — groups, volume controllers | S1 | 🔨 | |
| S4 | Sound sheets & banks | S1 | I5, I6 | 🔨 |
| Id | Tutorial | Starts from | Assumes | Status |
|---|---|---|---|---|
| N1 | Messages & callbacks — two-program chat (layer 3) | T3 | 🔨 ref: nel/samples/net/chat |
|
| N2 | Building a service — IService, naming service |
N1 | I1 | 🔨 |
| N3 | Unified services — layer 5, service-to-service | N2 | 🔨 | |
| N4 | Running a mini shard — naming/login/welcome + MySQL | N3 | 🔨 ⚠ nelns/Snowballs service setup vs Ryzom's shard unifier is out of sync; the Ryzom database setup is canonical — verify and upgrade nelns while writing this | |
| N5 | Networked scene — position sync between clients | D3 | N2 | 🔨 |
| Id | Tutorial | Starts from | Assumes | Status |
|---|---|---|---|---|
| P1 | PACS primitives — UMoveContainer, move & collide, headless |
T4 | 🔨 | |
| P2 | Collision in the scene — visualized primitives | D3 | P1 | 🔨 |
| P3 | Character controller — walking, sliding, follow camera | P2 | D5 | 🔨 |
| P4 | Landscape collision — .rbank/.gr, UGlobalRetriever, ground snap |
P3 | D11 | 🔨 uses prebuilt collision banks |
| Id | Tutorial | Starts from | Assumes | Status |
|---|---|---|---|---|
| G1 | Interface XML & action handlers | D2 | I1 | 🔨 |
| G2 | Lua-scripted UI | G1 | 🔨 | |
| G3 | Game HUD & menus | G1 | 🔨 |
| Id | Tutorial | Starts from | Assumes | Status |
|---|---|---|---|---|
| W1 | Building for the browser — toolchain, ports, preloaded data | D3 | 🔨 | |
| W2 | Streamed web assets — SNP over HTTP(S) | W1 | I9 | 🔨 ⚠ 🧱 blocked on engine work: SNP hash-list streaming is not integrated with the Emscripten build and isn't pipelined (slow for many small assets) — see the asset loading review |
| W3 | Publishing a browser demo — HTML shell, input caveats, control panels | W1 | 🔨 ref: the water demo's panel pattern |
Endpoints of the tree — real, playable games, committed in the repo under tutorials/<gamename>/. Each is also a validation vehicle for its branch joins.
| Id | Game | Starts from | Assumes | Notes |
|---|---|---|---|---|
| X0 | Paddle — breakout/pong-class micro-game, procedural assets | D2 | I1, T4 | Early payoff checkpoint: loop, input, text, 2D draw. Cheap to validate. |
| X1 | Rolling ball — MTP-Target / Monkey Ball class arcade game: ball on tilting course meshes, follow camera, checkpoints, timer | P2 | D4, S1, G3, A2, X0 | 🧱 Levels exported through the Blender/TOML sidecar route (exercises A2/A3); procedural + OpenGameArt assets. (Could start with fully procedural courses to decouple from A2 if the tooling lags.) Optional later round: multiplayer via N5, honoring the MTP-Target lineage. |
| X2 | Snowballs-class mini world — third-person character on a landscape, snowball combat, multiplayer shard | P4 | D10, D13, N4, N5, S2, G3, A7 | Ryzom/Snowballs assets. The nelns/shard-unifier/MySQL verification vehicle (see N4). WebGL target once W2 lands. |
Future candidate bucket (unscheduled): kart race on landscape, tower defense with particle weapons, fishing game on reflective water (D9 showcase).
Work items expected to surface while an autonomous session walks the tree, tracked here so they're scoped deliberately rather than discovered painfully:
.toml sidecar for NeL material/properties (water flags, specular, lightmap options, collision), matched by instance/object name. Preferred over growing more XML..max export pipeline — eliminate 3ds Max from the export route. Full codified design, invariants, known defects, and extension rules: Pipeline Max Design. The parser in nel/tools/3d/pipeline_max already handles the OLE compound container, the chunk storage layer, the DLL/class directories, and typed scene classes for the builtin, update1 (editable mesh), and epoly plugins — nodes, tri/poly/patch objects, standard and multi-materials, bitmap textures, param blocks 1/2, and the NeL AppData export properties. Its storage design is strict about fidelity: serialized data is parsed into typed form and written back so that unknown or untouched chunks remain byte-identical, which is what makes safe incremental extension possible. Missing is the back half — the export logic that plugin_max/nel_mesh_lib currently runs against the live 3ds Max SDK, re-targeted at the parsed scene. Validation is snapshot-based and exhaustive, and is itself well-suited to an autonomous session: the graphics source tree holds ~8,600 .max files, and the Ryzom Core data set is the exported reference — every source file must roundtrip cleanly through the parser (byte-identical rewrite), and pipeline output is diffed against the corresponding prebuilt reference data. Landing this unblocks every Max-export-dependent asset (and, in a later stage, the ligo/zone land export route), which is what retires the prebuilt-data scaffolding for good.Branch-parallel, cheapest-payoff first: Infrastructure (I1–I4) and X0 → Sound S1/S3 and Network N1–N3 → Asset A1/A2 (tooling side-quest) → PACS P1–P3 → X1 → GUI G1/G3 → Landscape D10–D13 and P4 → N4 (nelns side-quest) → X2 → Water/RT D7–D9 and Web W1/W3 → W2 when the asset work lands.
The headless .max pipeline (side-quest 5) runs in parallel with the whole schedule — its roundtrip/snapshot test suite is independent of any tutorial and can start immediately; tutorials that bootstrapped on prebuilt data get their assets re-sourced through the pipeline as it matures.