wren/val Public Public: anyone can read this; nobody can change it.
forked from benjivers/val
workbenchthis machine
Say in the README how bodies come into sight
Co-Authored-By: Claude Opus 5 <[email protected]>
1 file
changed +19
−9
README.md +19 −9
| @@ -73,15 +73,24 @@ 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. 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. | |
| 76 | against the walls. It is drawn into an offscreen canvas 960 columns wide | |
| 77 | (`static/resolution.js`, never more than the canvas has pixels), one ray | |
| 78 | every other column, and scaled onto the visible one, so the frame costs the | |
| 79 | same on a retina screen as on any other; the crosshair, the HUD and the | |
| 80 | minimap are drawn on top at full device resolution. Columns that would draw | |
| 81 | the same rectangle are batched into one fill (`static/slices.js`), the | |
| 82 | map's tiles are drawn once a size and blitted after that, and if the frame | |
| 83 | still runs over 20ms the render width drops a rung until it fits | |
| 84 | (`static/budget.js`). Fidelity is cheap here and frame rate is not. | |
| 85 | All of it is presentation: the simulation and the snapshots are untouched. | |
| 86 | - A body you have only just been shown is faded and grown into sight over a | |
| 87 | tenth of a second, and slid in from the direction it came if it was seen | |
| 88 | near there before; where somebody was last seen alive leaves an outline | |
| 89 | that dims away over a second (`static/presence.js`). The server still sends | |
| 90 | only what you can see — that is the rule, and nothing here bends it. This | |
| 91 | is a drawing about information you already had: an enemy who steps into a | |
| 92 | sightline has no history, and without it they appear mid-stride rather than | |
| 93 | walking into the room. | |
| 85 | 94 | - One map, one match at a time, ten seats. There is no matchmaking, no |
| 86 | 95 | ranking and no account: your seat belongs to a session cookie, and a |
| 87 | 96 | playing seat is capped one per client address so a cookie — free to mint |
| @@ -134,6 +143,7 @@ live match and its sockets · `src/server.ts` the door · `static/` the browser | ||
| 134 | 143 | `val.js` wires the socket, the keys and the HUD, `raycast.js` is the ray |
| 135 | 144 | maths, `scene.js` the first-person view, `slices.js` batches its wall |
| 136 | 145 | columns, `resolution.js` and `budget.js` decide how wide to draw it, |
| 146 | `presence.js` fades bodies into sight and marks where they left it, | |
| 137 | 147 | `topdown.js` the minimap, |
| 138 | 148 | `gun.js`, `beep.js`, `steer.js`, `roster.js`, `yaw.js`, `interp.js` and `prompt.js` the rest; the server bundles |
| 139 | 149 | them into one content-named file at start-up. The rules are pure functions and the tests play whole matches |