Migrating from Photon Fusion¶
You have a Unity game on Photon Fusion 2.1 and you want it on Lattice. This hub is the one place to start. It walks the whole port as a single journey and points you at the tool, the addon, and the three deep guides at each step.
The honest headline
A Fusion → Lattice port is assisted, not automatic. A codemod does the mechanical rewrites and produces a precise to-do list; you do the netcode-shaped parts (spawn model, RPC payloads, input routing, prediction timing) by hand against a clear pattern. Lattice does not hide the hard parts of a port behind a one-click button — it makes them explicit and gives you a recipe for each. Budget real engineering time; you will ship a port you understand.
The journey at a glance¶
flowchart LR
A["① Assess<br/>parity cookbook"] --> B["② Convert<br/>fusion2lattice codemod"]
B --> C["③ Port the hard parts<br/>KCC · physics · collections · input"]
C --> D["④ Check parity<br/>feature-by-feature verdicts"]
D -->|loop on each feature| C
| Step | What you do | Use |
|---|---|---|
| ① Assess | Inventory which Fusion features your game uses and learn each one's Lattice verdict (✅ core / 🧩 addon / 📝 port / ⚠️ gap) before you touch code. | Parity cookbook |
| ② Convert | Run the fusion2lattice codemod over your project. It rewrites the high-confidence Fusion surface and emits a per-file report of everything left to do, bucketed Auto / Review / Manual. |
Migration tool guide |
| ③ Port the hard parts | Work the report's Manual list: the KCC character controller, networked physics, networked collections, and input routing — each with a concrete com.lattice.netcode pattern. |
KCC + physics port |
| ④ Check parity | Confirm each feature has a Lattice home, build a vertical slice, then fan the pattern out. | Parity cookbook |
Start here¶
-
① Assess — parity cookbook
Every Photon Fusion feature, with an honest verdict and a concrete pattern: KCC, scene loading, physics, pooling, animator, input, AoI, lag comp, prediction, matchmaking, host migration, voice. Read this first to size the job.
-
② Convert — the
fusion2latticetool
A Roslyn codemod that rewrites the mechanical Fusion → Lattice surface and reports the rest. Honest about what it does and does not solve, with a full before → after walkthrough on a bundled sample.
-
③ Port — KCC, physics & collections
The deep dive on the hard parts: rebuilding the Fusion KCC as a
CharacterMotor(the codemod's--kcc adapterauto-converts yourKCCProcessors intoIKccProcessors — you finish the collision wiring + feel), the authority-simulate + replicate physics pattern, and bounded replacements for networked collections.
The two pieces that carry the port¶
Beyond the guides, two concrete artifacts do the heavy lifting — know what each is:
-
fusion2lattice— the migration tool (anet8.0console app undertools/fusion2lattice/). It is a Roslyn codemod, not a regex pass: it parses each.csto a syntax tree, rewrites the high-confidence mappings into a separate output tree (your sources are never touched), and writes a per-file report plus aMIGRATION-SUMMARY.md. It mechanically handles ~75–80% of detected constructs and flags the rest — it does not pretend to finish the port. See the migration tool guide. -
CharacterMotor— the addon that replaces the FusionKCC. Shipped in thecom.lattice.netcodeUnity package, it is a rollback-ready motor over a replicatedMotorStatewith an ordered, customizable step pipeline (IMotorStep) — the direct analogue of the KCC processor stack. It also ships a KCC-compat layer (IKccProcessor/KccData/KccProcessorStep) so you can paste a FusionKCCProcessor.Processbody in with minimal edits — and the codemod's--kcc adaptermode (the default) auto-converts yourKCCProcessor/NetworkKCCProcessorclasses intoIKccProcessors for you, mappingKCCDatamembers ontoKccData. The deep design is in the KCC + physics port.
What --kcc adapter does — and where it stops
The fusion2lattice --kcc adapter flag (the default) detects a Fusion KCCProcessor /
NetworkKCCProcessor and rewrites it to a Lattice IKccProcessor: it changes the base type, the
Process signature, and the KCCData.X → data.X member access (Position, Velocity, RealVelocity,
LookYaw, Height, IsGrounded, Crouching, Tick, LastGroundTick, LastJumpTick). It is a scaffold,
not a finished port — collision/sweep calls (kcc.Move / penetration / ICollisionProbe
wiring) and the movement feel are flagged for you to finish by hand. Pass --kcc report to
detect-only (emit KCC as Manual findings) instead.
Host migration is still a gap — plan for it
Host migration has no drop-in equivalent. Run a dedicated/managed authority instead of a player-host, or use the shared-authority "soft continuity" interim pattern. The parity cookbook §15 is blunt about it.
What maps where — the short version¶
A quick orientation before you read the cookbook. Full reasoning and code live behind each link.
| You leaned on (Fusion) | On Lattice it's | Where |
|---|---|---|
KCC + KCCProcessor stack |
🧩 addon + 📝 auto-convert | CharacterMotor + KCC-compat; --kcc adapter |
NetworkRigidbody / NetworkTransform |
🧩 addon | ReplicatedBody / ReplicatedTransform (authority-sim + replicate) |
NetworkMecanimAnimator |
🧩 addon | NetworkAnimator ([Networked] animator params) |
NetworkObjectProvider / pool |
🧩 addon | NetworkObjectPool over Spawn/Despawn |
NetworkArray / Dictionary / LinkedList |
📝 port | bounded POD field / Bytes field / event deltas |
INetworkInput / GetInput |
📝 port | InputRouter (event to authority, mailbox by netid) |
NetworkSceneManagerDefault |
📝 port | load + ready-barrier + proceed event handshake |
| Prediction / rollback / interpolation | ✅ core | core does it — keep your tick deterministic |
| Lag compensation, Area of Interest | ✅ core | core history-rewind + interest management |
| Matchmaking / lobby | ✅ platform | lattice-director |
| Host migration | ⚠️ gap | dedicated-authority interim pattern |
| Voice | ⚠️ third party | Vivox / Dissonance / custom over events |
Recommended order¶
Vertical slice before breadth
Don't port everything at once. Assess with the cookbook, convert with the tool, then
build one vertical slice — a single CharacterMotor (gravity + move + jump), spawned on a
host, predicted on one owning client, transform driven from replicated state. Get prediction
feeling right on that one object, then fan the same pattern out to every other moving thing.
Every later step reuses that shape.
Next steps¶
- ① Assess — parity cookbook
- ② Convert — the
fusion2latticetool - ③ Port — KCC, physics & collections
- The
lattice-gamedevClaude Code skill — teaches an AI assistant the real spawn / RPC / input / authority idioms you'll hand-write while finishing the port. - Getting Started — the underlying register → integrate → host path your ported game lands on.