@netforge/template-idle 0.1.0 → 0.2.0

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/AGENTS.md ADDED
@@ -0,0 +1,73 @@
1
+ # Extending BRINEWORKS
2
+
3
+ BRINEWORKS is the idle template of the Net Forge game engine. The template already has the works, the production chain, buying and levelling, raking, tending, the contract, the shift clock, netcode, rendering, earn and the store. You change the game by changing declarations. Read `llms.txt` for every field, and `llms-full.txt` for the complete worked example.
4
+
5
+ ## The one file to edit
6
+
7
+ - `src/game.ts` is the whole game. Change declarations in place.
8
+ - `src/names.json`, next to it, holds the title and every label. Plants go in `"weapons"` (`{ name, line }`), and `"enemies"` stays empty.
9
+ - Everything else (`src/manifest.ts`, `src/store.ts`, `src/autopilot.ts`, `client/`, `test/`, `scripts/`) is template machinery. Do not edit it.
10
+
11
+ ## Imports
12
+
13
+ `src/game.ts` imports only from `@netforge/engine`. The shipped game uses:
14
+
15
+ ```ts
16
+ import { earn, game, plant, saltFlat, store, upgrade } from "@netforge/engine";
17
+ ```
18
+
19
+ ## Declarations
20
+
21
+ - `game({ template: "idle", style, places, players: { prefab, max } })`, with `max` at most 8.
22
+ - `saltFlat({ shift, tend, start, rake: { salt, cooldown }, brinePerSalt, saltPerCrystal, packEvery, contract: { crystals } })`, exactly one.
23
+ - `plant(id, { model, kind: "pump" | "pan" | "kiln", cost, growth, rate })`, 1 to 8 of them. The bar shows plants in declaration order (keys 1 to 8).
24
+ - `upgrade(id, { stat, step, maxLevel })` with stat `might` (plant output), `haste` (raking speed) or `amount` (salt a rake) only.
25
+ - `earn.rule(id, { when, n, pay, oncePer: "run" })`. Events: `salt.packed`, `crystal.cut`, `crystal.shipped`, `plant.built`, `plant.upgraded` and `contract.filled`.
26
+ - `earn.stake({ min, max, multiple })`, exactly one, on one top-level line.
27
+ - `store.sku(id, { coins, grants? })`.
28
+
29
+ ## Rules the build enforces (the anti-farm rules)
30
+
31
+ - Ids are lower_snake_case.
32
+ - Every game declares at least one `earn.rule` and exactly one `earn.stake`. `"stake"` is reserved.
33
+ - Plants include at least one `pump`, one `pan` and one `kiln`.
34
+ - A shift is 600 to 3600 seconds. Every earn rule is `oncePer: "run"`.
35
+ - `tend` is at most 300 seconds, so a works nobody tends stops.
36
+ - No earn rule may pay sooner than 180 seconds into a fresh works, even with perfect play or raking as fast as the cooldown allows. If a change pays sooner, raise `packEvery` or the rule's `n`, or slow raking.
37
+ - No `weapon()` or `prefab()`.
38
+ - An earn rule must fire within about 4 minutes of 4-player play.
39
+ - Asset ids are library ids such as `"style.lowpoly.barrel"`, never URLs or paths. Keep `game({ style })` as the creator picked it.
40
+ - Keep the SKUs the client is wired to at their prices: `bellows`, `long_rake`, `quick_hands`, `skin_saltwhite`, `skin_rust` and `brass_bellows`.
41
+
42
+ ## Validate
43
+
44
+ - With the MCP server (`npx -y @netforge/mcp`), call `netforge_validate_game` on `src/game.ts`. It returns one actionable line per problem, including the measured first payout when it is too early.
45
+ - In this package, run the tests with vitest: `test/harness.test.ts` and `test/store.test.ts`.
46
+
47
+ ## Playtest
48
+
49
+ - With the MCP server, call `netforge_run_playtest`.
50
+ - In code, import the game module and run the headless harness:
51
+
52
+ ```ts
53
+ import { engine } from "@netforge/engine";
54
+ import "./src/game.js";
55
+
56
+ const report = await engine.test.run({ ticks: 30 * 240, bots: 4, seed: 1 });
57
+ console.log(report.kills, report.earned, report.rules?.checks);
58
+ ```
59
+
60
+ The report has crates packed (as kills), earn by rule, softlock, ms per tick and the genre's checks (the farming bounds) under `rules.checks`.
61
+
62
+ ## Play locally
63
+
64
+ In a folder with `netnet.json` (`{"template":"idle"}`) and `src/game.ts`, with `@netforge/kit-play` and `@netforge/engine` installed, run `npx kit-play`. It opens http://127.0.0.1:4663 with play money. The MCP tool `netforge_play_locally` gives the same steps.
65
+
66
+ ## Do not
67
+
68
+ - Do not write renderers, netcode, physics or bot logic. The template has them.
69
+ - Do not add offline production, wall-clock timers or client-reported numbers.
70
+ - Do not reference assets by URL or file path.
71
+ - Do not import anything other than `@netforge/engine` in `src/game.ts`.
72
+ - Do not edit `client/`, `src/manifest.ts`, `src/store.ts` or `src/autopilot.ts`.
73
+ - Do not rename or reprice the SKUs the client is wired to.
package/CLAUDE.md ADDED
@@ -0,0 +1,11 @@
1
+ # CLAUDE.md
2
+
3
+ This package is BRINEWORKS, a Net Forge game template. Read AGENTS.md before changing this game. It lists the declarations this genre has, the rules the build enforces, and how to validate, playtest and play the game locally.
4
+
5
+ The five hard rules:
6
+
7
+ 1. Edit only src/game.ts (and src/names.json for the labels players read).
8
+ 2. Import only from @netforge/engine.
9
+ 3. Ids are lower_snake_case.
10
+ 4. Declare at least one earn.rule and exactly one earn.stake.
11
+ 5. Never write renderers, netcode, physics or bot AI, and never reference assets by URL or file path (use library ids such as "style.lowpoly.frog").
package/README.md CHANGED
@@ -1,43 +1,87 @@
1
- # BRINEWORKS (idle template)
1
+ # @netforge/template-idle
2
2
 
