移除行动点系统,倒计时本地走秒,字体优化

为什么:游戏的时间(40 分钟一天、只能自然流动)本身就是唯一的行动节奏
阀门,再叠一层"每天 10 点行动点"纯属重复惩罚——浇水还要体力既不拟真
也不好玩。删掉之后,稀缺的只剩时间本身,放置玩法的定位反而更纯粹。

改动范围(引擎到界面连根拔):
- config 删 START_AP/AP_COST;models 删 ap 字段与 max_ap,存档 payload
  里的旧 ap 键被 from_dict 自然忽略;
- engine 删 _spend_ap 与全部 8 个调用点、每日恢复逻辑与日志;
  available_actions 不再按行动点筛,cost 只剩金币;
- storage 建表去掉 ap 列,老库在 connect() 里 ALTER TABLE DROP COLUMN
  无痛迁移(实测 saves/farm.db 已自动迁完);
- bot 删 AP 分支(无 AP 后 available_actions 恒可用);client/TUI/CLI/
  README/帮助文本同步清理。

网页端顺带两件事:
- "下一天"倒计时改为客户端本地走秒——SSE 只在有变化时推送,以前倒计时
  只在推送瞬间跳变,现在每秒都在动(记基点 + 1s 定时器补齐);
- 字体优化:页面字体栈补齐 MiSans/HarmonyOS Sans/PingFang,正文字号
  14→15,统计数字 tabular-nums;canvas 小字统一字体栈并加粗提对比度。

测试适配:删 2 个 AP 专属用例(无 AP 可测)、改名/收敛 5 个,
532 项全绿(skip 39),ruff/pyright 干净。真机验证:老库迁移、
统计条无行动点、倒计时逐秒递减(39:04→39:02)、动作不再报 no_ap。
This commit is contained in:
snowy-yang committed 2026-09-25 22:44:08 +08:00
1 parent 92b1a628b1
commit 15d290a60a
18 files changed
+82 -179

No files matched your search

+8 -8
View File
@@ -58,7 +58,7 @@ uv run main.py solo # 本地引擎 + 终端界面,不开
| 系统 | 规则 |
| --- | --- |
| **时间** | 每个牧场每 **40 分钟**自动推进一天(`--tick` 可调),作物生长、牲畜产出、市场波动都在此刻结算 |
| **行动点** | 每天 10 点;播种 / 浇水 / 喂食各 1 点,收获、收取、卖货、建造都免费。用完只能等第二天——时间只能自然流动,没有手动快进 |
| **节奏** | 动作**没有**行动点/体力限制,想种就种——稀缺的只有时间本身:一天就是 40 分钟,只能自然流动,没有手动快进 |
| **天气** | 每天从晴 / 多云 / 雨 / 干旱 / 暴风雨里抽一种(同种不连着出),而且**明天的天气提前可见**——「今晚浇不浇」因此是个能算的决策 |
| **水分** | 每天按天气消耗:晴 1、多云 0、干旱 2,雨天反补 3(上限 3);水分为 0 就停止生长。播种自带 2 点,只够晴天撑两天,所以下种前得先看预报 |
| **作物** | 小麦 → 胡萝卜 → 番茄 → 玉米 → 南瓜 → 草莓,按等级解锁,售价越高成熟越慢 |
@@ -73,7 +73,7 @@ uv run main.py solo # 本地引擎 + 终端界面,不开
净资产在 TUI 顶部实时显示,`goal_index` 表示已解锁的里程碑数。
> **关于节奏**:这是一款“放置型”农场,一天 40 分钟是刻意设计的,不是笔误。
> 每天 10 点行动点,用完就是等时间流动——所以一天的玩法是“上来干十件事,然后离开”。
> 动作没有体力限制,但作物、牲畜、市场的进展都随换天推进——所以一天的玩法是“上来把事干完,然后离开”。
> 小麦 2 天(80 分钟)成熟,草莓 10 天(约 6.7 小时);断水会停长,所以实际天数看天吃饭——
> 好在预报提前一天就给你,来得及浇。想调试就把节奏调快:
> `uv run main.py play --tick 3`(一天 3 秒)。
@@ -125,18 +125,18 @@ uv run main.py solo # 本地引擎 + 终端界面,不开
```bash
$ uv run main.py actions
牧场 default · 第 3 天 · 金币 96 · 行动点 7/10
牧场 default · 第 3 天 · 金币 96
共 9 个候选动作:
[ 1] harvest {"plot": 2} (免费)
2 号地的胡萝卜已成熟
[ 2] plant {"plot": 4, "crop": "wheat"} (gold:5 ap:1)
[ 2] plant {"plot": 4, "crop": "wheat"} (gold:5)
4 号地空闲,可种小麦
...
$ uv run main.py do harvest '{"plot":2}'
✓ 收获 2 份胡萝卜(丰收!),获得 104 金币 (0.01s)
第 3 天 · 金币 200 · 行动点 7/10 · 净资产 512.0
第 3 天 · 金币 200 · 净资产 512.0
```
---
@@ -189,7 +189,7 @@ POST /api/actions → {"action":"<上一步的 action>","params":{.
plant(plot,crop) water(plot) harvest(plot) harvest_all()
buy_animal(kind) feed(animal_id,quantity?) collect(animal_id)
buy_feed(quantity?) buy_plot() pause(paused?)
sell(key?,quantity?) build(key) ← 谷仓变现与建造,0 行动点
sell(key?,quantity?) build(key) ← 谷仓变现与建造
```
> `save` / `reset` 是**存档类动作**,不进通用动作表:它们必须由牧场会话处理,
@@ -215,7 +215,7 @@ curl -X POST 'http://127.0.0.1:8765/api/batch?farm=alice' \
{"action":"buy_feed","params":{"quantity":10}},
{"action":"plant","params":{"plot":1,"crop":"carrot"}}]}'
# 收成变现 / 造建筑:都是 0 行动点,行动点用完了照样能做
# 收成变现 / 造建筑
curl -X POST 'http://127.0.0.1:8765/api/actions?farm=alice' \
-H 'Content-Type: application/json' -d '{"action":"sell"}'
curl -X POST 'http://127.0.0.1:8765/api/actions?farm=alice' \
@@ -481,7 +481,7 @@ None 误用、属性不存在、参数类型不符。本项目的状态快照是
* 未知动作 → `400 unknown_action`,并列出可用动作;
* 缺必需参数 → `missing_param`;多传参数 → `bad_param`(明确拒绝而不是静默忽略);
* 类型错误 → `bad_param`,但宽容地把 `"3"` 这类数字字符串转成整数(命令行/表单常见);
* 越界地块 → `no_such_plot`;未解锁作物 → `locked`;金币/行动点不足 → `not_enough_gold` / `no_ap`;
* 越界地块 → `no_such_plot`;未解锁作物 → `locked`;金币不足 → `not_enough_gold`;
* 牧场名会被用作文件名 → 白名单校验,挡掉 `../`、`a/b` 之类的路径穿越;
* 请求体上限 64KB、批量动作上限 50、`limit` 参数自动夹取到合法区间。