34 lines
5.0 KiB
Markdown
34 lines
5.0 KiB
Markdown
# MVP browser client
|
||
|
||
The client lives in `client/` and is served by `shacraft-server` at `/`. It uses ES modules and its own WebGL2 renderer, with no bundler, npm dependencies, or off-the-shelf game engine. Open `http://127.0.0.1:4000` after starting the server. Modern desktop browsers with WebGL2 are supported; `localhost` or HTTPS is required for `crypto.subtle` and package verification.
|
||
|
||
## Controls
|
||
|
||
- Click the world to capture the mouse. If the browser blocks pointer lock, hold the mouse button and drag to look around.
|
||
- WASD or arrow keys move; Space jumps. Movement follows the camera; +Y is up, and yaw 0 looks along −Z. The player's position specifies their feet.
|
||
- Left-click removes the selected block, right-click places a block against the selected face, and middle-click copies the selected material into the current hotbar slot.
|
||
- 1–9 or the mouse wheel selects a hotbar slot. E opens the library of all states; search uses English Minecraft identifiers. Selecting a state replaces the current slot.
|
||
- T or Enter opens chat, Enter sends, and Esc closes it.
|
||
- The world-name button opens the instance selector. F3 opens diagnostics. The menu contains the player name, return-to-spawn action, and Spleef start action.
|
||
- Esc releases the mouse. Losing focus or opening a panel sends zero input so the player does not keep moving.
|
||
|
||
## Rendering and synchronization
|
||
|
||
Geometry is built from each material's local box shapes. Meshes are divided into 16³ sections; shared faces between full opaque cubes are culled. A block change rebuilds its section and adjacent sections. The shader uses directional lighting, fog, a pixelated surface pattern, and an original texture from a verified package. The sky and sun are also drawn with WebGL. Transparent materials use a separate pass with sections sorted by distance; transparent surface ordering within each section is simplified. A package with the declarative style `effect: bounce` (including the trampoline and custom blocks) supplies a texture, a verified GLSL highlight function, and an original sound; the response is tied to the player's upward movement received from the server. Entity shapes come from the catalog; players have separate multipart avatars. These are original, simplified visuals rather than an exact reproduction of Minecraft.
|
||
|
||
The client sends input at most 20 times per second, never declares its own position, and does not edit blocks optimistically. The server computes movement, collisions, and edits, while the client smooths received positions between frames. This introduces a small movement delay but keeps the displayed position aligned with the authoritative simulation. The camera responds to the mouse locally.
|
||
|
||
`welcome` and `snapshot` replace all visible geometry. A full `registry` is optional: snapshots contain at most 256 definitions of materials in use, and the client gradually fetches the remaining shapes through `/api/catalog?ids=...&limit=128`. Each response rebuilds only affected sections; a neutral cube is displayed until its shape arrives. `blocks` events are applied only in revision order; data outside the latest 64×40×64 window is discarded while the revision still advances. A gap triggers `resync`; old revisions are ignored. After a disconnect, the client retries after 1, 2, 4, 8, 16, then 20 seconds. Connection failures, incompatible protocols, resource errors, and actions rejected by the server are shown to the user.
|
||
|
||
## Packages
|
||
|
||
Before joining through WebSocket, the client fetches `/api/manifest`, downloads the declared client files from the same server, verifies their sizes and SHA-256 hashes, and stores their contents in CacheStorage keyed by hash. Cached files are verified again. Cache failure does not skip integrity verification. A hash mismatch removes the file from the cache and prevents joining. A single file is limited to 64 MiB, the set verified per download to 128 MiB, and the cache to its 512 most recent entries. These limits apply to verified contents; browser network buffers and image decoding also consume memory.
|
||
|
||
The Control API token is never sent to the client. Packages do not execute arbitrary privileged JavaScript in the browser. Client-side hash verification establishes resource compatibility; it does not prove that the client itself is unmodified on the player's device.
|
||
|
||
## Debugging and checks
|
||
|
||
F3 displays real values: world, revision, visible block and entity counts, players, WebGL, FPS, triangles, tick, acknowledged input, coordinates, packages, and available server metrics. `#world-canvas` exposes `data-world`, `data-revision`, `data-blocks`, `data-entities`, `data-webgl`, and `data-connected`; these update once per second for automated browser checks. Secrets and control commands are not exposed through the DOM.
|
||
|
||
Run the pure math checks with `cd client && npm test`. They cover camera axes and projection, negative coordinates, the nearest face, reach limits, and exact hits on non-full-block shapes. Visual and end-to-end checks use a real server separately from these unit tests.
|