Skip to content

Architecture

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

Architecture · Arquitetura

🇧🇷 Português · 🇬🇧 English


English

Source layout

src/
  App.jsx                  theme/scenario state, GM mode, CSS vars, URL params, idle
  audio/sfx.js             Web Audio synthesis (keystroke/beep/whoosh/hum)
  styles/{base,crt}.css    @font-face fonts + CRT effect
  # engine logic — virtual filesystem, command parser, crack/tracer/decrypt,
  # markdown — now lives in the rpgterm-engine npm package (extracted from this
  # app). The scenario-forge editor consumes the same package, so there's no
  # schema drift between authoring and play.
  components/
    Terminal.jsx           history, typewriter queue, command ctx
    Prompt.jsx             input with inline cursor
    OutputLine.jsx         line (typewriter / banner / progress / countdown)
    ProgressModal.jsx      popup with the animated bar (crack/decrypt)
    SelfDestructModal.jsx  big self-destruct popup + OVERRIDE
    Tracer.jsx             top-right tracer countdown popup
    CountdownLine.jsx      self-destruct / event countdown
    InputModal.jsx         password / roll dialog
    Screensaver.jsx        idle animation
    ThemeSwitcher.jsx · AudioToggle.jsx
  themes/
    index.js                       registry + loader (glob + front-matter) + composeTheme
    <id>.json                      skins
    scenarios/<theme>/<id>/
      scenario.json                motd + commands + login + events + selfDestruct + tracer
      files/**                     terminal files (text / front-matter)
public/fonts/              self-hosted fonts (.ttf/.otf)

How it fits together

  • composeTheme(themeId, scenarioId) merges a theme skin with a scenario, returning the runtime theme object that Terminal.jsx reads.
  • The rpgterm-engine npm package provides the virtual filesystem, command parser, crack/tracer/decrypt mechanics and scenario composition. The scenario-forge editor builds scenarios against the same package and can push one here live via postMessage (or ?scenario64=) for preview — no schema drift.
  • Files under files/ are loaded via import.meta.glob and parsed for front-matter at build time; directories are inferred from the path tree.
  • No backend, no client-side router — the theme/scenario are chosen via URL query params (?theme=…&scenario=…).

Offline / PWA

The app installs and runs offline. A service worker (public/sw.js, cache-first with a background refresh) caches the shell, code, fonts and scenarios after one online visit; the web manifest (public/manifest.webmanifest, relative paths) makes it installable under both the Pages subpath and the domain root. Registered in production only, scoped to import.meta.env.BASE_URL. Handy for running the prop at a table with no/flaky wifi.

Fonts

Self-hosted in public/fonts/ — no external calls.

  • 3270 Nerd Font — BSD-2-Clause (3270) + MIT (Nerd Font).
  • Terminal Grotesque (Raphaël Bastide) — SIL Open Font License.

Português

Layout do código-fonte

src/
  App.jsx                  estado de tema/cenário, GM mode, CSS vars, URL params, idle
  audio/sfx.js             síntese Web Audio (keystroke/beep/whoosh/hum)
  styles/{base,crt}.css    fontes @font-face + efeito CRT
  # o motor — sistema de arquivos virtual, parser de comandos,
  # crack/tracer/decrypt, markdown — agora vive no pacote npm rpgterm-engine
  # (extraído deste app). O editor scenario-forge consome o mesmo pacote, então
  # não há divergência de schema entre autoria e jogo.
  components/
    Terminal.jsx           histórico, fila de typewriter, ctx dos comandos
    Prompt.jsx             input com cursor inline
    OutputLine.jsx         linha (typewriter / banner / progress / countdown)
    ProgressModal.jsx      popup com a barra animada (crack/decrypt)
    SelfDestructModal.jsx  popup grande de autodestruição + OVERRIDE
    Tracer.jsx             popup do rastreador no canto superior direito
    CountdownLine.jsx      contagem de autodestruição / evento
    InputModal.jsx         diálogo de senha / rolagem
    Screensaver.jsx        animação ociosa
    ThemeSwitcher.jsx · AudioToggle.jsx
  themes/
    index.js                       registry + loader (glob + front-matter) + composeTheme
    <id>.json                      skins
    scenarios/<tema>/<id>/
      scenario.json                motd + commands + login + events + selfDestruct + tracer
      files/**                     arquivos do terminal (texto / front-matter)
public/fonts/              fontes self-hosted (.ttf/.otf)

Como se encaixa

  • composeTheme(themeId, scenarioId) mescla a skin do tema com um cenário, retornando o objeto de tema em runtime que o Terminal.jsx lê.
  • O pacote npm rpgterm-engine fornece o sistema de arquivos virtual, o parser de comandos, as mecânicas de crack/tracer/decrypt e a composição de cenários. O editor scenario-forge monta cenários sobre o mesmo pacote e consegue enviar um pra cá ao vivo via postMessage (ou ?scenario64=) pra preview — sem divergência de schema.
  • Arquivos em files/ são carregados via import.meta.glob e têm o front-matter parseado em build time; diretórios são inferidos da árvore de paths.
  • Sem backend, sem router no cliente — tema/cenário são escolhidos por query params na URL (?theme=…&scenario=…).

Offline / PWA

O app instala e roda offline. Um service worker (public/sw.js, cache-first com refresh em background) guarda o shell, código, fontes e cenários após uma visita online; o web manifest (public/manifest.webmanifest, paths relativos) o torna instalável tanto no subpath do Pages quanto na raiz do domínio. Registrado só em produção, com escopo em import.meta.env.BASE_URL. Útil pra rodar o prop numa mesa com wifi ruim ou sem internet.

Fontes

Self-hosted em public/fonts/ — sem chamadas externas.

  • 3270 Nerd Font — BSD-2-Clause (3270) + MIT (Nerd Font).
  • Terminal Grotesque (Raphaël Bastide) — SIL Open Font License.

Clone this wiki locally