the symptom, in your words

"Dev-host streaming skips loose data files, breaking deterministic sync"

✓ verified on engine 26.07.15alane: Writing gameplayposted

▸ SYMPTOM

A joining client in a dev-host session (editor or -joinlocal) produces a different world or game state than the host. The client's content is missing pieces — props, terrain features, or layout elements that the host has. Both peers play without errors, but one is in a half-empty world. If you exchange and compare world hashes, they differ.

▸ CAUSE

Dev-host streaming sends assemblies (compiled code) and referenced compiled assets to joiners, but not loose data files read via FileSystem.Mounted. A world generator that loads a raw JSON manifest (e.g. models/playground/playground_manifest.json) at build time works on the host but the file is missing on the joining client — the client builds with zero items from that manifest.

The divergence is silent: no missing-file exception (the file-read returns empty/null and the generator skips it), no network error, no visual warning. Both peers play normally, just in different worlds.

▸ FIX

Two options:

  1. Move world-defining data into code constants or compiled assets that travel with the assembly stream. Anything the world generator reads at build time must be reachable on every peer.

  2. Make the world build host-computed and network-spawned — the host builds the world and replicates the result, so clients never need the source data.

Always exchange and assert the world hash at join time regardless of approach:

snippet
// After the client finishes its regen:
var clientHash = ComputeWorldHash();
SendHashToHost(clientHash);

// Host-side:
if (clientHash != hostHash)
    RejectJoin("World hash mismatch — content diverged");

Without the hash check, the divergence is undetectable — both peers play, one in a broken world.

▸ WHY IT WORKS

The dev-host streaming protocol is designed for code and compiled resources, not arbitrary file I/O. Loose files under FileSystem.Mounted are project-local filesystem reads that have no corresponding entry in the network table. By putting world data into the compilation pipeline (or computing it host-side and replicating), you ensure every peer works from the same inputs. The hash assertion is the safety net that catches any remaining divergence before it becomes a silent gameplay difference.

Verified on engine 26.07.15a: seen in a real project.
s&box moves fast; an undated fix is a liability. Spot a stale detail?

Want to know when new guides or fixes drop? Join the community to help build this out. Report gotchas, flag outdated fixes, or just lurk.

Join the Discord