Skip to content

Commit d44b5af

Browse files
committed
feat: add docs
1 parent 32a2a9f commit d44b5af

File tree

9 files changed

+1290
-0
lines changed

9 files changed

+1290
-0
lines changed

docs/docs/architecture.rst

Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
Architecture
2+
============
3+
4+
Overview
5+
--------
6+
7+
NanoForge Loader is a runtime system that serves and executes NanoForge game
8+
engine projects. It provides two execution modes:
9+
10+
- **Client mode**: Serves a web interface where users can load and play games
11+
directly in the browser using WebGL.
12+
- **Server mode**: Executes game server logic in a Node.js worker thread,
13+
suitable for multiplayer game backends.
14+
15+
Both loaders share a common architecture: they read game files from a directory,
16+
generate a manifest of assets, and execute the game's ``main.js`` entry point.
17+
18+
Technology Stack
19+
----------------
20+
21+
.. list-table::
22+
:header-rows: 1
23+
:widths: 30 70
24+
25+
* - Component
26+
- Technology
27+
* - Language
28+
- TypeScript (strict mode)
29+
* - Runtime
30+
- Bun (bundler and runtime)
31+
* - Module Formats
32+
- ESM + CJS (dual package)
33+
* - Target
34+
- Browser (client) / Node.js (server)
35+
* - Package Manager
36+
- pnpm 10.x
37+
* - Node Version
38+
- 25
39+
* - Linter
40+
- ESLint 9.x
41+
* - Formatter
42+
- Prettier 3.x
43+
* - CI/CD
44+
- GitHub Actions
45+
46+
Package Architecture
47+
--------------------
48+
49+
The loader is organized as a monorepo with three packages:
50+
51+
::
52+
53+
loader/
54+
+-- apps/
55+
| +-- client/ # Browser loader server
56+
| | +-- src/
57+
| | | +-- server.ts # HTTP server entry point
58+
| | | +-- env.ts # Environment configuration
59+
| | | +-- files.ts # File utilities
60+
| | | +-- manifest.ts # Manifest generation
61+
| | | +-- watch.ts # File watcher for hot reload
62+
| | +-- package.json
63+
| +-- server/ # Node.js server loader
64+
| | +-- src/
65+
| | | +-- server.ts # Bootstrap entry point
66+
| | | +-- worker.ts # Worker thread implementation
67+
| | | +-- env.ts # Environment configuration
68+
| | | +-- files.ts # File utilities
69+
| | | +-- watch.ts # File watcher for hot reload
70+
| | +-- package.json
71+
| +-- website/ # Web interface
72+
| +-- src/
73+
| | +-- index.ts # Main entry point
74+
| | +-- cache/ # Caching logic
75+
| | +-- file-system/ # File system abstraction
76+
| | +-- game/ # Game runner
77+
| | +-- loader/ # Game file loader
78+
| | +-- types/ # TypeScript types
79+
| | +-- utils/ # Utility functions
80+
| | +-- version/ # Version management
81+
| +-- package.json
82+
+-- package.json # Root workspace config
83+
+-- pnpm-workspace.yaml # pnpm workspace definition
84+
+-- turbo.json # Turbo build configuration
85+
86+
Client Loader Flow
87+
------------------
88+
89+
The client loader implements an HTTP server using Bun:
90+
91+
1. **Server Initialization**: Starts an HTTP server on the configured port.
92+
93+
2. **Route Handling**:
94+
95+
- ``/`` - Serves the website ``index.html``
96+
- ``/*`` - Serves static website assets
97+
- ``/manifest`` - Returns the game file manifest (JSON)
98+
- ``/env`` - Returns public environment variables
99+
- ``/game/*`` - Serves game files from the game directory
100+
101+
3. **Manifest Generation**: On each ``/manifest`` request, scans the game
102+
directory and builds a list of all game files with their paths.
103+
104+
4. **Hot Reload** (optional): When ``WATCH=true``, starts a WebSocket server
105+
that notifies the browser when game files change.
106+
107+
.. code-block:: text
108+
109+
Browser Client Loader Game Directory
110+
| | |
111+
|----GET /manifest-------->| |
112+
| |---scan directory--------->|
113+
| |<--file list---------------|
114+
|<---JSON manifest---------| |
115+
| | |
116+
|----GET /game/main.js---->| |
117+
| |---read file-------------->|
118+
|<---JavaScript file-------| |
119+
| | |
120+
|====WebSocket (watch)=====| |
121+
|<---file changed----------|<--fsnotify---------------|
122+
123+
Server Loader Flow
124+
------------------
125+
126+
The server loader executes game logic in a Node.js worker thread:
127+
128+
1. **Bootstrap**: Reads the game directory and locates ``main.js``.
129+
130+
2. **Worker Fork**: Spawns a child process that runs the worker script.
131+
132+
3. **Game Execution**: The worker imports ``main.js`` and calls its ``main()``
133+
function with a file map containing all game assets.
134+
135+
4. **Hot Reload** (optional): When watch mode is enabled, the worker process
136+
is killed and restarted when files change.
137+
138+
.. code-block:: text
139+
140+
Server Loader Worker Thread Game Code
141+
| | |
142+
|---fork(worker.js)--------->| |
143+
| |---import main.js-------->|
144+
| |<--main function----------|
145+
| |---call main()----------->|
146+
| | |
147+
[file change detected] | |
148+
|---kill worker------------->| |
149+
|---fork new worker--------->| |
150+
151+
Website Architecture
152+
--------------------
153+
154+
The website package provides the browser-side game loader:
155+
156+
1. **Manifest Fetching**: Requests ``/manifest`` from the client server.
157+
158+
2. **File Caching**: Downloads game files and stores them in browser storage
159+
(IndexedDB via the file-system abstraction).
160+
161+
3. **Version Checking**: Compares the manifest version with cached version
162+
to determine if files need updating.
163+
164+
4. **Game Loading**: Imports the main module and creates a file map for
165+
the game to access assets.
166+
167+
5. **Game Execution**: Calls the game's ``main()`` function with canvas
168+
and file references.
169+
170+
6. **Watch Integration**: Subscribes to the WebSocket for hot reload
171+
notifications during development.
172+
173+
Build Pipeline
174+
--------------
175+
176+
The project uses Bun for building and bundling:
177+
178+
.. code-block:: bash
179+
180+
# Build all packages
181+
pnpm run build
182+
183+
# What happens internally:
184+
# 1. website: bun build -> dist/index.html + assets
185+
# 2. client: bun build -> dist/server.js
186+
# 3. server: bun build -> dist/server.js + dist/worker.js
187+
188+
Each package produces optimized bundles for its target environment:
189+
190+
- **Website**: Browser bundle with HTML entry point
191+
- **Client**: Bun-targeted server bundle
192+
- **Server**: Node.js-targeted bundles for server and worker
193+
194+
Turbo is used to orchestrate builds across packages with proper dependency
195+
ordering (website must build before client).

docs/docs/client.rst

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
client
2+
=============
3+
4+
**Package**: ``@nanoforge-dev/loader-client``
5+
6+
The client loader serves a web interface for loading and running NanoForge
7+
games in the browser. It provides an HTTP server that serves the website
8+
assets and game files.
9+
10+
Overview
11+
--------
12+
13+
The client loader is a Bun-based HTTP server that:
14+
15+
- Serves the loader website interface
16+
- Provides a manifest endpoint listing all game files
17+
- Serves game files from a configured directory
18+
- Optionall:white_check_mark: y enables hot reload via WebSocket
19+
20+
Environment Variables
21+
---------------------
22+
23+
.. list-table::
24+
:header-rows: 1
25+
:widths: 25 15 60
26+
27+
* - Variable
28+
- Required
29+
- Description
30+
* - ``PORT``
31+
- Yes
32+
- Port number for the HTTP server
33+
* - ``GAME_DIR``
34+
- Yes
35+
- Absolute path to the game directory
36+
* - ``WATCH``
37+
- No
38+
- Set to ``"true"`` to enable hot reload
39+
* - ``WATCH_PORT``
40+
- No
41+
- Port for the WebSocket watch server
42+
* - ``WATCH_SERVER_GAME_DIR``
43+
- No
44+
- Game directory for server-side watch
45+
* - ``PUBLIC_*``
46+
- No
47+
- Any variable prefixed with ``PUBLIC_`` is exposed to the client
48+
49+
API Endpoints
50+
-------------
51+
52+
.. list-table::
53+
:header-rows: 1
54+
:widths: 20 80
55+
56+
* - Endpoint
57+
- Description
58+
* - ``GET /``
59+
- Serves the main ``index.html`` page
60+
* - ``GET /*``
61+
- Serves static website assets
62+
* - ``GET /manifest``
63+
- Returns the game manifest as JSON
64+
* - ``GET /env``
65+
- Returns public environment variables as JSON
66+
* - ``GET /game/*``
67+
- Serves files from the game directory
68+
69+
Manifest Format
70+
---------------
71+
72+
The ``/manifest`` endpoint returns a JSON object:
73+
74+
.. code-block:: typescript
75+
76+
interface IManifest {
77+
version: string;
78+
files: { path: string }[];
79+
watch: { enable: false } | { enable: true; url: string };
80+
}
81+
82+
Source Modules
83+
--------------
84+
85+
server.ts
86+
^^^^^^^^^
87+
88+
Main entry point that creates and configures the Bun HTTP server with all
89+
route handlers.
90+
91+
env.ts
92+
^^^^^^
93+
94+
Environment variable accessors:
95+
96+
.. code-block:: typescript
97+
98+
function getPort(): string
99+
function getGameDir(): string
100+
function getWatch(): string | undefined
101+
function getWatchPort(): string | undefined
102+
function getWatchServerGameDir(): string | undefined
103+
function getPublicEnv(): Record<string, string>
104+
105+
manifest.ts
106+
^^^^^^^^^^^
107+
108+
Manifest generation:
109+
110+
.. code-block:: typescript
111+
112+
const MANIFEST: IManifest
113+
function updateManifest(gameDir: string): Promise<void>
114+
115+
watch.ts
116+
^^^^^^^^
117+
118+
File watching for hot reload:
119+
120+
.. code-block:: typescript
121+
122+
function startWatch(
123+
gameDir: string,
124+
watchPort: string | undefined,
125+
watchServerGameDir: string | undefined
126+
): void
127+
128+
Usage
129+
-----
130+
131+
.. code-block:: bash
132+
133+
# Set required environment variables
134+
export PORT=3000
135+
export GAME_DIR=/path/to/game
136+
137+
# Start the client loader
138+
pnpm --filter @nanoforge-dev/loader-client start
139+
140+
# With hot reload
141+
export WATCH=true
142+
export WATCH_PORT=3001
143+
pnpm --filter @nanoforge-dev/loader-client start

docs/docs/index.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
Technical Documentation
2+
======================
3+
4+
.. toctree::
5+
:maxdepth: 2
6+
7+
architecture
8+
client
9+
website
10+
server

0 commit comments

Comments
 (0)