tutorial_roadmap - ryzom/ryzomcore GitHub Wiki
title: Tutorial Tech Tree description: The complete planned NeL tutorial dependency tree โ branches per engine domain, playable mini-game capstones, conventions, and validation strategy published: true date: 2026-07-05T00:00:00.000Z tags: editor: markdown dateCreated: 2026-03-14T00:00:00.000Z
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.
- One or two new concepts per tutorial. Complete, compilable code at the end of every page.
- Every tutorial includes a screenshot of the final state, at minimum. Visual tutorials should also show intermediate states where a step visibly changes the output; console tutorials show the terminal output. The validation runs produce these automatically (headless capture), so they stay in sync with the code. Screenshots are cropped to the application render area only โ capture the canvas element (or the client area of a native window), never the surrounding HTML page frame, padding, or window decorations.
- Header block on every page: Starts from ยท Assumes ยท Leads to.
-
Reference projects are zipped, not committed. Each tutorial's finished project is archived as a downloadable zip (produced by the validation runs). The mini-game capstones are the exception: they live in the repo under
tutorials/<gamename>/so they stay buildable and playable. - WebGL is first-class. Rendering tutorials are validated both native and as Emscripten builds (headless browser + SwiftShader harness). Full streamed-asset web builds are gated on the asset-loading work (see W2).
-
Assets: Ryzom assets (
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.maxsource assets are reached through the headless.maxpipeline (side-quest 5) rather than by consuming prebuilt data. - Validation: the tree is designed to be walked by a fully autonomous agent session in topological order: unpack the parent zip โ apply the tutorial's steps โ compile โ run โ screenshot/assert โ archive the zip โ refresh the wiki page code. API drift, exporter gaps, and stale service setups get fixed as side-quests during the walk.
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 mesh import tooling (A2/A3/A5): Blender/OBJ โ .shape with a human-readable
.tomlsidecar for NeL material/properties (water flags, specular, lightmap options, collision), matched by instance/object name. Preferred over growing more XML. - nelns / Snowballs service refresh (N4/X2): verify nelns against Ryzom's shard unifier MySQL handling; the Ryzom database setup is canonical; upgrade Snowballs' service usage where stale.
- Web asset streaming (W2): SNP hash-list downloads integrated with the Emscripten build, with proper pipelining over HTTP(S) โ currently sequential-as-needed and slow for many small assets. Planned separately (asset loading review).
- Exporter patch-ups as tutorials exercise features the tools don't cover yet (the water material v15 additions set the precedent).
-
Headless
.maxexport pipeline โ eliminate 3ds Max from the export route. Full codified design, invariants, known defects, and extension rules: Pipeline Max Design. The parser innel/tools/3d/pipeline_maxalready 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 thatplugin_max/nel_mesh_libcurrently 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.maxfiles, 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.