create-siltrun 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Joel Brubaker
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,54 @@
1
+ # create-siltrun
2
+
3
+ Scaffold a [Silt](https://silt.run) multiplayer project: an authoritative room
4
+ contract and a client, in one directory, wired together and ready to run.
5
+
6
+ ```bash
7
+ npm create siltrun@latest my-game
8
+ cd my-game
9
+ npm install
10
+ npm run dev
11
+ ```
12
+
13
+ `npm run dev` boots both halves at once. Your room runs through the `siltrun` CLI,
14
+ which serves room info on <http://localhost:4000>, and the Vite client runs on
15
+ <http://localhost:5173>. Open the client in two windows and you have a multiplayer
16
+ room. Edit `room.ts` and both sides reload.
17
+
18
+ The project directory is required. Running the command with no directory prints
19
+ usage and exits.
20
+
21
+ ## Templates
22
+
23
+ ```bash
24
+ npm create siltrun@latest my-game -- --template tower-defense
25
+ ```
26
+
27
+ | Template | What you get |
28
+ |---|---|
29
+ | `minimal` | The default. The smallest real room: each player moves a ship by tapping a target, the server clamps that intent and eases the ship toward it, and every client renders the same authoritative state. |
30
+ | `tower-defense` | Co-op tower defense. Two players share one always-warm room, ready up, and defend a path against waves together. |
31
+ | `mass-grid` | Territory capture in the Paper.io style. Leave your land to draw a trail, loop back to claim what you enclosed, cut a rival by crossing their trail. |
32
+ | `turn-based-grid` | A starter for agent-first games: a deterministic world that agents play and humans watch, with an action API, an ASCII view alongside the graphics view, an emote channel, and scripted stub agents to prove it. |
33
+
34
+ An unknown template name fails immediately and lists the ones that exist.
35
+
36
+ ## What you get
37
+
38
+ ```
39
+ my-game/
40
+ room.ts your contract: tick(state, inputs), runs server-side at 60Hz
41
+ src/ the client, built on @siltrun/react and @siltrun/stage
42
+ package.json a dev script that runs the room and Vite together
43
+ ```
44
+
45
+ `room.ts` is the whole server. It default-exports a `tick(state, inputs)` function
46
+ that runs 60 times a second and owns the truth. Clients send intent; the tick
47
+ decides what actually happens.
48
+
49
+ This is a plain Node initializer with no dependencies of its own, so it runs
50
+ anywhere `npm create` does.
51
+
52
+ ## Docs
53
+
54
+ Full guides and API reference: <https://silt.run/docs/>
package/package.json CHANGED
@@ -1,18 +1,22 @@
1
1
  {
2
2
  "name": "create-siltrun",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
+ "license": "MIT",
4
5
  "description": "Scaffold a Silt multiplayer project — `npm create siltrun my-game`.",
5
6
  "type": "module",
6
7
  "bin": {
7
8
  "create-siltrun": "index.mjs"
8
9
  },
9
- "files": ["index.mjs", "templates"],
10
- "repository": "https://github.com/digitalpine/silt",
10
+ "files": [
11
+ "index.mjs",
12
+ "templates"
13
+ ],
11
14
  "engines": {
12
15
  "node": ">=18"
13
16
  },
14
17
  "scripts": {
15
18
  "test": "node --test",
16
19
  "typecheck": "true"
17
- }
20
+ },
21
+ "homepage": "https://silt.run"
18
22
  }
@@ -50,7 +50,7 @@ server sends and send intent back. This is why cheating is hard: a client asking
50
50
  understand before you touch `State`.** → `skills/compact-snapshots.md`.
51
51
  - **The genre picks the lane.** Moves ride the *reliable* lane, not the presence datagram lane,
52
52
  because a slow discrete grid game wants ordered, no-drop turns (a dropped turn is a death).
53
- **Ratified amendment (DIG-763): a room that opts into client-side prediction moves its
53
+ **Amendment: a room that opts into client-side prediction moves its
54
54
  steering to the INPUT lane as held intent** — only input-envelope seqs are acked, so only
55
55
  they can reconcile. → `skills/genre-lane-mapping.md` (incl. the prediction amendment).
56
56
 
@@ -55,7 +55,7 @@ ack map would be pure dead weight on a datagram budget this genre already pushes
55
55
  empty and is dropped from the wire entirely. The lane choice that is *correct for the genre* is
56
56
  also the one that *reclaims budget*. That is not a coincidence you should fight.
57
57
 
58
- ## The prediction amendment (DIG-763, ratified 2026-07-21)
58
+ ## The prediction amendment
59
59
 
60
60
  The rule above has one ratified exception: **a room that opts into client-side prediction
61
61
  puts its steering on the INPUT (datagram) lane — even discrete steering.** Prediction's
@@ -3,7 +3,7 @@
3
3
  // intent on the reliable lane; this tick() decides what actually happens; every peer
4
4
  // (playing agents + spectating humans) receives the resulting State each tick.
5
5
  //
6
- // THE TICK / BEAT MODEL (DIG-725, the load-bearing decision) ─────────────────────────
6
+ // THE TICK / BEAT MODEL (the load-bearing decision) ─────────────────────────
7
7
  //
8
8
  // • The relay clock is a constant 60Hz and never pauses while ≥1 peer is present.
9
9
  // We do NOT fight it. On top of it we quantize turns into BEATS of BEAT_TICKS ticks.
@@ -1,7 +1,7 @@
1
1
  // brains.ts — scripted stub agents. Each brain is a pure decision function over the
2
2
  // AGENT PERCEPTION (the rendered ASCII string) — it never sees State. That constraint
3
3
  // is the whole point: if these can play from text alone, the substrate is sufficient,
4
- // and the same brain lifts behind a real MCP agent later (DIG-718) unchanged.
4
+ // and the same brain lifts behind a real MCP agent later unchanged.
5
5
  //
6
6
  // The four brains double as the substrate's live demonstrators:
7
7
  // greedy — competent play (walks to the nearest pellet)
@@ -1,7 +1,7 @@
1
1
  // stubAgent.ts — a scripted agent as a REAL Silt client. It opens its own joinRoom
2
2
  // connection (exactly like the drift diag two-connection pattern), so from the room's
3
3
  // point of view it is indistinguishable from any other peer — and from a real MCP-driven
4
- // agent later (DIG-718). The only difference is the brain: scripted here, an LLM there.
4
+ // agent later. The only difference is the brain: scripted here, an LLM there.
5
5
  //
6
6
  // The read→think→act loop is deliberately faithful to real agent latency:
7
7
  // 1. snapshot the latest received State,
@@ -6,7 +6,7 @@
6
6
 
7
7
  import type { Dir, Pos } from "./types.ts";
8
8
 
9
- // ── The tick / beat model constants (the load-bearing design, DIG-725) ──
9
+ // ── The tick / beat model constants (the load-bearing design) ──
10
10
  //
11
11
  // The relay's world clock runs at a fixed 60 ticks/sec and never pauses while ≥1 peer
12
12
  // is present. On top of that constant clock we quantize turns into BEATS.