Skip to content

Custom Scenarios

Felipe Lippelt edited this page Jun 5, 2026 · 3 revisions

Custom Scenarios · Cenários Custom

🇧🇷 Português · 🇬🇧 English

Run your own campaign on the hosted site without editing the repo — load a scenario bundle from a URL or paste it as JSON.

🛠 The scenario-forge editor produces exactly these: export a JSON bundle or copy a ?scenario64= link straight from the app (and preview it live before sharing).


English

Loading

  • URL param: .../?scenarioUrl=https://host/bundle.json — loaded on first paint.
  • Command: loadscenario https://host/bundle.json — fetches at runtime.
  • Paste: loadscenario (no argument) opens a dialog; paste the JSON and press Ctrl+Enter.

A CUSTOM badge shows in the top bar while a custom scenario is active. Switching theme or scenario (or using the switcher) drops it.

Share link (no hosting)

With a custom scenario active, run sharescenario — it builds a link that embeds the whole bundle in the URL (?scenario64=…, base64url) and copies it to the clipboard. Send that single link and the recipient opens straight into your campaign — no file hosting, no CORS. Best for small/medium bundles; for very large ones (big images, many files) host the JSON and use ?scenarioUrl=.

Bundle format

A bundle mirrors a scenario.json plus a files map and an optional base theme id to skin it:

{
  "theme": "ibm",                 // base skin (defaults to ibm)
  "id": "demo-op",
  "name": "Operation Nightjar",
  "header": "NIGHTJAR // FIELD TERMINAL",
  "motd": ["..."],
  "commands": { "...": ["..."] },
  "login": { "...": "..." },
  "dialog": { "...": "..." },
  "events": { "...": "..." },
  "selfDestruct": { "...": "..." },
  "tracer": { "...": "..." },
  "files": {
    "/brief.md": "# OPERATION NIGHTJAR\n\nRecover the cache...",
    "/intel/cache.dat": "---\nlocked: true\npassword: \"1977\"\ncrackDC: 13\n---\nCACHE CONTENTS:..."
  }
}
  • files is a map of path → raw text (front-matter and all), exactly what a real file under files/ would contain. See Authoring: Scenarios and Locked Files.
  • A bundle may also override skin fields (palette, font, fontSize, crt, banner, screensaver, sounds) for a fully bespoke look.
  • A working sample ships at public/examples/scenario.example.json.

Hosting & security

  • The URL must be CORS-enabled and start with http(s)://. raw.githubusercontent.com and Gist raw URLs work; many file hosts don't.
  • Loading fetches arbitrary JSON and renders it as terminal text / markdown / images. It's React-escaped (no HTML/script injection), but only load bundles you trust — an image: URL can phone home, and content is yours to vet.

Português

🛠 O editor scenario-forge produz exatamente isto: exporte um bundle JSON ou copie um link ?scenario64= direto do app (e teste no preview antes de compartilhar).

Carregando

  • Param de URL: .../?scenarioUrl=https://host/bundle.json — carrega no primeiro paint.
  • Comando: loadscenario https://host/bundle.json — busca em runtime.
  • Colar: loadscenario (sem argumento) abre um diálogo; cole o JSON e aperte Ctrl+Enter.

Um selo CUSTOM aparece na barra de cima enquanto um cenário custom está ativo. Trocar de tema ou cenário (ou usar o switcher) o descarta.

Link compartilhável (sem hospedar)

Com um cenário custom ativo, rode sharescenario — ele monta um link que embute o bundle inteiro na URL (?scenario64=…, base64url) e copia pra área de transferência. Mande esse link único e quem abrir já cai direto na sua campanha — sem hospedar arquivo, sem CORS. Melhor pra bundles pequenos/médios; pra muito grandes (imagens pesadas, muitos arquivos), hospede o JSON e use ?scenarioUrl=.

Formato do bundle

Um bundle espelha um scenario.json mais um mapa files e um theme base opcional pra skin:

{
  "theme": "ibm",                 // skin base (padrão ibm)
  "id": "demo-op",
  "name": "Operation Nightjar",
  "header": "NIGHTJAR // FIELD TERMINAL",
  "motd": ["..."],
  "commands": { "...": ["..."] },
  "login": { "...": "..." },
  "dialog": { "...": "..." },
  "events": { "...": "..." },
  "selfDestruct": { "...": "..." },
  "tracer": { "...": "..." },
  "files": {
    "/brief.md": "# OPERATION NIGHTJAR\n\nRecover the cache...",
    "/intel/cache.dat": "---\nlocked: true\npassword: \"1977\"\ncrackDC: 13\n---\nCACHE CONTENTS:..."
  }
}
  • files é um mapa path → texto cru (com front-matter), exatamente o que um arquivo real em files/ conteria. Veja Autoria: Cenários e Arquivos Trancados.
  • Um bundle pode sobrescrever campos de skin (palette, font, fontSize, crt, banner, screensaver, sounds) pra um visual totalmente próprio.
  • Um exemplo funcional vem em public/examples/scenario.example.json.

Hospedagem & segurança

  • A URL precisa ter CORS habilitado e começar com http(s)://. raw.githubusercontent.com e URLs raw de Gist funcionam; muitos hosts de arquivo não.
  • Carregar busca JSON arbitrário e renderiza como texto / markdown / imagens do terminal. É escapado pelo React (sem injeção de HTML/script), mas só carregue bundles em que você confia — uma URL em image: pode "telefonar pra casa", e o conteúdo é sua responsabilidade verificar.