benjivers/val Public Public: anyone can read this; the crew can change it.
Say in the README how wide the world is drawn, and why
Co-Authored-By: Claude Opus 5 <[email protected]>
1 file
changed +16
−4
README.md +16 −4
| @@ -73,7 +73,15 @@ Guns: Classic, Ghost, Sheriff, Spectre, Phantom, Vandal, Operator. | ||
| 73 | 73 | - The view is a raycaster: walls are one tile tall and flat-shaded, there is |
| 74 | 74 | no looking up or down, and everything that is not a wall — bodies, the |
| 75 | 75 | spike, ability zones — is a flat billboard scaled by distance and clipped |
| 76 | against the walls. | |
| 76 | against the walls. It is drawn into an offscreen canvas a fixed number of | |
| 77 | columns wide (`static/resolution.js`: 1280 on a wide window, 960 otherwise, | |
| 78 | never more than the canvas has pixels) and scaled onto the visible one, so | |
| 79 | the frame costs the same on a retina screen as on any other; the crosshair, | |
| 80 | the HUD and the minimap are drawn on top at full device resolution. Columns | |
| 81 | that would draw the same rectangle are batched into one fill | |
| 82 | (`static/slices.js`), and if the frame still runs over 20ms the render | |
| 83 | width drops a rung until it fits (`static/budget.js`). All of that is | |
| 84 | presentation: the simulation and the snapshots are untouched by it. | |
| 77 | 85 | - One map, one match at a time, ten seats. There is no matchmaking, no |
| 78 | 86 | ranking and no account: your seat belongs to a session cookie, and a |
| 79 | 87 | playing seat is capped one per client address so a cookie — free to mint |
| @@ -96,8 +104,10 @@ Guns: Classic, Ghost, Sheriff, Spectre, Phantom, Vandal, Operator. | ||
| 96 | 104 | Click the view to capture the mouse, then WASD move and the mouse looks; |
| 97 | 105 | **Esc** gives the pointer back. Click fires, **R** reloads, **F** plants and |
| 98 | 106 | defuses (hold it), **C / Q / E / X** cast, **B** opens the buy, **Tab** |
| 99 | holds the big map open, **V** swaps to the top-down view and **H** or **?** | |
| 100 | brings back the how-to-play card. On a phone it stays top-down: the left | |
| 107 | holds the big map open, **V** swaps to the top-down view, **H** or **?** | |
| 108 | brings back the how-to-play card, and **F3** or **`** prints the frame | |
| 109 | readout: frame rate, mean frame, snapshots a second, the interpolation delay | |
| 110 | in force and the width the world is being drawn at. On a phone it stays top-down: the left | |
| 101 | 111 | thumb walks and the right thumb aims and fires. |
| 102 | 112 | |
| 103 | 113 | sh |
| @@ -122,7 +132,9 @@ says how. | ||
| 122 | 132 | no clock) · `src/bots.ts` the seats nobody is in · `src/arena.ts` the one |
| 123 | 133 | live match and its sockets · `src/server.ts` the door · `static/` the browser client — |
| 124 | 134 | `val.js` wires the socket, the keys and the HUD, `raycast.js` is the ray |
| 125 | maths, `scene.js` the first-person view, `topdown.js` the minimap, | |
| 135 | maths, `scene.js` the first-person view, `slices.js` batches its wall | |
| 136 | columns, `resolution.js` and `budget.js` decide how wide to draw it, | |
| 137 | `topdown.js` the minimap, | |
| 126 | 138 | `gun.js`, `beep.js`, `steer.js`, `roster.js`, `yaw.js`, `interp.js` and `prompt.js` the rest; the server bundles |
| 127 | 139 | them into one content-named file at start-up. The rules are pure functions and the tests play whole matches |
| 128 | 140 | headlessly. |