Memo: JSHack Extension Fabric
JSHack is fundamentally a browser-first game.
The browser owns the simulation. Combat, AI, world generation, ECS, inventory, rendering, saves, and nearly every game mechanic execute locally. The game should remain fully playable offline, with networking treated as an optional enhancement rather than a requirement.
This leads to a simple architectural principle:
«The engine never talks to servers directly. Cloud Extensions do.»
The extension layer becomes the boundary between the local game and the outside world.
JSHack
├── Engine
│ ├── ECS
│ ├── World Simulation
│ ├── Rendering
│ ├── Input
│ ├── Saves
│ └── Rules
│
└── Extensions
├── Mailbox
├── High Scores
├── Proof of Effort
├── Daily Challenges
├── Cloud Saves
├── Community Events
└── ...
The engine exposes events, commands, UI hooks, and extension APIs. An extension may choose to remain entirely local, or it may communicate with a remote service. The engine neither knows nor cares.
For example, interacting with a mailbox in town invokes the Mailbox extension. The extension displays inbox and outbox UI, communicates with its backend, and returns results to the game. From the engine's perspective, it is simply another interaction.
Likewise, a High Scores extension observes the completion of a run and decides whether to submit it. A Proof of Effort extension observes gameplay, constructs whatever evidence it requires, and publishes it independently. None of these concerns belong in the engine.
On the server side, the architecture mirrors the extension boundary.
Cloudflare Worker
POST /ext/:extension/:command
mailbox
high-scores
proof-of-effort
cloud-saves
...
Each extension owns its own API surface and persistence. Most will likely use Cloudflare Workers backed by D1 or KV. There is no monolithic "game server." Instead, there is a collection of narrowly scoped services that support optional online features.
This has several advantages.
First, the engine remains deterministic and portable. Running locally, offline, or embedded in another environment requires no changes.
Second, online features can evolve independently. The Mailbox extension can start life as an intentionally insecure prototype keyed only by phone number. Later it can introduce mailbox secrets, notifications, or stronger authentication without any changes to the engine or the town interaction itself.
Third, new online capabilities become additive. Features like trading posts, shared world events, speedrun verification, cloud-backed journals, seasonal ladders, or asynchronous quests all fit naturally into the same model.
The resulting philosophy is straightforward:
- The engine owns gameplay.
- Extensions own integration.
- Servers exist to support extensions, not to run the game.
If this boundary holds, JSHack remains what it was designed to be: a local-first roguelike that can gradually acquire rich online capabilities without ever becoming dependent on them.
Memo: JSHack Extension Fabric
JSHack is fundamentally a browser-first game.
The browser owns the simulation. Combat, AI, world generation, ECS, inventory, rendering, saves, and nearly every game mechanic execute locally. The game should remain fully playable offline, with networking treated as an optional enhancement rather than a requirement.
This leads to a simple architectural principle:
«The engine never talks to servers directly. Cloud Extensions do.»
The extension layer becomes the boundary between the local game and the outside world.
JSHack
├── Engine
│ ├── ECS
│ ├── World Simulation
│ ├── Rendering
│ ├── Input
│ ├── Saves
│ └── Rules
│
└── Extensions
├── Mailbox
├── High Scores
├── Proof of Effort
├── Daily Challenges
├── Cloud Saves
├── Community Events
└── ...
The engine exposes events, commands, UI hooks, and extension APIs. An extension may choose to remain entirely local, or it may communicate with a remote service. The engine neither knows nor cares.
For example, interacting with a mailbox in town invokes the Mailbox extension. The extension displays inbox and outbox UI, communicates with its backend, and returns results to the game. From the engine's perspective, it is simply another interaction.
Likewise, a High Scores extension observes the completion of a run and decides whether to submit it. A Proof of Effort extension observes gameplay, constructs whatever evidence it requires, and publishes it independently. None of these concerns belong in the engine.
On the server side, the architecture mirrors the extension boundary.
Cloudflare Worker
POST /ext/:extension/:command
mailbox
high-scores
proof-of-effort
cloud-saves
...
Each extension owns its own API surface and persistence. Most will likely use Cloudflare Workers backed by D1 or KV. There is no monolithic "game server." Instead, there is a collection of narrowly scoped services that support optional online features.
This has several advantages.
First, the engine remains deterministic and portable. Running locally, offline, or embedded in another environment requires no changes.
Second, online features can evolve independently. The Mailbox extension can start life as an intentionally insecure prototype keyed only by phone number. Later it can introduce mailbox secrets, notifications, or stronger authentication without any changes to the engine or the town interaction itself.
Third, new online capabilities become additive. Features like trading posts, shared world events, speedrun verification, cloud-backed journals, seasonal ladders, or asynchronous quests all fit naturally into the same model.
The resulting philosophy is straightforward:
If this boundary holds, JSHack remains what it was designed to be: a local-first roguelike that can gradually acquire rich online capabilities without ever becoming dependent on them.