3
- A white salt flat under a hot sky. Up to eight players each run a works:
4
- pumps draw brine, pans boil it into salt, kilns cut crystals, and salt buys
5
- more plants. A barge on the canal takes crystals for a contract everyone
6
- fills together. A shift lasts fifteen minutes; then a new one begins.
3
+ A shared idle game template for Net Forge: a salt flat where up to eight players each run a works and fill one contract together (BRINEWORKS).
7
4
 
8
- A board genre (`packages/engine/src/rules/idle.ts`) on the shared runtime;
9
- client kit `@netforge/tabletop`. Room template `idle` (cap 8).
5
+ A white salt flat under a hot sky. Pumps draw brine, pans boil it into salt, kilns cut crystals, and salt buys more plants. A barge on the canal takes crystals for a contract everyone fills together. A shift lasts fifteen minutes, and then a new one begins from nothing.
6
+
7
+ ## Install
8
+
9
+ ```sh
10
+ npm install @netforge/template-idle
11
+ ```
12
+
13
+ You rarely import this package directly. kit play (`@netforge/kit-play`) and the Net Forge MCP server use it to build and run a game whose `src/game.ts` you write.
14
+
15
+ ## Play it locally
16
+
17
+ ```sh
18
+ mkdir -p my-game/src && cd my-game
19
+ npm init -y && npm install @netforge/kit-play @netforge/engine @netforge/template-idle
20
+ cp node_modules/@netforge/template-idle/src/game.ts src/
21
+ echo '{"template":"idle"}' > netnet.json
22
+ npx kit-play # opens http://127.0.0.1:4663
23
+ ```
24
+
25
+ Open the link in more tabs for more players. Coins are play money. Real-token earning, stakes and claims run only on the hosted Net Forge server.
26
+
27
+ ## Change the game
28
+
29
+ Edit `src/game.ts` and run `npx kit-play` again. For example, make the hand pump cheaper to level for longer:
30
+
31
+ ```ts
32
+ plant("hand_pump", { model: "style.lowpoly.barrel", kind: "pump", cost: 15, growth: 1.1, rate: 3 });
33
+ ```
34
+
35
+ Or lengthen the shift and enlarge the contract in `saltFlat({ ... })`:
36
+
37
+ ```ts
38
+ shift: 1200,
39
+ contract: { crystals: 120 },
40
+ ```
41
+
42
+ Keep the first payout at least 180 s into a fresh works. The build measures it and fails with the number if a change pays sooner.
10
43
 
