№ · 完成设计
CH.06.22
day-night-tech-design
# 白天夜晚技术实现文档
目标:把昼夜玩法接到现有时间系统与离线结算中,保证夜晚不再产生无限主收益,同时不破坏旧存档。
现状基线
src/utils/gameTime.ts已有dawn / day / dusk / night四段时间。src/App.tsx已有在线 tick、离线回流和时间推进逻辑。- 当前收益来源分散在前堂、后院、后厨、闯荡、活动和角色深度中。
- 离线回流会根据现实时间补结收益,存在夜间无限膨胀风险。
需要新增的概念
1. 营业阶段
export type BusinessPhase = 'open' | 'closing' | 'closed';
建议推导规则:
dawn->openday->opendusk->closingnight->closed
2. 昼夜锁定规则
新增一个纯函数,用于判断当前时段允许哪些收益:
export interface TimePhasePolicy {
businessPhase: BusinessPhase;
canFrontDeskIncome: boolean;
canBackyardProduction: boolean;
canKitchenProduction: boolean;
canAdventure: boolean;
canNightRisk: boolean;
}
建议从 gameTime.timeOfDay 推导,不要一开始就直接持久化全部结果。
3. 日收益上限
建议把收益上限分成两层:
dailyIncomeCap:全店单日收益总上限。phaseIncomeCap:白天 / 傍晚 / 夜晚各自的阶段上限。
这样可以先保住系统,再逐步细化。
实现路径
路径 A:最小侵入
- 先在时间工具里增加营业阶段推导函数。
- 在在线 tick 里按阶段屏蔽收益来源。
- 在离线回流里按阶段拆分结算。
- 在离线结算弹窗里展示“白天收益 / 夜晚封存 / 夜间风险”。
路径 B:更完整
- 在
GameState里增加businessPhase或可缓存字段。 - 给各收益来源统一入口,便于做上限和阶段判断。
- 给夜间事件加独立权重。
- 在总览页与帮助文档中展示昼夜规则。
在线 tick 改造点
建议在现有时间推进逻辑中插入阶段判定:
- 白天:正常经营。
- 傍晚:允许收摊结算与少量补产。
- 夜晚:停止主收益增长,只保留巡夜、恢复、风险。
要特别注意:
- 不能让夜晚仍旧通过自动烹饪、后院采集、闯荡收益继续滚大。
- 如果某些夜间事件需要产出,必须走单独白名单。
离线回流改造点
现有离线回流大概率是按 elapsedSeconds 直接推收益,建议改成:
- 先拆出跨越了多少个完整时段。
- 白天段只算主收益。
- 傍晚段按折损系数算少量收益。
- 夜晚段只结算封存收益、恢复和风险。
- 输出一份时间摘要给离线弹窗。
建议离线摘要字段:
export interface OfflineTimeBreakdown {
startLabel: string;
endLabel: string;
dayDelta: number;
openSeconds: number;
closingSeconds: number;
closedSeconds: number;
openEarnings: number;
closedEarnings: number;
}
存档兼容
- 旧存档不强制新增字段,也能按
gameTime.timeOfDay推导营业阶段。 - 如果后续要持久化阶段缓存,可做可选字段。
- 所有新增字段都要有默认值,不可破坏旧档读取。
UI 需要显示的东西
- 当前时段属于白天、傍晚还是夜晚。
- 该时段是否允许继续营业。
- 夜晚是否进入闭店状态。
- 离线收益被拆成了哪些部分。
验收标准
- 夜晚无法继续无限滚主收益。
- 离线回流时可以看到昼夜拆分结果。
- 现有白天收益逻辑不被破坏。
- 旧存档仍然能加载。
- 时间体系不需要重做,只是被增强。
给新会话的执行建议
- 先在
src/utils/gameTime.ts增加营业阶段推导。 - 再改
src/App.tsx的 tick 和离线回流。 - 最后补 UI 文案与帮助说明。
- 每一步都跑
npm run lint和npm run build。