Authoring, testing, exporting and publishing are separate operations. A saved local draft is not automatically visible to subscribers; a successful upload does not prove that a clean installation can play every branch. Use a repeatable release checklist and keep the exact ZIP/version that you distributed.

This chapter covers both offline sharing and the Steam publication interface. Read Your first mod for creation and Profiles and snapshots for the player's installation/resume behavior.

Prepare a release candidate

  1. Give the pack a stable unique ID, useful name, author and description. Update its three-part pack version for a distributed revision.
  2. Declare supported game/API ranges and modes. Add required dependency versions and known conflicts. Do not enable multiplayer merely to obtain a filter tag.
  3. Validate all sections and actual referenced assets. Remove unresolved article/action/scenario/character/wave references.
  4. Test every ordinary solution, diagnostic cause, important graph choice, campaign ending and objective route. Include the deliberately wrong route and failure path.
  5. Check recording coverage for each advertised locale/actor; listen to samples and exercise missing/failing audio fallback. A filename count does not prove speech accuracy.
  6. Preview office art and run an actual scratch shift. Verify stock presentation returns after disabling the pack.
  7. Use a disposable normal campaign save for resume tests. Scratch tests intentionally cannot prove durable save behavior.
  8. Export a ZIP, import it into a clean profile and test that release copy. This catches missing assets and files only present in your authoring environment.
  9. Include a concise README and reuse terms. Keep a copy of this release archive before making incompatible edits.

The README should explain supported modes, how to start an experience, dependency IDs/versions, recommended profile order, available languages/recordings, known limits and significant save changes. If an update changes required campaign content, state that older saved snapshots may need their exact older files; do not promise automatic migration that the pack does not implement.

ZIP contents and boundaries

The native exporter uses an allowlist shared with publication. Included files are runtime mod.json, content.json, achievements.json, preview.png, README (README, .txt or .md), LICENSE (LICENSE or .txt), and permitted image/audio files under art/ and voice/. Use those recognized root names for documents you want exported.

Editor recovery drafts, publication receipts and unrelated files are excluded. Keep private notes outside runtime documents: a password or private text inside content.json is still part of the exported runtime file. The allowlist is not a text-redaction service.

The importer accepts supported stored/deflated ZIP entries with verified checksums and safe regular-file paths. It rejects traversal, case-insensitive duplicate names, filesystem links, encrypted/multipart/unsupported archives, malformed headers and excessive expansion. Each audio file stays below 32 MB; other allowed files below 8 MB; the full expanded archive below 512 MB and 10,000 files.

Do not instruct players to run a bundled executable or place code in the application directory. JavaScript, DLLs, GLB models and full room/interface replacement are outside this pack format. Export/import works in-game without a Steam connection.

Offline CLI for source users

The installed game provides UI import/export. If you have the source repository and its dependencies installed, the same native validation/archive service is available through these commands:

powershell
npm run mod:validate -- "C:\Mods\router-rescue"
npm run mod:pack -- "C:\Mods\router-rescue" "C:\Exports\router-rescue-1.0.0.zip"
npm run mod:unpack -- "C:\Exports\router-rescue-1.0.0.zip" "C:\Mods\imported-router-rescue"

On PowerShell systems where the npm script alias is restricted, use npm.cmd with the same arguments. The destination for unpack should be a new pack directory; the tool does not overwrite an existing release folder. Quoted absolute paths prevent spaces being interpreted as extra arguments.

CLI validation checks the same content contract and real file references used by the game. It does not play a campaign, listen to audio or contact teammates. After a successful pack operation, import the ZIP through the UI if you need to verify player-facing installation.

Workshop publication

Open the local editable pack in Studio. Import a suitable preview through Import preview; the importer writes/resizes the root preview.png used for Workshop. Set title, description, author tags and intended visibility. New uploads default to Private. Choose Friends Only when conducting a cross-account install check, then choose Public once you are ready for public discovery.

Use Preview publication changes before upload. It lists added, changed and removed allowlisted files and upload size compared with the last successful local publication receipt. A first upload has no prior receipt. The receipt is local publication bookkeeping, not a source-control history or a proof of successful subscriber installation.

The native service stages a validated immutable copy for upload. Editing the authoring folder while upload is in progress does not intentionally alter that staged release. Finish the upload, inspect its result and publish another deliberate update if you changed content afterward.

Publishing preserves allocated item identity. Once Steam creates an item, Studio records its workshopId immediately, including when upload fails or an agreement is required. Retrying should update that allocated item rather than create duplicate listings. If the UI says an item was created but its ID could not be saved locally, preserve the displayed ID before another attempt and fix the authoring folder's write problem.

Steam may require acceptance of the Workshop agreement. Follow the displayed link/instructions, accept through Steam, and retry the same item. The game does not accept that agreement for you. If upload reports success but local settings could not be saved, retain the item ID and repair the local folder; do not assume the upload failed solely because local bookkeeping failed.