11
44
  ## Why it cannot be farmed
12
45
 
13
- - Production runs only in the room's sim, on its ticks, for players in the
14
- room. No wall clock, no offline accrual, no client-reported numbers.
15
- - A works stalls two minutes after its last tend (rake, buy, ship): an idle
16
- tab makes nothing.
17
- - Raking has a cooldown; mashing adds nothing.
18
- - Earn rules pay once a run. A seat that leaves and rejoins starts a fresh
19
- works from 20 kg of salt. The genre's gate check simulates a fresh works
20
- with perfect play and with pure raking: the first payout comes 199 s in
21
- (the floor is 180 s), and the most one seat can earn is about 550 coins an
22
- hour even rejoining every time a rule pays, before the per-wallet daily
23
- cap, the free-play lifetime cap and the stake terms. With full shifts the
24
- four rules pay at most 80 coins a shift (320 an hour).
25
- - One earning seat per wallet (the room's seat lock), and the run replays
26
- from its inputs for the referee.
27
-
28
- ## Run it
29
-
30
- This template runs on your own computer with play money through
31
- `kit play` (`@netforge/kit-play`). From the repository root:
46
+ - Production runs only in the room's sim, on its ticks, for players in the room. There is no wall clock, no offline accrual and no client-reported number.
47
+ - A works stalls two minutes after its last tend (rake, buy, ship), so an idle tab makes nothing.
48
+ - Raking has a cooldown, so mashing adds nothing.
49
+ - Earn rules pay once a run. A seat that leaves and rejoins starts a fresh works from 20 kg of salt. The genre's gate check simulates a fresh works with perfect play and with pure raking: the first payout comes 199 s in (the floor is 180 s). With full shifts the four rules pay at most 80 coins a shift.
50
+ - One earning seat per wallet, and the run replays from its inputs for the referee.
51
+
52
+ ## Files
53
+
54
+ | Path | What |
55
+ |---|---|
56
+ | `src/game.ts` | The game, as declarations only. This is the file you edit. |
57
+ | `src/manifest.ts` | Loads the game; `idleAdapter()` for the room host and the client (up to 8 seats). |
58
+ | `src/store.ts` | Coin prices the client is wired to. |
59
+ | `src/autopilot.ts` | The autopilot the browser's `?autopilot=1` and the measure script use. |
60
+ | `client/` | The browser client, drawn with `@netforge/tabletop`. |
61
+ | `test/` | Playtest bots through `engine.test.run`, and the store test. |
62
+ | `llms.txt`, `llms-full.txt` | How to change the game, for agents. |
63
+
64
+ ## Controls
65
+
66
+ Space rakes (or click your plot), 1 to 5 buy a plant, S ships crystals.
67
+
68
+ ## For AI agents
69
+
70
+ Read `AGENTS.md` and `llms.txt` before editing. The Net Forge MCP server gives a coding agent the templates, the API and a playtest loop:
32
71
 
33
72
  ```sh
34
- pnpm install --frozen-lockfile && pnpm build
35
- mkdir -p play-idle/src && cp packages/template-idle/src/game.ts play-idle/src/
36
- echo '{"template":"idle"}' > play-idle/netnet.json
37
- node packages/kit-play/dist/cli.js play-idle # opens http://127.0.0.1:4663
73
+ npx -y @netforge/mcp
38
74
  ```
39
75
 
40
- Edit `play-idle/src/game.ts` and run it again to try a change. Real-token
41
- earning, stakes and claims run only on the hosted Net Forge server.
76
+ The package is `@netforge/mcp` and its bin is `netforge-mcp`. Its tools are `netforge_list_templates`, `netforge_create_game`, `netforge_explain_api`, `netforge_search_docs`, `netforge_validate_game`, `netforge_run_playtest` and `netforge_play_locally`.
77
+
78
+ To set up a coding agent in a game project, run `npx netforge setup agent`. It writes AGENTS.md, CLAUDE.md, Cursor rules and `.mcp.json` into the project. In Claude Code you can also add the server directly with `claude mcp add netforge -- npx -y @netforge/mcp`.
79
+
80
+ ## Docs
81
+
82
+ - https://forge.netnet.capital/docs/templates/idle
83
+ - `llms.txt` and `llms-full.txt` in this package. The full file includes the complete `src/game.ts` and the validate and playtest steps.
84
+
85
+ ## License
42
86
 
43
- Space rakes (or click your plot), 1-5 buy a plant, S ships crystals.
87
+ MIT. See LICENSE and NOTICE.
package/llms-full.txt ADDED
@@ -0,0 +1,209 @@
1
+ # Net Forge idle template (BRINEWORKS)
2
+
3
+ > A shared salt flat for up to 8 players. Each player runs a works on a
4
+ > plot: pumps draw brine, pans boil it into salt, kilns cut salt into
5
+ > crystals, and salt buys and levels more plants. Players rake by hand for
6
+ > salt, and everyone ships crystals to one contract barge. A shift has a
7
+ > fixed length; then a new shift starts from nothing.
8
+ > You change the game by editing src/game.ts only. The template already has
9
+ > the works, the production chain, buying and levelling, raking, tending,
10
+ > the contract, the shift clock, netcode, rendering, earn and the store.
11
+
12
+ ## Files
13
+
14
+ - src/game.ts: THE GAME. game(), saltFlat(), plant(), upgrade(),
15
+ earn.rule(), earn.stake(), store.sku().
16
+ - src/names.json: the title and every label. Plants go in "weapons"
17
+ ({ name, line }); "enemies" stays empty.
18
+
19
+ ## Rules the build enforces (the anti-farm rules)
20
+
21
+ - game({ template: "idle", style, places, players: { prefab, max } }), max at most 8.
22
+ - Exactly one saltFlat(...); 1 to 8 plant(...)s with at least one "pump",
23
+ one "pan" and one "kiln" (the chain).
24
+ - A shift is 600 to 3600 seconds. Every earn rule is oncePer: "run" (a run
25
+ is a shift, or a player's time in it).
26
+ - tend is at most 300 seconds: a works nobody tends stops, so an idle tab
27
+ makes nothing. Production happens only on the room's clock while the
28
+ player is in the room; nothing is earned offline and a player who leaves
29
+ and comes back starts a fresh works.
30
+ - No earn rule may pay sooner than 180 seconds into a fresh works, even
31
+ with perfect play or raking as fast as the cooldown allows. The gate
32
+ measures it; if a draft pays sooner it fails with the number. Raise
33
+ packEvery or the rule's n, or slow raking.
34
+ - Upgrades read three stats: might (plant output), haste (raking speed),
35
+ amount (salt a rake). No weapon() or prefab().
36
+ - An earn rule must fire within about 4 minutes of 4-player play.
37
+
38
+ ## Units
39
+
40
+ Seconds, litres of brine, kg of salt, whole crystals. A plant's rate is a
41
+ second, a level. Costs are kg of salt; each level costs growth times the last.
42
+
43
+ ## Common changes
44
+
45
+ ### Faster or slower progress
46
+ plant("hand_pump", { model: "style.lowpoly.barrel", kind: "pump", cost: 15, growth: 1.15, rate: 3 });
47
+ Lower growth makes levels cheap for longer; a higher rate makes each level count more.
48
+ Keep the first payout at least 180 s away (the gate checks).
49
+
50
+ ### A new plant
51
+ plant("deep_bore", { model: "style.lowpoly.generator_large", kind: "pump", cost: 5000, growth: 1.2, rate: 200 });
52
+ Add its label to names.json weapons. The bar shows plants in order (keys 1-8).
53
+
54
+ ### Longer or shorter shifts
55
+ saltFlat({ shift: 1200, ... }) (600 to 3600 s). A bigger contract: contract: { crystals: 120 }.
56
+
57
+ ### Earn rules
58
+ earn.rule("first_crate", { when: "salt.packed", n: 30, pay: 5, oncePer: "run" });
59
+ Events: salt.packed (one each packEvery kg a player makes), crystal.cut,
60
+ crystal.shipped, plant.built, plant.upgraded (each credits the player),
61
+ contract.filled (the players who shipped to it; world progress, so never a
62
+ player whose run started after the shift began). Pays coins once a run.
63
+
64
+ ### The buy-in run (required)
65
+ earn.stake({ min: 20, max: 200, multiple: 2 }); one top-level line. "stake" is reserved.
66
+
67
+ ### Coins: earn and the store
68
+ store.sku("bellows", { coins: 40 }); // one level of "bellows" for the shift
69
+ store.sku("skin_rust", { coins: 500, grants: { cosmetic: 2 } }); // a finish for your foreman
70
+ store.sku("brass_bellows", { coins: 150, grants: { gear: "bellows", loseBelow: 0.25 } }); // losable gear
71
+ Keep the SKUs the client is wired to (bellows, long_rake, quick_hands,
72
+ skin_saltwhite, skin_rust, brass_bellows) at their prices.
73
+
74
+ ## Test
75
+
76
+ engine.test.run({ ticks: 30 * 240, bots: 4 }) plays the flat and reports
77
+ crates packed (as kills), earned by rule, softlock, ms per tick and the
78
+ genre's checks (the farming bounds) under rules.checks.
79
+
80
+ ## Worked example: src/game.ts
81
+
82
+ This is the template's complete src/game.ts as it ships. A new game on this
83
+ template starts from this file and changes declarations in place.
84
+
85
+ ```ts
86
+ /**
87
+ * BRINEWORKS: the idle template (play style: idle).
88
+ *
89
+ * A white salt flat under a hot sky. Up to eight players each run a works on
90
+ * the flat: pumps draw brine, pans boil it into salt, kilns cut salt into
91
+ * crystals, and salt buys and levels more plants. A barge on the canal
92
+ * takes crystals for a contract everyone fills together. A shift lasts
93
+ * fifteen minutes; then the flat is raked clean and a new shift begins.
94
+ *
95
+ * Works run only while their player is on the flat and has tended them in
96
+ * the last two minutes (a rake, a purchase, a shipment): no offline
97
+ * production, nothing for an idle tab.
98
+ *
99
+ * This file is the whole game as the model writes it: declarations only,
100
+ * against the typed API in @netforge/engine.
101
+ */
102
+ import { earn, game, plant, saltFlat, store, upgrade } from "@netforge/engine";
103
+
104
+ export default game({
105
+ template: "idle",
106
+ style: "lowpoly",
107
+ places: { flat: { chunks: "places/flat", spawn: [0, 0, 0] } },
108
+ players: { prefab: "style.lowpoly.worker", max: 8 },
109
+ });
110
+
111
+ // The flat: a fifteen-minute shift, works that stall two minutes after the last tend,
112
+ // a rake every 0.4 s for 3 kg, 3 L of brine to a kg of salt, 25 kg of salt to a crystal, a crate every 150 kg.
113
+ saltFlat({
114
+ shift: 900,
115
+ tend: 120,
116
+ start: 20,
117
+ rake: { salt: 3, cooldown: 0.4 },
118
+ brinePerSalt: 3,
119
+ saltPerCrystal: 25,
120
+ packEvery: 150,
121
+ contract: { crystals: 60 },
122
+ });
123
+
124
+ // Plants. cost is kg of salt for the first level, growth the price rise a level; rate is a second, a level
125
+ // (pumps: litres of brine; pans: kg of salt boiled; kilns: crystals cut).
126
+ plant("hand_pump", { model: "style.lowpoly.barrel", kind: "pump", cost: 15, growth: 1.15, rate: 3 });
127
+ plant("boil_pan", { model: "style.lowpoly.crate", kind: "pan", cost: 25, growth: 1.15, rate: 1 });
128
+ plant("steam_pump", { model: "style.lowpoly.generator", kind: "pump", cost: 400, growth: 1.18, rate: 30 });
129
+ plant("sun_pan", { model: "style.lowpoly.barrels", kind: "pan", cost: 600, growth: 1.18, rate: 10 });
130
+ plant("crystal_kiln", { model: "style.lowpoly.generator_large", kind: "kiln", cost: 900, growth: 1.25, rate: 0.05 });
131
+
132
+ // Store upgrades: one level each, for the rest of the shift, on the buyer's own works.
133
+ upgrade("bellows", { stat: "might", step: 0.15, maxLevel: 1 });
134
+ upgrade("long_rake", { stat: "amount", step: 0.3, maxLevel: 1 });
135
+ upgrade("quick_hands", { stat: "haste", step: 0.25, maxLevel: 1 });
136
+
137
+ // Earn (mandatory). Pays the game's coins (1 coin = 1 token), once a shift each. Values are PLACEHOLDER.
138
+ earn.rule("first_crate", { when: "salt.packed", n: 30, pay: 5, oncePer: "run" });
139
+ earn.rule("long_haul", { when: "salt.packed", n: 300, pay: 20, oncePer: "run" });
140
+ earn.rule("full_hold", { when: "contract.filled", n: 1, pay: 50, oncePer: "run" });
141
+ earn.rule("cutter", { when: "crystal.cut", n: 30, pay: 5, oncePer: "run" });
142
+ // Buy-in run (the mandatory sink loop): stake coins at shift start to earn above free play. Values are PLACEHOLDER.
143
+ earn.stake({ min: 20, max: 200, multiple: 2 });
144
+
145
+ // Store (the Kit), priced in coins: three shift upgrades, two finishes owned for good, one piece of losable gear.
146
+ store.sku("bellows", { coins: 40 });
147
+ store.sku("long_rake", { coins: 40 });
148
+ store.sku("quick_hands", { coins: 60 });
149
+ store.sku("skin_saltwhite", { coins: 300, grants: { cosmetic: 1 } });
150
+ store.sku("skin_rust", { coins: 500, grants: { cosmetic: 2 } });
151
+ // Losable gear: owned for good until lost. It brings one level of its upgrade into every staked shift,
152
+ // and is lost when that shift makes less than loseBelow of its most earn. Values are PLACEHOLDER.
153
+ store.sku("brass_bellows", { coins: 150, grants: { gear: "bellows", loseBelow: 0.25 } });
154
+ ```
155
+
156
+ ## Validate and playtest
157
+
158
+ ### With the MCP server
159
+
160
+ Run `npx -y @netforge/mcp` (package @netforge/mcp, bin netforge-mcp) and
161
+ connect it to your coding agent. Its tools are netforge_list_templates, netforge_create_game,
162
+ netforge_explain_api, netforge_search_docs, netforge_validate_game, netforge_run_playtest and netforge_play_locally.
163
+
164
+ - netforge_validate_game checks src/game.ts against the engine's schemas and this
165
+ template's rules, and returns one actionable line per problem.
166
+ - netforge_run_playtest plays the game headless with bots and returns the report.
167
+ - netforge_play_locally gives the steps to open the game in a browser with kit play.
168
+
169
+ ### In code
170
+
171
+ Import the game module first so its declarations register, then run the
172
+ headless harness. This plays 4 players for 4 minutes at 30 Hz.
173
+
174
+ ```ts
175
+ import { engine } from "@netforge/engine";
176
+ import "./src/game.js";
177
+
178
+ const report = await engine.test.run({
179
+ ticks: 30 * 240,
180
+ bots: 4,
181
+ seed: 1,
182
+ assert: [
183
+ { name: "earn fired", check: (r) => r.earnEmitted > 0 },
184
+ { name: "no softlock", check: (r) => !r.softlock },
185
+ ],
186
+ });
187
+ if (report.failed.length > 0) throw new Error(report.failed.join("\n"));
188
+ ```
189
+
190
+ The report has crates packed (as kills), earned by rule, softlock, ms per tick and the genre's checks (the farming bounds) under rules.checks.
191
+
192
+ The template's own tests (vitest) are the reference checks:
193
+
194
+ - test/harness.test.ts
195
+ - test/store.test.ts
196
+
197
+ ### Play it locally
198
+
199
+ In a folder with netnet.json and src/game.ts:
200
+
201
+ ```sh
202
+ npm install @netforge/kit-play @netforge/engine @netforge/template-idle
203
+ echo '{"template":"idle"}' > netnet.json
204
+ npx kit-play # opens http://127.0.0.1:4663
205
+ ```
206
+
207
+ kit play builds the template client with your src/game.ts and runs a local
208
+ room host with play money. No wallet, no chain and no hosted servers are
209
+ involved. Open the link in more tabs for more players.
package/llms.txt CHANGED
@@ -1,4 +1,4 @@
1
- # BRINEWORKS: the idle template (NetNet game runtime, board genre)
1
+ # Net Forge idle template (BRINEWORKS)
2
2
 
3
3
  > A shared salt flat for up to 8 players. Each player runs a works on a
4
4
  > plot: pumps draw brine, pans boil it into salt, kilns cut salt into
package/package.json CHANGED
@@ -1,12 +1,34 @@
1
1
  {
2
2
  "name": "@netforge/template-idle",
3
- "version": "0.1.0",
4
- "description": "BRINEWORKS: the idle template of the NetNet game runtime, a shared salt flat for up to eight: pump brine, boil salt, cut crystals, fill the contract together. The game module, its browser client and its playtest bots.",
3
+ "version": "0.2.0",
4
+ "description": "Shared idle game template for Net Forge: up to 8 players pump, boil and cut salt to fill a contract together (BRINEWORKS).",
5
+ "keywords": [
6
+ "game-template",
7
+ "multiplayer",
8
+ "browser-game",
9
+ "html5-game",
10
+ "threejs",
11
+ "game-engine",
12
+ "typescript",
13
+ "gamedev",
14
+ "ai-agents",
15
+ "mcp",
16
+ "net-forge",
17
+ "idle-game"
18
+ ],
5
19
  "license": "MIT",
6
20
  "type": "module",
21
+ "sideEffects": [
22
+ "./src/game.ts",
23
+ "./src/manifest.ts",
24
+ "./client/**"
25
+ ],
7
26
  "exports": {
8
27
  ".": "./src/manifest.ts",
9
- "./store": "./src/store.ts"
28
+ "./store": "./src/store.ts",
29
+ "./package.json": "./package.json",
30
+ "./llms.txt": "./llms.txt",
31
+ "./llms-full.txt": "./llms-full.txt"
10
32
  },
11
33
  "files": [
12
34
  "src",
@@ -15,26 +37,32 @@
15
37
  "llms.txt",
16
38
  "README.md",
17
39
  "NOTICE",
18
- "LICENSE"
40
+ "LICENSE",
41
+ "llms-full.txt",
42
+ "AGENTS.md",
43
+ "CLAUDE.md"
19
44
  ],
20
45
  "publishConfig": {
21
46
  "access": "public"
22
47
  },
48
+ "homepage": "https://forge.netnet.capital/docs/templates/idle",
49
+ "bugs": {
50
+ "url": "https://github.com/netnetdev/net-forge/issues"
51
+ },
23
52
  "repository": {
24
53
  "type": "git",
25
54
  "url": "git+https://github.com/netnetdev/net-forge.git",
26
55
  "directory": "packages/template-idle"
27
56
  },
28
- "homepage": "https://github.com/netnetdev/net-forge/tree/main/packages/template-idle#readme",
29
57
  "engines": {
30
58
  "node": ">=20"
31
59
  },
32
60
  "dependencies": {
33
61
  "three": "0.186.1",
34
- "@netforge/asset-library": "0.1.0",
35
- "@netforge/engine-sim": "0.1.0",
36
- "@netforge/engine": "0.1.0",
37
- "@netforge/tabletop": "0.1.0"
62
+ "@netforge/asset-library": "0.2.0",
63
+ "@netforge/tabletop": "0.2.0",
64
+ "@netforge/engine": "0.2.0",
65
+ "@netforge/engine-sim": "0.2.0"
38
66
  },
39
67
  "devDependencies": {
40
68
  "@types/node": "22.20.1",
@@ -44,9 +72,6 @@
44
72
  "vite": "6.4.3",
45
73
  "vitest": "3.2.7"
46
74
  },
47
- "bugs": {
48
- "url": "https://github.com/netnetdev/net-forge/issues"
49
- },
50
75
  "scripts": {
51
76
  "build": "node ../engine/scripts/fresh-dist.mjs && vite build --config client/vite.config.ts",
52
77
  "typecheck": "tsc -p tsconfig.json",