Migrating from ChatMapper Desktop
This section is for studios that already use the Windows ChatMapper Desktop app
— typically writers authoring .cmp projects, exporting XML, and a Unity or
custom importer consuming it.
The headline: your engine importer does not need to change. ChatMapper Cloud writes the same XML and the same JSON. What changes is where the file lives, who can edit it at the same time, and how much you find out before the build.
1. Get the projects in
Section titled “1. Get the projects in”Import in the toolbar reads all of it:
| File | Notes |
|---|---|
.cmp | Decrypted server-side. Nobody needs a Desktop install to open one. |
.cmpkg | The zipped variant. |
.xml | Desktop XML save/export. |
.json | Canonical JSON. |
Conversations, nodes, links, actors, items, locations, variables, custom fields, conditions, user scripts, node colours, localisation, reviewer notes and emphasis settings all survive.
The decryption is a full reimplementation (AES-256-CBC around a .NET
BinaryFormatter object graph), verified across both file versions in
circulation. If you have an archive of old projects, they open.
2. What is bit-compatible
Section titled “2. What is bit-compatible”- XML export is round-trip tested. Every fixture is exported to XML,
re-imported through the Python importer, and asserted deep-equal on nodes,
links, colours, field values,
DoExportfiltering and emphasis. Field order and element names follow what the Desktop serializer emits. - Custom field types and the
DoExportflag are honoured — a field marked not-for-export is filtered out of the XML exactly as Desktop does. - Lua is unchanged: same
Variable["name"]access, same name-cleaning rules, sameSimStatusvalues. - Inline markup is unchanged:
|,[em1]…[/em1],[var=Name],[pic=N]/[pica=N]/[picc=N],[f],[a], and the input prompt in both the Desktop[input=?Name]form and the bare[?Name]form.
Two caveats to note before you delete the Desktop install:
- The round trip is verified against the project’s own XML importer (itself
built from real Desktop XML), not against the Desktop
XmlSerializerbinary. Do one manual open-in-Desktop check with a real project. - The XML attribute is genuinely spelled
FalseCondtionAction. The typo is part of the format; do not “fix” it in your importer.
3. What changed in the editing model
Section titled “3. What changed in the editing model”No files
Section titled “No files”Projects live in a workspace and autosave. History replaces save-a-copy-before-I-experiment: every save snapshots a revision you can diff and restore. Concurrent edits raise an explicit conflict banner (Discard mine & reload / Overwrite with mine) rather than last-write-wins. Save As is now cloning the project from the project list.
Roles are Owner / Admin / Editor / Viewer, and Viewer is a genuinely read-only editor — the right permission for a reviewer or a producer.
Menu mapping
Section titled “Menu mapping”| Desktop | ChatMapper Cloud |
|---|---|
| File → Export XML / CMPKG | Export ▾ (plus JSON, Unity preset, Yarn, HTML player, SCORM/xAPI, CSVs, RTF, SVG) |
| Tools → Simulate (F5) | ▶ Simulate |
| Tools → Check Errors | Validate — and it runs continuously |
| Find / Replace | Ctrl+F / Ctrl+H, project-wide, with Replace All |
| Overview window | Always-on minimap |
| Collapse / Expand All | Layout ▾ |
| MindFusion tree layout | Layout ▾ → direction, auto-arrange, structured layout lock |
| Project preferences → custom asset fields | Sidebar → field templates, per-field type and export flag |
Keyboard tree building is preserved: Tab child, Enter sibling, Home root, arrows to move, Ctrl+↑/↓ to reorder siblings.
What the web adds
Section titled “What the web adds”- Deeper validation: duplicate IDs, unreachable nodes, orphan and broken
links, undefined variables, cross-conversation link integrity, spoken lines
with no actor — plus a Unity preflight that catches Lua key collisions,
missing
Is Item,|inside bracketed tags, cross-project links and unparseable conditions before they reach your importer. - Simulator step history and a Lua console — walk a run backwards and forwards, branch differently from any step, evaluate and assign variables against live state.
- Real-time collaboration: presence, roles, reviewer notes with review status and a CSV export for review meetings.
- Insert-between: select a link and splice a node into it.
- Inline canvas text editing and structured auto-layout.
- Real media storage: attachments are uploaded and content-addressed instead
of referencing paths on one writer’s PC — which is what makes the
.cmpkgexport actually portable. - New export targets you did not have: Yarn Spinner, a standalone HTML player, SCORM 1.2 / xAPI, voiceover and proofreading sheets, RTF screenplay, conversation SVG.
- New import sources: CSV/Excel, Twine, Arcweave and articy:draft X — useful when you acquire a project written in something else.
Still Desktop-only
Section titled “Still Desktop-only”- Encrypted
.cmpexport. Import works; export is XML or CMPKG + media (project XML + JSON + media files, zipped). There is no.cmp-native round trip. - Conversation
LockedMode— not modelled; exported XML always saysUnlocked. - File links from a node to an external
.cmp. - Promote to primary link — no primary/secondary link concept on the web.
- Reparent by dragging onto a new parent — delete and recreate the link.
- Audio File Placer (bulk audio assignment).
- Excel import/export of per-asset worksheets — the CSV exports open in Excel in the meantime.
- Sort assets by field, Cut, Select All, Conditions/Scripts snippet
menus, Word count report, Yack
.dls/.dlaexport.
Also gone, deliberately, are the Desktop-platform concepts with no web analog: local file dialogs, Windows metafiles, licensing/keygen, the embedded localhost server and publish-to-cloud.
4. Keeping your Unity pipeline
Section titled “4. Keeping your Unity pipeline”Nothing changes on the Unity side: Pixel Crushers Dialogue System still imports ChatMapper XML via Tools → Pixel Crushers → Dialogue System → Import → Chat Mapper.
What you should change is which export you hand it. Use Unity — Dialogue System XML: identical bytes to the plain XML export, plus a preflight that reports
- assets whose names clean to the same Lua key (error — Dialogue System keys its tables by cleaned name and the second silently overwrites the first),
- assets with no
Name, - Items missing
Is Item(ChatMapper keeps items and quests in one collection), |inside a bracketed tag (Dialogue System splits lines on|),- links to another project file (unsupported — one combined database),
- conditions that do not parse as the supported Lua subset,
- a count of dialogue nodes with no
Sequencefield.
Apply the “Unity — Dialogue System” custom field template once, and
Sequence / Response Menu Sequence / Is Item appear for your writers on
every relevant asset from then on.
5. Keeping a custom importer
Section titled “5. Keeping a custom importer”If you wrote your own parser against Desktop XML or JSON, it keeps working. Two things are worth revisiting while you migrate:
- Read variables by name. If your code keyed them by
ID, XML round trips will have been quietly breaking it already —<UserVariable>has noID. - Preserve unknown fields. The additive-extension rule is what lets the
editor add features without breaking you; the reciprocal obligation is not
dropping fields you do not recognise.
_editoris the one exception — it is editor-only, stripped from exports, and safe to ignore entirely.
The repo ships docs/format/chatmapper-json.md as the normative format spec,
plus a dependency-free MIT-licensed reference-parser.ts and a fictional
example-scenario.json kept honest by a test. If you are about to rewrite an
importer, start from those.
6. A sensible migration order
Section titled “6. A sensible migration order”- Import one real, finished project. Validate it and read every warning — many will be pre-existing problems Desktop never told you about.
- Export XML and open it in Desktop ChatMapper. Confirm the graph is intact. Do this once, on real content, before trusting the round trip.
- Export Unity — Dialogue System XML, clear the preflight, and import it in Unity. Play one conversation.
- Set up the workspace properly: teams, roles, a custom field template for your engine’s fields.
- Move the writers over. Give them the working example and the new-to-ChatMapper section — most of what they need is the same tree they already know.
- Keep one Desktop install around until the gaps in §3 stop mattering to you.
- Start here — new to ChatMapper — the data model, traversal semantics and Lua host API in full.
- LearnBrite authors manual — if these scenarios also need to run in a 3D space.