Updates remember title, description, visibility and tags. An update change note belongs to that publication, rather than permanently replacing the pack description. Legacy items without saved publication settings preserve current tags/visibility until those fields are explicitly edited.

Tags and browse filters

Studio infers content tags from actual data: Calls, Stories, Challenges, Night Shift, Office, Audio, Translations. It also adds supported-mode tags (mode:career, mode:nightshift, mode:challenge, mode:campaign, mode:multiplayer) and language tags such as language:en or language:pt-br.

Your custom author tags are stored separately as workshop.authorTags so inferred filters can refresh when content changes. Steam's limit is 20 tags. More than 20 custom tags blocks publication. If custom tags plus automatic tags exceed the limit, Studio reports omitted automatic filters. Reduce redundant custom tags when that warning would make the item difficult to find.

Browsing depends on the same stable vocabulary and the game's Steam Workshop configuration. A tag is a search aid, not a compatibility override or a completeness certification. Include truthful supported modes/languages in the description as well.

Credits and reuse terms

Only distribute artwork, text and recordings you have permission to distribute. Preserve required attribution when cloning or adapting a template or another pack. The toolkit's reusable examples include their own reuse terms; those terms do not automatically cover unrelated community assets.

Include LICENSE or LICENSE.txt for reusable pack terms and describe required credits in README. Technical cloning copies assets and clears publication settings; it does not grant new redistribution rights. A public Workshop item is not automatically a blanket permission to re-publish its assets. Keep the original author credited where the source terms require it.

Scratch debugging

Studio provides Test Call, Test Shift and authored experience playtests. Select seed, day, caller variant, subtitle language and audio language. Zero is a valid seed. Make the day eligible for the scenario. Cosmetic-only tests use stock calls so you can inspect the real office without authoring an irrelevant call expansion.

The debug panel shows selection pool, current scenario and diagnostic cause, verification, current graph node/prior choices, available solutions, rules, objectives and actual audio resolution/playback or timed-subtitle fallback. Use Rerun call to select a diagnostic cause and compare its route. Use Rerun shift to reset owned state and scheduling with the selected seed.

Scratch sessions do not write career/Cloud data, stock awards, trophies, prestige progress or custom results. They restore temporary subtitle/audio choices when returning to the menu. For a save-resume defect, use a disposable normal experience save and record the exact choice/event preceding the save.

Undo/redo keeps a bounded editor history. Unsaved text/data is recovered from local studio-draft.json. On reopen, recover or discard consciously: discarding does not publish anything, and recovering does not magically resolve validation errors. Recovery files are excluded from releases. Export or separately back up milestones; do not rely on a single draft after an extensive restructuring.

Symptom-to-check reference

Symptom Check first
Subscribed item is absent Download status, Steam connection and Installed refresh.
Pack installed but content not active Active profile, enable state, selected source and intended mode.
Unknown article/action Exact reference spelling, local definition, dependency/version and namespacing.
Call never appears minDay, weight zero, mode/profile, selected call pool and explicit scheduling.
Graph has no available useful option Conditions, verification/diagnosis route, else branch and terminal exit.
Recording missing despite import Actor, locale prefix, raw voice key, stable token and exact basename.
Coverage complete but no sound Preview decode/volume, file content, audio setting and debug fallback reason.
Language partly English Missing keys/phrases/dialogue, placeholder correctness, independent UI/subtitle settings.
Office image absent Imported art/... path, file type, byte/pixel bounds, selected source and later surface override.
Trophy absent in Studio test Scratch deliberately suppresses trophies; check an eligible normal session.
Mail bonus repeats or branch forgets state Stable message/choice IDs, rule once policy and normal save-resume reproduction.
Campaign resume blocked Required version/full hash, historical local cache or imported exact release.
Lobby cannot become Ready Exact game/pack requirements, multiplayer opt-in, completed downloads and recheck.
Ready reset Host refreshed/changed its profile; agree to the new frozen requirement set.
Publication asks for agreement Accept the displayed Steam agreement and retry the retained item ID.

A useful bug report

Include the game version, content API/pack version, mod ID, profile, selected local/Workshop source and relevant item ID. Copy validation errors with their full paths. Describe expected and actual behavior, the shortest sequence that reproduces it, seed/day/caller variant, chosen subtitle/audio locales, current node/cause, and whether the run was scratch, career, campaign, custom Night Shift or multiplayer.

For a resume issue, identify the release that created the save and whether its frozen files still exist. For audio, give the target filename and whether a preview decodes. For a multiplayer mismatch, include each peer's displayed required/installed version and hash rather than only saying both downloaded “the latest.” Attach a validated ZIP if its reuse terms permit it.

Local automated tests cover schema, native file/archive contracts, experience runtime behavior, local Electron flows and simulated multiplayer agreement. Live two-account Steam Workshop upload/download and two-PC modded co-op remain a separate verification cycle. Do not label a pack's real Steam delivery tested solely because validation or a simulated lobby passed.