grinders-farm 0.3.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.
Files changed (77) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +135 -0
  3. package/SKILL.md +142 -0
  4. package/dist/scripts/generate-tiles.d.ts +2 -0
  5. package/dist/scripts/generate-tiles.d.ts.map +1 -0
  6. package/dist/scripts/generate-tiles.js +138 -0
  7. package/dist/scripts/generate-tiles.js.map +1 -0
  8. package/dist/src/adapters/auto-worker.d.ts +2 -0
  9. package/dist/src/adapters/auto-worker.d.ts.map +1 -0
  10. package/dist/src/adapters/auto-worker.js +79 -0
  11. package/dist/src/adapters/auto-worker.js.map +1 -0
  12. package/dist/src/adapters/daemon.d.ts +6 -0
  13. package/dist/src/adapters/daemon.d.ts.map +1 -0
  14. package/dist/src/adapters/daemon.js +6 -0
  15. package/dist/src/adapters/daemon.js.map +1 -0
  16. package/dist/src/adapters/image-server.d.ts +2 -0
  17. package/dist/src/adapters/image-server.d.ts.map +1 -0
  18. package/dist/src/adapters/image-server.js +90 -0
  19. package/dist/src/adapters/image-server.js.map +1 -0
  20. package/dist/src/adapters/oneshot.d.ts +2 -0
  21. package/dist/src/adapters/oneshot.d.ts.map +1 -0
  22. package/dist/src/adapters/oneshot.js +36 -0
  23. package/dist/src/adapters/oneshot.js.map +1 -0
  24. package/dist/src/adapters/terminal.d.ts +2 -0
  25. package/dist/src/adapters/terminal.d.ts.map +1 -0
  26. package/dist/src/adapters/terminal.js +70 -0
  27. package/dist/src/adapters/terminal.js.map +1 -0
  28. package/dist/src/game/crops.d.ts +8 -0
  29. package/dist/src/game/crops.d.ts.map +1 -0
  30. package/dist/src/game/crops.js +71 -0
  31. package/dist/src/game/crops.js.map +1 -0
  32. package/dist/src/game/engine.d.ts +15 -0
  33. package/dist/src/game/engine.d.ts.map +1 -0
  34. package/dist/src/game/engine.js +236 -0
  35. package/dist/src/game/engine.js.map +1 -0
  36. package/dist/src/game/farm.d.ts +12 -0
  37. package/dist/src/game/farm.d.ts.map +1 -0
  38. package/dist/src/game/farm.js +387 -0
  39. package/dist/src/game/farm.js.map +1 -0
  40. package/dist/src/game/types.d.ts +70 -0
  41. package/dist/src/game/types.d.ts.map +1 -0
  42. package/dist/src/game/types.js +23 -0
  43. package/dist/src/game/types.js.map +1 -0
  44. package/dist/src/index.d.ts +9 -0
  45. package/dist/src/index.d.ts.map +1 -0
  46. package/dist/src/index.js +8 -0
  47. package/dist/src/index.js.map +1 -0
  48. package/dist/src/local-auto.d.ts +13 -0
  49. package/dist/src/local-auto.d.ts.map +1 -0
  50. package/dist/src/local-auto.js +239 -0
  51. package/dist/src/local-auto.js.map +1 -0
  52. package/dist/src/notify/openclaw-delivery.d.ts +36 -0
  53. package/dist/src/notify/openclaw-delivery.d.ts.map +1 -0
  54. package/dist/src/notify/openclaw-delivery.js +104 -0
  55. package/dist/src/notify/openclaw-delivery.js.map +1 -0
  56. package/dist/src/notify/openclaw-push.d.ts +49 -0
  57. package/dist/src/notify/openclaw-push.d.ts.map +1 -0
  58. package/dist/src/notify/openclaw-push.js +451 -0
  59. package/dist/src/notify/openclaw-push.js.map +1 -0
  60. package/dist/src/render/ansi-renderer.d.ts +6 -0
  61. package/dist/src/render/ansi-renderer.d.ts.map +1 -0
  62. package/dist/src/render/ansi-renderer.js +41 -0
  63. package/dist/src/render/ansi-renderer.js.map +1 -0
  64. package/dist/src/render/image-renderer.d.ts +3 -0
  65. package/dist/src/render/image-renderer.d.ts.map +1 -0
  66. package/dist/src/render/image-renderer.js +174 -0
  67. package/dist/src/render/image-renderer.js.map +1 -0
  68. package/dist/src/render/text-renderer.d.ts +3 -0
  69. package/dist/src/render/text-renderer.d.ts.map +1 -0
  70. package/dist/src/render/text-renderer.js +73 -0
  71. package/dist/src/render/text-renderer.js.map +1 -0
  72. package/dist/src/storage/local-storage.d.ts +15 -0
  73. package/dist/src/storage/local-storage.d.ts.map +1 -0
  74. package/dist/src/storage/local-storage.js +115 -0
  75. package/dist/src/storage/local-storage.js.map +1 -0
  76. package/package.json +44 -0
  77. package/src/notify/notify.json.example +3 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Grinder's Farm contributors
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,135 @@
1
+ # 🌿 Grinder's Farm
2
+
3
+ 像素风种田模拟:种植、浇水、自动推进天数、收获并出售。状态与渲染全部在**本机**完成;OpenClaw 等端只通过插件/CLI **调起**游戏逻辑,**不依赖大模型、无远程游戏后端**。
4
+
5
+ ## End-User Install (No Build)
6
+
7
+ 面向普通用户的安装不需要 clone 仓库,也不需要本地 build:
8
+
9
+ ```bash
10
+ npm install -g grinders-farm
11
+ openclaw plugins install openclaw-plugin-grinders-farm --dangerously-force-unsafe-install
12
+ # skill 发布到 ClawHub 后:
13
+ # openclaw skills install grinders-farm
14
+ ```
15
+
16
+ 安装后直接使用:
17
+
18
+ - 在任意聊天先执行一次 `/farm farm`(绑定推送频道)
19
+ - 执行 `/farm start`(固定 20 秒/天,自动推送到所有已绑定频道)
20
+ - 执行 `/farm stop`(停止)
21
+
22
+ ## Developer Quick Start
23
+
24
+ ```bash
25
+ npm install
26
+ npm run generate-tiles # 生成像素地块素材
27
+ npm run dev # 终端交互模式
28
+ ```
29
+
30
+ ## Commands
31
+
32
+ | Command | Description |
33
+ |---------|-------------|
34
+ | `farm` / `status` | View your farm (renders a PNG image + text) |
35
+ | `plant <crop> <pos>` | Plant a crop, e.g. `plant carrot A1` |
36
+ | `water [pos]` | Water a plot, or all plots if no position given |
37
+ | `harvest [pos]` | Harvest a ready crop, or all ready crops |
38
+ | `shop` | View seed shop with prices |
39
+ | `sell` | Sell everything in your inventory |
40
+ | `inventory` / `inv` | View inventory |
41
+ | `start` | Start local auto worker (fixed **20s/day**). Auto-pushes to all bound channels |
42
+ | `stop` | Stop local auto worker |
43
+ | `reset` | Start over |
44
+ | `help` | Show help |
45
+ | `quit` / `exit` | Exit the game (terminal mode only) |
46
+
47
+ ## Available Crops
48
+
49
+ | Crop | Growth | Seed Cost | Sell Price |
50
+ |------|--------|-----------|------------|
51
+ | 🥕 Carrot | 5 days | 5G | 11G |
52
+ | 🥔 Potato | 7 days | 8G | 22G |
53
+ | 🍅 Tomato | 6 days | 9G | 24G |
54
+ | 🎃 Pumpkin | 8 days | 12G | 34G |
55
+
56
+ Growth art stages now map to `seed -> sprout -> growing_1 -> growing_2 -> ready`, and in-game growth days are scaled proportionally from real-world maturity time.
57
+
58
+ ## How It Works
59
+
60
+ 1. You start with a 4×5 grid and 50G
61
+ 2. Buy seeds from the shop and plant them on empty plots
62
+ 3. Water your crops each day — unwatered crops don't grow
63
+ 4. After enough days, crops become ready to harvest
64
+ 5. Harvest and sell for gold, then plant more
65
+
66
+ ## Local Files
67
+
68
+ | Path | Purpose |
69
+ |------|---------|
70
+ | `~/.grinders-farm/farm.json` | Save game |
71
+ | `~/.grinders-farm/farm.png` | Latest rendered farm image |
72
+ | `~/.grinders-farm/image-server.pid` / `image-server.json` | Local image HTTP server metadata (for clickable PNG URL in OpenClaw) |
73
+ | `~/.grinders-farm/auto.pid` / `auto.config.json` | Local auto-advance worker (when running) |
74
+ | `~/.grinders-farm/auto.log` | Optional log from the auto worker |
75
+ | `~/.grinders-farm/openclaw-delivery.json` | Auto-written when you use `/farm` in OpenClaw (push target) |
76
+ | `~/.grinders-farm/openclaw-deliveries.json` | Auto-written binding list (fan-out auto-push to all bound channels) |
77
+
78
+ ## OpenClaw
79
+
80
+ - **Skill**: `SKILL.md`(推荐走 ClawHub 安装)
81
+ - Plugin runtime auto-detects in this order: `GRINDERS_FARM_ROOT` → plugin `gameRoot` → plugin parent directory → `grinders-farm` CLI in `PATH` (`GRINDERS_FARM_CLI_BIN` override).
82
+ - 对外安装推荐走 npm 包:`openclaw-plugin-grinders-farm`,无需源码路径。
83
+ - Plugin will start a local image server on Gateway boot (default `http://127.0.0.1:18931/farm.png`) so status output uses a clickable URL instead of `file://...`.
84
+ - **Proactive push (OpenClaw)**: In every channel you want to receive pushes, send **`/farm …` once**. Plugin records them in `~/.grinders-farm/openclaw-deliveries.json`. After `/farm start`, each auto-advance tick fan-outs to all recorded channels. Stop worker: `/farm stop`.
85
+
86
+ ## OpenClaw Plugin Release Notes
87
+
88
+ - Plugin package: `openclaw-plugin/` (contains `openclaw.plugin.json`, `README.md`, `LICENSE`).
89
+ - Root package exports runnable CLI (`grinders-farm`) and includes only release files via `package.json.files`.
90
+ - Plugin package is precompiled (`openclaw-plugin/dist/`) for npm install; end users do not build.
91
+ - Skill sync script is cross-machine (`npm run sync-skill`), no Homebrew-only hardcoded path.
92
+ - Recommended validation before publishing:
93
+ - `npm run build`
94
+ - `(cd openclaw-plugin && npm run build)`
95
+ - `npx tsx src/adapters/oneshot.ts help`
96
+ - OpenClaw smoke test: `/farm farm`, `/farm start`, `/farm stop`
97
+
98
+ ## Architecture
99
+
100
+ ```
101
+ src/
102
+ ├── game/ # Core rules (pure logic + command router)
103
+ │ ├── types.ts
104
+ │ ├── crops.ts
105
+ │ ├── farm.ts
106
+ │ └── engine.ts
107
+ ├── local-auto.ts # Spawn/stop local auto worker (no OpenClaw cron)
108
+ ├── notify/ # openclaw message send integration
109
+ ├── render/ # Text + PNG output
110
+ ├── storage/ # ~/.grinders-farm JSON persistence
111
+ └── adapters/
112
+ ├── oneshot.ts # Single command (used by OpenClaw plugin)
113
+ ├── auto-worker.ts # Background loop: auto-advance on an interval
114
+ ├── daemon.ts # Dev helper → auto-worker @ 10s
115
+ └── terminal.ts # Interactive CLI
116
+ ```
117
+
118
+ ## Scripts
119
+
120
+ | Script | Purpose |
121
+ |--------|---------|
122
+ | `npm run dev` | Interactive terminal game |
123
+ | `npm run daemon` | Auto-advance every **10s** (dev) |
124
+ | `npm run auto-worker -- 3600` | Run worker directly (e.g. 3600s interval) |
125
+ | `npm run sync-skill` | Copy `SKILL.md` to OpenClaw skills dir (portable path detection) |
126
+
127
+ ## Tech Stack
128
+
129
+ - TypeScript + ESM
130
+ - @napi-rs/canvas for image rendering
131
+ - Local JSON file storage
132
+
133
+ ## License
134
+
135
+ MIT
package/SKILL.md ADDED
@@ -0,0 +1,142 @@
1
+ ---
2
+ name: grinders-farm
3
+ description: "Pixel-art farm simulation game. Use when: user wants to play a farming game, plant/water/harvest crops, manage a virtual farm, or mentions grinders-farm/农场游戏. NOT for: real agriculture, finance, or weather queries."
4
+ metadata: { "openclaw": { "emoji": "🌾", "requires": { "bins": ["npx"] } } }
5
+ command-dispatch: tool
6
+ command-tool: grinders_farm
7
+ disable-model-invocation: false
8
+ ---
9
+
10
+ # Grinder's Farm
11
+
12
+ 本地确定性农场游戏:状态在 `~/.grinders-farm/`。模型负责把自然语言映射成命令并调用 `grinders_farm` tool;游戏逻辑仍在本地 CLI 子进程执行。
13
+
14
+ ## 架构(重要)
15
+
16
+ - **游戏与存档**:全部在本地进程内完成(`npx tsx src/adapters/oneshot.ts …`)。
17
+ - **OpenClaw**:只负责把 `/farm`、`/grinders_farm …` 转到插件里注册的 **tool / command**,直接执行上述 CLI,**不经过模型推理**。
18
+ - **自动推进**:`start` 在本地启动后台 worker(`src/adapters/auto-worker.ts`),固定每 20 秒推进一天;**不使用** OpenClaw cron,也**不**向 agent 注入 system-event。
19
+
20
+ ## When to Use
21
+
22
+ - "我想玩农场游戏" / "play farm game"
23
+ - "种点什么" / "plant something"
24
+ - "看看我的农场" / "show my farm"
25
+ - "浇水" / "water crops"
26
+ - "收获" / "harvest"
27
+ - Any mention of grinders-farm
28
+ - 用户用自然语言要求执行农场动作(如“在 A4 种胡萝卜”“帮我浇水”)
29
+
30
+ ## Invocation Rule (Critical)
31
+
32
+ - 当用户意图是执行农场命令时,必须直接调用 `grinders_farm` tool(`command` 参数传原始命令),不要只返回解释性文字。
33
+ - 禁止改用 `exec` / shell / `cargo run` 等其他工具路径执行农场命令;农场命令统一走 `grinders_farm`。
34
+ - 例如:
35
+ - “给我的农场在 A4 种一个胡萝卜” → `command: "plant carrot A4"`
36
+ - “看看我的农场” → `command: "farm"`
37
+ - “全部浇水” → `command: "water"`
38
+
39
+ ## When NOT to Use
40
+
41
+ - Real agricultural data or finance (use farmos-finance)
42
+ - Weather queries (use weather skill)
43
+ - Animal/livestock management (not implemented yet)
44
+
45
+ ## Display Rules
46
+
47
+ Command output includes two parts:
48
+
49
+ 1. **Emoji farm grid** (markdown table) — the primary visual. Copy the table AS-IS into your reply so it renders with proper alignment.
50
+ 2. **Pixel art link** — prefer local HTTP URL (for OpenClaw clickability), fallback to `file://` URI.
51
+
52
+ Formatting rules:
53
+
54
+ - The emoji grid is already a markdown table — paste it directly, do NOT wrap it in a code fence
55
+ - Do NOT wrap the pixel art link in backticks or code — keep it as a raw URL so it is clickable
56
+ - Present both in your reply: first the emoji grid table, then the link at the end
57
+
58
+ ## Commands
59
+
60
+ ### View Farm
61
+
62
+ - tool call: `command: "farm"`
63
+
64
+ ### Plant
65
+
66
+ - tool call: `command: "plant <crop> <pos>"`
67
+ - example: `command: "plant carrot A1"`
68
+
69
+ Crops: `carrot` (5d, 5→11G), `potato` (7d, 8→22G), `tomato` (6d, 9→24G), `pumpkin` (8d, 12→34G)
70
+
71
+ ### Water
72
+
73
+ - tool call: `command: "water"` 或 `command: "water A1"`(单格)
74
+
75
+ Unwatered crops do NOT grow. Water daily.
76
+
77
+ ### Harvest
78
+
79
+ - tool call: `command: "harvest"` 或 `command: "harvest A1"`(单格)
80
+
81
+ ### Sell / Shop / Inventory
82
+
83
+ - `command: "sell"`
84
+ - `command: "shop"`
85
+ - `command: "inventory"`
86
+
87
+ ### Auto-Advance(本地后台,不经模型)
88
+
89
+ 固定每 **20 秒** 推进游戏内一天。
90
+
91
+ - `command: "start"`
92
+ - `command: "stop"`
93
+
94
+ ### 在 OpenClaw 里:自动后台 + 定时推送(推荐,无需手填收件人)
95
+
96
+ 1. 每个你希望接收推送的频道里,先发一次 **`/farm …`**(或任意入站消息触发绑定),插件会把会话写入 `~/.grinders-farm/openclaw-deliveries.json`。`~/.grinders-farm/openclaw-delivery.json` 仍保留为单目标兼容。
97
+ 2. 执行 **`/farm start`** 后,本地 worker 固定每 20 秒推进一天;每次推进成功后会自动推送当前农场到**所有已绑定频道**(**不经模型**)。Telegram 等使用 `openclaw message send`,webchat 使用 Gateway **`chat.inject`**。
98
+ 3. **停止自动推进**:`/farm stop`(与 CLI 一致)。
99
+
100
+ ### Reset
101
+
102
+ - `command: "reset"`
103
+
104
+ ## Grid
105
+
106
+ 4 rows (A-D) × 5 columns (1-5). Positions: `A1`, `B3`, `D5`.
107
+
108
+ ## Game Loop
109
+
110
+ 1. Start: 50G, 4×5 empty grid
111
+ 2. `shop` → pick crop → `plant <crop> <pos>`
112
+ 3. `water` → 等待自动推进(repeat daily)
113
+ 4. When ready → `harvest` → `sell`
114
+
115
+ ## Natural Language Mapping
116
+
117
+ 若用户自由打字,也应优先直接调用 `grinders_farm` tool;用户手动输入 **`/farm …`** 或 **`/grinders_farm …`** 也可。
118
+
119
+ - "种胡萝卜在A1" → `plant carrot A1`
120
+ - "全部浇水" → `water`
121
+ - "收获所有" → `harvest`
122
+ - "卖掉" → `sell`
123
+ - "买什么好" → run `shop`, then recommend based on gold
124
+ - "开启自动模式" / "start auto" → `start`
125
+ - "停止自动" / "stop auto" → `stop`
126
+
127
+ ## OpenClaw 集成
128
+
129
+ 1. 安装并启用 `openclaw-plugin-grinders-farm`(或开发模式下本仓库 `openclaw-plugin/`)。插件注册:
130
+ - **`grinders_farm` tool** — 与 frontmatter 中 `command-dispatch: tool` / `command-tool` 配合,使 slash 直达工具执行。
131
+ - **`/farm`** — 插件命令,直接跑 `oneshot.ts`,并写入 `openclaw-delivery.json`(兼容)+ `openclaw-deliveries.json`(多频道 fan-out)供推送使用。
132
+ 2. 修改 Gateway 配置后重启。插件会按顺序自动定位运行时:`GRINDERS_FARM_ROOT` → `plugins.entries.grinders-farm.config.gameRoot` → 插件父目录 → `PATH` 中的 `grinders-farm`(可用 `GRINDERS_FARM_CLI_BIN` 覆盖)。若自动定位失败,再显式设置 `gameRoot`。可选:`autoStartWorkerOnGatewayBoot`、`imageServerPort`。
133
+ 3. `disable-model-invocation: false` 允许模型在自然语言对话中直接调用本 skill 的 `grinders_farm` tool;slash / 插件命令仍可用。
134
+
135
+ ## Notes
136
+
137
+ - State: `~/.grinders-farm/farm.json`
138
+ - PNG: `~/.grinders-farm/farm.png`(多数会改变状态的命令后会更新)
139
+ - Local image URL (plugin auto-start): `http://127.0.0.1:18931/farm.png`(可在 plugin config 里改端口 `imageServerPort`)
140
+ - 本地自动推进日志(可选):`~/.grinders-farm/auto.log`
141
+ - 推送会话:`~/.grinders-farm/openclaw-deliveries.json`(由 `/farm` 自动累积);兼容文件 `~/.grinders-farm/openclaw-delivery.json`
142
+ - 终端快速测试自动:`npm run daemon`(10 秒/天)
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=generate-tiles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-tiles.d.ts","sourceRoot":"","sources":["../../scripts/generate-tiles.ts"],"names":[],"mappings":""}
@@ -0,0 +1,138 @@
1
+ import { createCanvas } from "@napi-rs/canvas";
2
+ import * as fs from "node:fs";
3
+ import * as path from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
6
+ const TILE = 16;
7
+ const ASSETS = path.join(__dirname, "..", "assets", "tiles");
8
+ function ensureDir(dir) {
9
+ if (!fs.existsSync(dir))
10
+ fs.mkdirSync(dir, { recursive: true });
11
+ }
12
+ function drawTile(spec) {
13
+ const canvas = createCanvas(TILE, TILE);
14
+ const ctx = canvas.getContext("2d");
15
+ ctx.clearRect(0, 0, TILE, TILE);
16
+ for (const [x, y, color] of spec.pixels) {
17
+ ctx.fillStyle = color;
18
+ ctx.fillRect(x, y, 1, 1);
19
+ }
20
+ const dir = path.join(ASSETS, spec.dir);
21
+ ensureDir(dir);
22
+ const buf = canvas.toBuffer("image/png");
23
+ fs.writeFileSync(path.join(dir, `${spec.name}.png`), buf);
24
+ }
25
+ function rect(x, y, w, h, color) {
26
+ const pixels = [];
27
+ for (let dx = 0; dx < w; dx++) {
28
+ for (let dy = 0; dy < h; dy++) {
29
+ pixels.push([x + dx, y + dy, color]);
30
+ }
31
+ }
32
+ return pixels;
33
+ }
34
+ function terrainTiles() {
35
+ // empty plot - brown soil
36
+ drawTile({
37
+ dir: "terrain",
38
+ name: "empty",
39
+ pixels: [
40
+ ...rect(0, 0, 16, 16, "#8B6914"),
41
+ ...rect(1, 1, 14, 14, "#A0782C"),
42
+ ...rect(3, 7, 2, 1, "#8B6914"),
43
+ ...rect(8, 4, 2, 1, "#8B6914"),
44
+ ...rect(12, 10, 2, 1, "#8B6914"),
45
+ ...rect(5, 12, 2, 1, "#8B6914"),
46
+ ],
47
+ });
48
+ // watered plot - darker soil
49
+ drawTile({
50
+ dir: "terrain",
51
+ name: "watered",
52
+ pixels: [
53
+ ...rect(0, 0, 16, 16, "#5C4410"),
54
+ ...rect(1, 1, 14, 14, "#6B5220"),
55
+ ...rect(3, 7, 2, 1, "#4A3A10"),
56
+ ...rect(8, 4, 2, 1, "#4A3A10"),
57
+ ...rect(12, 10, 2, 1, "#4A3A10"),
58
+ ...rect(5, 12, 2, 1, "#4A3A10"),
59
+ ],
60
+ });
61
+ }
62
+ const CROP_COLORS = {
63
+ carrot: { stem: "#2D8B2D", body: "#FF8C00", accent: "#FFA500" },
64
+ potato: { stem: "#2D6B2D", body: "#B58A5A", accent: "#D2A679" },
65
+ tomato: { stem: "#2D8B2D", body: "#E53935", accent: "#FF6F61" },
66
+ pumpkin: { stem: "#2D6B2D", body: "#FF6600", accent: "#FF8C00" },
67
+ };
68
+ function cropTiles() {
69
+ for (const [cropId, colors] of Object.entries(CROP_COLORS)) {
70
+ // seed stage - small dot in soil
71
+ drawTile({
72
+ dir: "crops",
73
+ name: `${cropId}_seed`,
74
+ pixels: [
75
+ ...rect(0, 0, 16, 16, "#A0782C"),
76
+ ...rect(7, 10, 2, 2, "#5C3A10"),
77
+ ...rect(7, 9, 2, 1, colors.body),
78
+ ],
79
+ });
80
+ // sprout - small green shoot
81
+ drawTile({
82
+ dir: "crops",
83
+ name: `${cropId}_sprout`,
84
+ pixels: [
85
+ ...rect(0, 0, 16, 16, "#A0782C"),
86
+ ...rect(7, 12, 2, 2, "#5C3A10"),
87
+ ...rect(7, 8, 2, 4, colors.stem),
88
+ ...rect(6, 7, 1, 2, colors.stem),
89
+ ...rect(9, 8, 1, 1, colors.stem),
90
+ ],
91
+ });
92
+ // growing stage 1 - medium plant
93
+ drawTile({
94
+ dir: "crops",
95
+ name: `${cropId}_growing_1`,
96
+ pixels: [
97
+ ...rect(0, 0, 16, 16, "#A0782C"),
98
+ ...rect(7, 13, 2, 2, "#5C3A10"),
99
+ ...rect(7, 6, 2, 7, colors.stem),
100
+ ...rect(5, 5, 6, 3, colors.stem),
101
+ ...rect(6, 4, 4, 2, colors.body),
102
+ ...rect(7, 3, 2, 1, colors.accent),
103
+ ],
104
+ });
105
+ // growing stage 2 - almost mature
106
+ drawTile({
107
+ dir: "crops",
108
+ name: `${cropId}_growing_2`,
109
+ pixels: [
110
+ ...rect(0, 0, 16, 16, "#A0782C"),
111
+ ...rect(7, 14, 2, 2, "#5C3A10"),
112
+ ...rect(7, 6, 2, 8, colors.stem),
113
+ ...rect(5, 4, 6, 3, colors.stem),
114
+ ...rect(5, 2, 6, 3, colors.body),
115
+ ...rect(6, 1, 4, 1, colors.accent),
116
+ ],
117
+ });
118
+ // ready - full plant with vibrant crop color
119
+ drawTile({
120
+ dir: "crops",
121
+ name: `${cropId}_ready`,
122
+ pixels: [
123
+ ...rect(0, 0, 16, 16, "#A0782C"),
124
+ ...rect(7, 14, 2, 2, "#5C3A10"),
125
+ ...rect(7, 6, 2, 8, colors.stem),
126
+ ...rect(5, 5, 6, 2, colors.stem),
127
+ ...rect(4, 2, 8, 4, colors.body),
128
+ ...rect(5, 1, 6, 2, colors.accent),
129
+ ...rect(6, 0, 4, 1, colors.accent),
130
+ ],
131
+ });
132
+ }
133
+ }
134
+ console.log("Generating tiles...");
135
+ terrainTiles();
136
+ cropTiles();
137
+ console.log("Done! Tiles written to assets/tiles/");
138
+ //# sourceMappingURL=generate-tiles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-tiles.js","sourceRoot":"","sources":["../../scripts/generate-tiles.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=auto-worker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-worker.d.ts","sourceRoot":"","sources":["../../../src/adapters/auto-worker.ts"],"names":[],"mappings":""}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Background worker: advances one in-game day every `intervalSec` seconds.
3
+ * Writes ~/.grinders-farm/auto.pid and auto.config.json — no OpenClaw, no LLM.
4
+ */
5
+ import * as fs from "node:fs";
6
+ import * as os from "node:os";
7
+ import * as path from "node:path";
8
+ import { GameEngine } from "../game/engine.js";
9
+ import { LocalStorage } from "../storage/local-storage.js";
10
+ import { loadNotifyConfig, pushFarmSnapshot, shouldNotifyOnAutoAdvance } from "../notify/openclaw-push.js";
11
+ const DATA_DIR = path.join(os.homedir(), ".grinders-farm");
12
+ const PID_FILE = path.join(DATA_DIR, "auto.pid");
13
+ const CONFIG_FILE = path.join(DATA_DIR, "auto.config.json");
14
+ const LOG_FILE = path.join(DATA_DIR, "auto.log");
15
+ const intervalSec = Math.max(1, parseInt(process.argv[2] ?? "3600", 10));
16
+ fs.mkdirSync(DATA_DIR, { recursive: true });
17
+ fs.writeFileSync(PID_FILE, String(process.pid), "utf8");
18
+ fs.writeFileSync(CONFIG_FILE, JSON.stringify({ intervalSec, startedAt: new Date().toISOString(), pid: process.pid }, null, 2), "utf8");
19
+ function log(line) {
20
+ const entry = `[${new Date().toISOString()}] ${line}\n`;
21
+ try {
22
+ fs.appendFileSync(LOG_FILE, entry, "utf8");
23
+ }
24
+ catch {
25
+ /* ignore */
26
+ }
27
+ }
28
+ function cleanup() {
29
+ try {
30
+ fs.unlinkSync(PID_FILE);
31
+ }
32
+ catch {
33
+ /* ignore */
34
+ }
35
+ try {
36
+ fs.unlinkSync(CONFIG_FILE);
37
+ }
38
+ catch {
39
+ /* ignore */
40
+ }
41
+ process.exit(0);
42
+ }
43
+ process.on("SIGINT", cleanup);
44
+ process.on("SIGTERM", cleanup);
45
+ log(`started pid=${process.pid} intervalSec=${intervalSec}`);
46
+ async function tick() {
47
+ // Recreate engine each tick so manual commands (plant/water/harvest) written by
48
+ // other processes are picked up from ~/.grinders-farm/farm.json.
49
+ const storage = new LocalStorage();
50
+ const engine = new GameEngine(storage);
51
+ const result = await engine.advanceDay();
52
+ log(result.success ? "auto advance ok" : `auto advance fail: ${result.message.slice(0, 200)}`);
53
+ if (!result.success)
54
+ return;
55
+ if (!shouldNotifyOnAutoAdvance()) {
56
+ const cfg = loadNotifyConfig();
57
+ if (!cfg) {
58
+ log("notify skipped: no delivery config。在聊天发 /farm 或设 GRINDERS_FARM_NOTIFY_TARGET(见 SKILL)。");
59
+ }
60
+ else if (cfg.onAutoAdvance === false) {
61
+ log("notify skipped: onAutoAdvance 已关闭(notify.json 或环境变量)");
62
+ }
63
+ else {
64
+ log("notify skipped");
65
+ }
66
+ return;
67
+ }
68
+ try {
69
+ const push = await pushFarmSnapshot();
70
+ log(push.ok ? "notify ok" : `notify skip/fail: ${push.message.slice(0, 300)}`);
71
+ }
72
+ catch (err) {
73
+ log(`notify error: ${err instanceof Error ? err.message : String(err)}`);
74
+ }
75
+ }
76
+ setInterval(() => {
77
+ tick().catch((err) => log(`tick error: ${err instanceof Error ? err.message : String(err)}`));
78
+ }, intervalSec * 1000);
79
+ //# sourceMappingURL=auto-worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-worker.js","sourceRoot":"","sources":["../../../src/adapters/auto-worker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * 开发用:默认每 10 秒推进一天(与 `npm run auto-worker -- 10` 相同)。
3
+ * 生产节奏请用:`start`(固定 20 秒)。
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=daemon.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../../../src/adapters/daemon.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,CAAC"}
@@ -0,0 +1,6 @@
1
+ if (process.argv[2] === undefined) {
2
+ process.argv[2] = "10";
3
+ }
4
+ await import("./auto-worker.js");
5
+ export {};
6
+ //# sourceMappingURL=daemon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../../src/adapters/daemon.ts"],"names":[],"mappings":"AAMA,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;IAClC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;AACzB,CAAC;AACD,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=image-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-server.d.ts","sourceRoot":"","sources":["../../../src/adapters/image-server.ts"],"names":[],"mappings":""}