城市军事交互框架

目标

城市面板负责具体的本地军事行动,地图与编队负责调兵遣将和持续运营,军事主界面只做跨城市、跨编队的总览与快速定位。

军事动作不能再统一等价为“玩家拥有城市”。城市归属只是权限来源之一,不是编队、征募、生产和后勤的共同所有者。

当前问题清单

  1. 创建编队与征募训练耦合(已处理)。 空编队建立与小队征募现在是两个独立命令。
  2. 城市军镇状态只有一个势力槽位(已处理)。 正式索引已经改为 (force_id, city_id);city_id 索引只保留为当前控制者与旧后勤调用的兼容入口。
  3. 城市归属承担了过多权限(部分处理)。 本地户口现在可以独立授予征募和训练能力,但占领、盟军、通行权与地方合作仍待建立统一授权模型。
  4. 兵源账本尚未连接人口账本。 recruited_manpower 已避免每日同步把已征兵员重新补回,但征兵目前仍未同步扣减玩家—城市人口注册表。
  5. 城市易主缺少完整转移策略(部分处理)。 不同势力的库存、订单与兵源不再共用对象;库存缴获、订单取消或接管等易主规则仍待定义。
  6. 命令边界不完整。 UI 虽然经由运行时与命令服务写入,但创建、训练、排产仍存在组合命令,失败后的回滚与错误语义不够清楚。
  7. 存档链条不完整。 编队有独立编解码器,生产服务只有序列化,没有对应恢复;运行时流水号也未纳入统一存档,读档后存在 ID 冲突风险。
  8. 界面曾直接判断城市归属。 这会让展示层复制领域规则,并在规则变化时与服务层产生不同结论。

目标数据边界

城市军事基础设施

键为 city_id,只描述地点自身:

  • 城市接纳的科技与工艺;
  • 产业、船坞、训练场等设施;
  • 山地、水域等本地环境;
  • 地点级生产与训练容量。

它不归属于某个势力,也不保存某个势力的兵源和订单。

势力—城市军事状态

键为 (force_id, city_id),描述某势力在某城市的实际资源与权利:

  • 可征募人口及其来源;
  • 该势力控制的库存、生产单和训练单;
  • 征募、生产、驻扎、补给等授权;
  • 占领、盟约、地方合作等权限来源。

编队

编队属于势力并位于地图坐标。建立空编队不消耗人口,也不要求拥有城市;向编队补入小队才进入征募、训练与装备流程。

权限策略

各动作分别查询能力,不再查询一个笼统的“是否拥有城市”:

动作核心条件
创建空编队势力和城市有效,且城市自有、无主或有本势力户口
本地征募势力在城市具有征募来源与授权
训练小队已选择编队、模板可用、训练设施可访问
生产军械科技可用、城市工艺满足、势力有生产访问权
设置后勤源库存访问权与运输路线有效
调动编队势力拥有或获授权指挥该编队

分阶段迁移

第一阶段:拆开建军与征募(已实施)

  • 城市面板分别提供“创建空编队”和“征募并加入编队”。
  • 无主城市中的空编队创建不再依赖户口或军镇生产状态;他势力城市仍要求本势力在当地有户口。
  • UI 不再直接用 city.rule_player 拦截整个军事子界面。
  • 运行时提供分层的城市军事能力查询。
  • 修正已归属城市的军镇状态注册顺序,使其先写入势力 ID 再注册。

空编队与征募入口已经解耦;后续阶段继续把非统治势力的本地兵源从城市统治权中拆出。

第二阶段:拆分城市设施与势力—城市状态(部分实施)

  • **已实施:**军镇状态建立 (force_id, city_id) 正式索引,同城不同势力分别保存兵源、库存与训练单。
  • **已实施:**非统治势力在当地有户口时,可以用自己的兵源创建并训练小队;训练单不会写入统治者状态。
  • **已实施:**本地户口只授予征募和训练能力,不授予该城军械生产或后勤控制权。
  • **已实施:**生产、训练和换装服务均可显式携带 force_id;旧的 city_id 主索引暂只作为城市控制者及后勤兼容索引。
  • **已实施:**民兵随本地征募征集农具,农具仍属于模板装备,但无需先进入军械生产库存。
  • **待实施:**把接纳科技、产业、训练场和地形环境抽成纯地点级基础设施状态,避免在各势力状态中复制。
  • **待实施:**城市易主时为库存、在途订单和设施控制权定义完整转移策略。

第三阶段:建立兵源账本

  • 征募来源直接关联玩家—城市户口、流民、俘虏或其他人口池。
  • 排队时预占兵源,开训时结算,取消时释放。
  • “无户口征兵”作为新的征募来源与政治代价规则接入,不修改空编队创建规则。

第四阶段:后勤与地图权限

  • 补给源改用库存访问权、外交/占领权限和实际运输路线判定。
  • 城市面板负责驻城整补,编队面板负责当前后勤状态和改派来源,地图负责路线反馈。

第五阶段:统一存档与事件

  • 编队、势力—城市军事状态、订单、补给关系和流水号进入同一版本化存档。
  • 城市归属、户口和权限变化通过明确事件刷新相关状态,避免全局刷新导致 UI 状态丢失。

约束

  • UI 只提交意图并展示能力结果,不直接写人口、库存、订单或编队数组。
  • 组合操作必须由多个可独立失败、可回滚的命令组成。
  • 城市切换只更新上下文数据,不重置城市面板当前子页;同一城市重复点击也不改变当前子页。
  • 每完成一个迁移阶段,都保留对应的无主城市、非统治城市、城市易主和读档回归测试。