MCCF: S1000D Applied to MCCF
Watch the MCCF demo
A short video of the Multi-Channel Coherence Field working in an X3D scene. Watch it on YouTube.
7 November 2026. How MCCF borrows from S1000D, where it shows up in our files, and why it helps both the people and the language model that work on the documentation.
MCCF is a system for building X3D scenes where characters have emotional state, music follows the scene, and an AI can take a part beside the humans. That is a lot of moving parts. The documentation has to keep pace with software that changes every week, and it has to be usable by a person at a keyboard and by a language model that reads, drafts and checks it. We solved that the way the aircraft and defence industries solved it for much bigger machines: we borrowed from S1000D, the international specification for technical publications.
The idea in one line: write small pieces, give each piece an address that never changes, and let everything else point at the address.
1. What S1000D is, in a paragraph
S1000D breaks a manual into data modules. Each module covers one topic: how a part works, or how to do one task. Each has a code that names it and an issue number that says which version it is. Modules live in a common store, the CSDB (common source database). A publication is not a document you write once. It is a list of modules that is assembled into a manual, a web page or a training course. Change a module and every publication that uses it changes with it.
We do not claim to follow the full specification. We took the parts that pay for themselves in a small project, and we say so in the Guide: stay as close as practical.
2. The code, field by field
A data module code in MCCF looks like this:
MCCF-A-20-06-00-00A-040A-D
| Part | Meaning in MCCF |
|---|---|
MCCF | The issuer. MCCF for the project's own material. An author who adds a module uses their own three to five letters, so two authors can never issue the same code and there is no central office to ask. |
A | The kind of thing. A is a User's Guide module, P a Programmed Instruction lesson, E an effect assembly. |
20-06 | Where it sits. In the Guide the first number is the group (00 front matter, 20 the tools, 90 the appendices) and the second is the chapter. For effect assemblies the first number is the category (10 timing and triggers, 20 camera, 30 light, 40 audio, 50 movement, 90 other) and the second is a serial number. |
00-00A | Fixed. We do not use the finer levels yet. |
040A or 520A | The information code. 040 is a description: what a thing is and how it behaves. 520 is our one procedural code: do these steps. It comes from the procedure range of the standard and is used here as the project's own choice. We chose to use just two. |
D | Fixed. |
Two rules keep the codes useful. The author is the sole authority for the codes, and a code is never reused or renumbered. A retired module stays retired. That is why anything that points at a code can be trusted years later. We also decided that codes are assigned last, as the final step before publishing, so the structure is not locked in while the content is still moving.
3. Where it lives in our files
The codes are not only in the manual. They are in the working files, which is the point.
The Scene XML. The scene root can carry the scene's own data module code, and the server's scene registry reports it beside the audio, MIDI and project files the scene uses. A scene is a description module (040A). The schema documents it:
<Scene xmlns="http://mccf.artistinprocess.com/v1" id="GettingStarted"
dm="MCCF-P-10-01-00-00A-040A-D" ...>
Effect assemblies. When an author saves a reusable effect (a camera move, a light cue, a sound trigger), the server issues the next code in that category from a registry file and writes it into the X3D head. The registry records the code, file, title, issuer, date and status, and a retired code is never issued again:
<meta name="dmCode" content="MCCF-E-20-01-00-00A-040A-D"/> <meta name="issuer" content="MCCF"/>
The Programmed Instruction schema. Our teaching lessons are XML files, and the schema has a type that checks the shape of a code. A lesson has its own code (520A, procedural), names the scene it uses by code (040A), and every frame can point at the Guide module that explains it:
<Meta><DmCode>MCCF-P-10-01-00-00A-520A-D</DmCode> ... </Meta> <Scene dmCode="MCCF-P-10-01-00-00A-040A-D" issue="001" file="GettingStarted_M1.x3d"/> <Step id="f3" title="Scene Setup"> ... <Guide dmCode="MCCF-A-20-06-00-00A-040A-D" title="6. Scene Composer, Scene tab" section="scene-tab"/> </Step>
The code is also the file name. A lesson is saved as MCCF-P-10-01-00-00A-520A-D.xml, its performance log is kept in pi_logs/MCCF-P-10-01-00-00A-520A-D.jsonl, and the Guide link on each frame points at guide/<code>.pdf with the section as an anchor. Nobody has to remember where anything is: the name is the address.
The Guide itself. Every chapter opens with its code, title, date and issue, and ends with a provenance line that says where the text came from (for example, drafted from the Scene Composer page, screenshots from a specific build). The final layout will put the code at the head of every page and the provenance and page number in the footer.
4. One module, many publications
The most useful S1000D idea for us is that a publication is a list. The same modules are meant to feed the Guide, a short overview, a workshop handout and the Getting Started lessons. Getting Started is a second manifest over the same modules, not a second copy of the text. A correction in one place reaches all of them. Screenshots follow the same rule: they are named by module so the Guide and the lesson use the same file.
5. Structure that does not wander
S1000D also gives a way of working. Each control in the Guide is described in the same fixed structure, one topic per module. Procedures say what to do and what you should see, so a step ends with something the learner can check. Cautions and warnings have a place of their own and plain wording. The Export tab, for example, opens with a caution that X3D is a final rendering and cannot be edited back, and the scene XML must be saved to edit later. Troubleshooting entries must state their remedy or point to a deeper procedure. We kept the structure and let ourselves add some colour and humour to the presentation, because the safety and accuracy text stays plain either way.
6. Why it helps a person
- You can find things. A code is a stable name. A support note, a lesson frame and a bug report can all say "see MCCF-A-20-06" and mean the same thing.
- Small pieces are easier to keep true. A module with one topic can be checked against the software in one sitting. Each carries an issue and a date.
- Nothing is memorized. A file named by its code needs no map of folders.
- Learning is built in. Because the lesson points at the Guide and the Guide points at the page, a learner who is stuck is sent to exactly one place.
7. Why it helps the language model
This is the part we did not expect to matter as much as it does. A language model working on documentation has a short memory and no map of the project. It can lose its place in a long document, and it can state something confidently that was true three weeks ago. The structure gives it what it needs.
- An address to hold. A code is a precise handle. Instead of "the section about the scene tab", the model works with one module, reads it, changes it and leaves the rest alone.
- Small, self-contained context. A module is the right size to load whole. The model can read the module and the code that implements it together.
- A fixed shape to check against. Because every control is described the same way, a missing field is easy to see, and a lesson's expected results can be written as machine-checkable tests. Our lessons carry XPath checks against the learner's saved scene XML, so the system can mark an answer right or wrong without a human reading the file.
- Provenance. The line at the end of a module says what it was drafted from. A model, or a person, can see what to re-check when the source changes.
- Hand-offs that survive. A new session can pick up with a list of codes, registry entries and open items rather than a long conversation to reread. We have already lived this: several times a session has ended mid-task and the next one continued from the register and the codes.
- Honest limits. The registry is the authority. When a code or a reference does not resolve, that is a visible error, not a quiet guess. We found one in a lesson link this week, an appendix cited with the wrong information code, because the references are explicit enough to check.
8. Speculation: assets we do not control
Everything from here to the next heading is a forecast, not a feature. None of it is built.
A real world is not made only of what we author. Avatars come from Mixamo or a scanning service. Models, textures and sounds come from public libraries. Another author's effect assemblies arrive as files. Each of these can change or vanish at its source, or carry a licence we must honour, and none of them follows our naming. The danger is a scene that works today and fails quietly in a year because something upstream moved.
S1000D has an old answer to this problem: you do not edit the part you bought, you write a module about it. We could do the same.
- A wrapper module for every foreign asset. The foreign file stays untouched. We issue a description module (040A) under our own code that records where it came from, its licence and the attribution it requires, the date we fetched it, a checksum, what it contains (units, skeleton level, formats) and what we changed when we imported it. The scene refers to our code. The foreign filename is only a detail inside it.
- Issues instead of surprises. If the source publishes a new version, we do not overwrite. We fetch it, test it, and issue the next version of the wrapper. A scene can say which issue it was built and tested against, so "it worked on issue 002" is a statement we can check. A bad upstream change cannot slip in unseen.
- No collisions. The issuer part of the code is the reason this scales. A studio that brings its own library uses its own letters, and its modules sit beside ours without a central office to ask. Two things can have the same name in the wild and still never share a code.
- Applicability. S1000D lets a module say which products it applies to. For us that could say which scenes, which MCCF versions, or which avatar skeletons an asset is good for. A model that only works with a given H-Anim level would say so in its wrapper, and a check could refuse the mismatch before a learner meets it.
- Business rules that can be run. The standard has a notion of project rules checked by machine. Ours are short and already written: every dimension in metres, effects carry a code and issuer, scenes use a stated navigation type. An import step could test a foreign asset against those rules and write the result into its wrapper, for example "authored in centimetres, scaled by 0.01."
- A catalogue. The registry that issues our effect codes could grow into a catalogue of every outside asset in use, with its status: active, under review, retired. Retired codes stay retired, so an old scene still tells you exactly what it used.
For the language model the wrapper matters most of all. A foreign file is untrusted. Text inside a downloaded model, its comments, its metadata, should be treated as data and never as instructions. A wrapper is our own statement, written and reviewed by us, so the model reads the wrapper, which is trusted, and treats the asset behind it as a sealed part. It is the same discipline a maintenance crew applies to a part from another supplier: you trust the paperwork you wrote, not the label on the box.
9. Speculation: one address space for web and worlds
Again, a forecast and not a feature.
A web page and a 3D world are usually separate things with separate links. A data module code gives them a shared language, because a code points at a thing and not at a place.
- Links that cross the boundary. A page could refer to a world object by code, and a world object could carry the code of the module that explains it. We already do the second half: effect assemblies carry their code in the X3D head, and a lesson frame points from the scene to the Guide. Click a fountain in a world and you could land on its description module. Follow a Guide link and you could land standing next to the fountain.
- One source, several faces. A publication is a list of modules, so the same modules can be assembled as a printed guide, a website, a guided walk through a world, or a lesson. Our Programmed Instruction player already does one of these: it is the Guide's modules replayed as a course. A site and a world could be two more manifests over the same text.
- Federation without a centre. Because an issuer code needs no registrar, projects could publish their modules on their own servers and refer to each other's codes, much as sites refer to each other's addresses. A resolver, something as simple as a rule that turns a code into a file location, would make a code clickable anywhere. One world could cite a lighting rig from another and carry its wrapper along.
- A bill of materials for a world. Every scene already lists the audio, MIDI and project files it uses. Extended to codes, it becomes a parts list: this world is these modules at these issues. You could rebuild it, check it, hand it to someone else, or ask which worlds a changed asset touches.
- Service bulletins. Fleets of aircraft are kept in step by notices that say which parts to check. A worlds project could do the same. Retire an asset and every scene that cites it is flagged, with the module that replaces it.
- Agents that can cite. A character driven by a language model could answer a visitor from a module, saying which module and which issue, instead of from a vague memory. A question in the world becomes a lookup, and the answer can be checked.
Cautions, honestly. S1000D is heavy, and a small project that adopts all of it will drown in paperwork. Our approach has been to take only what pays for itself, and a federated scheme would need the same restraint. Foreign libraries have their own identifiers and will not adopt ours, so a thin mapping layer would carry the load. Wrappers go stale if nobody maintains them. And all of this rests on people actually issuing codes and keeping them honest. The idea holds together on paper. Whether it holds up on a real project with a dozen authors is the experiment.
10. What is built, and what is not
Built today: the code format and its validation in the Programmed Instruction schema; the scene code attribute and the scene registry; the effect-assembly registry that issues and retires codes; lessons, logs and Guide links keyed by code; and the Guide's chapter codes, headers and provenance lines.
Not yet: the Guide built to one PDF per module under the code names the lessons link to; the finer levels of the code (we hold them at fixed values); a published CSDB. The code, the manuals and the registry will go to GitHub once the manuals are final.
Where it stands
S1000D is a heavy specification, and we use a light slice of it. That slice is the part that makes a documentation project with several humans and an AI behave: small modules, permanent addresses, one source feeding many publications, and structure that can be checked. The result is a manual that is easier to keep correct, and a body of work that the next person, or the next session, can pick up without starting over.

Comments
Post a Comment