# 虫害机制 ## 规则与来源 用户明确规定:每只虫使生长速度降低 5%;成熟瞬间每只虫使本季 产量减少 5%。最多三只,速度最低为正常速度的 85%。 采用线性相加,不是逐只复乘。减产在地块加成后的整数产量上 再乘 `(100 - 5 × 成熟虫数) / 100`,向下取整;经验不变。 生虫时机是本项目新增规则,不宣称来自网页:每季间隔为 `max(3600, ceil(基础生长秒数/4))`,最多发生三次生虫事件。 每次一只;除虫后已发生事件不重放,尚未到来的事件仍可继续发生。 成熟时停止生虫;如果生虫与成熟恰好同秒,优先成熟。 ## 时间与结算 `farm_core/pests.py` 按生虫事件分段计算,剩余工作量以百分之一秒 为整数单位。无虫时每秒完成 100 单位,有 n 只虫时每秒完成 `100-5n` 单位,成熟秒数向上取整。 除虫恢复后续速度,不补回此前已经损失的时间。 不创建定时后台任务;查询以保存的状态和统一 UTC 时间投影, 收获、除虫在既有 SQLite 业务事务中结算并保存。 因此不需要在线挂机,也不会按“看了几次农场”重复生虫。 阶段展示使用已完成生长工作量,不使用减速后的预计成熟时间倒推阶段。 成熟虫数冻结为 `maturity_pests`。成熟后再除虫会清除可见虫子, 但不会恢复本季产量。下一季及重新播种清空虫数、事件数和减产记录, 重新开始生长;枯萎、铲除后没有虫子。 ## 状态与迁移 schema v3 的 plots 增加六个字段: | 字段 | 含义 | | --- | --- | | pest_count | 当前虫数 | | pest_spawned | 本季已经发生的生虫次数 | | growth_remaining | 剩余工作量,百分之一秒 | | growth_updated_at | 已结算到的 UTC 秒 | | next_pest_at | 下一次生虫 UTC 秒;无后续事件时为空 | | maturity_pests | 成熟瞬间冻结的虫数 | v1→v2→v3、v2→v3 都在初始化事务内迁移,保留已有资产、流水与地块。 迁移前已经种植的当前季不追溯增加虫害和成熟时间,仍按原规则结算; 下一季或重新播种后启用虫害。底层原始快照保留计算基准, 业务服务的 snapshot 提供指定时刻投影后的虫数、进度和预计成熟时间。 ## QQ 指令与绘制 发送 `农场除虫` 或 `除虫`,一次清除自己所有地块现存虫子, 不收费、不奖励经验;无虫时返回明确提示。重复事件返回原结果, 事务失败全部回滚。`农场详述` 显示虫数、当前减速及已冻结减产比例, 收获结果说明发生减产的地块。 正式渲染器采用 `13-insect-coordinates-deferred.md` 中的固定位置, 以地块中心定位,显示 0~3 只虫,成熟后未除虫时仍显示虫子。 这是为展示用户所要求的成熟虫害状态而保留,区别于网页 step<6 的隐藏条件。 静态图片从完整 38 帧中稳定选帧:依据农场作用域摘要、地块、 本地作物编号、当前季数、虫序,以 SHA-256 确定选帧顺序。 同一地块的多只虫不重复选帧;跨地块允许偶然相同。 不依赖进程随机种子,刷新、重启、切换画质、除虫调整成熟时间均不改帧。 下一季重新计算;同一作物重新播种且其他组合相同时会复用该组合的选帧。 无需增加业务数据库字段。虫数与选帧都进入可见场景缓存键, 除虫后不会复用带虫旧图。完整 38 帧均已归档并进入资源包。 ## 验证范围 离线测试覆盖分段减速、离线成熟、成熟后除虫仍减产、多季重置、 重复消息、并发除虫、失败回滚、数据库重新打开、旧版本迁移、 QQ 指令编排和渲染缓存失效。未验证真实 QQ 发送或正在运行的宿主部署。