summaryrefslogtreecommitdiff
path: root/src
Commit message (Collapse)AuthorAgeFilesLines
* perf(kernel): P27 第二步 — Rumor 扫描去装箱 + 裁剪判定 O(1)Somhairle H. Marisol13 days5-14/+70
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | 两条互相独立、均不改变保留集合与查询结果的优化: 1) 扫描去装箱:latestRumorFor / rumorIsDuplicate 用 `=` 比较 [<Struct>] 的 NpcId/RumorId(含 RumorId option)会走泛型结构相等并逐条装箱(实测 ~24 B/条, Sim.chat 单独测得 N=16000 时 393,736 B/次、随 N 线性)。改为先解构底层 int/int64 再比较;Parent 用 int64 option 比较替代 RumorId option 结构相等。 语义完全等价,扫描不再逐条分配。 2) 裁剪判定 O(1):World 新增派生镜像 RumorCount/RumorOldestDay(不参与存档, 读档由列表经 rumorWorkingSetStats 重建)。appendRumor 用「count+1>capacity 或 min(oldest,day)<cutoff」O(1) 判定,仅真需裁剪时才走 trimRumors;旧 consRumor 每次追加都 rumorsNeedTrim 全表扫一遍。条件与 needTrim 逐字等价,保留集合相同。 等价性验证:5 天 2000 聊天/天跑两遍 WorldSave.save 逐字节相同, RumorCount/RumorOldestDay 与对列表重算一致(count=8000、oldest_day=1)。 Kernel 长跑基准 30 NPC × 2000 聊天/天(--rumor-bench D 30 2000): days 修复前 alloc / ms 修复后 alloc / ms 3 930,716,456 / 1626.7 482,716,192 / 1511.3 30 13,419,045,864 / 12182.5 4,884,067,640 / 8879.6 60 27,297,668,608 / 23769.7 9,774,660,360 / 17078.2 60 天分配 -64%、耗时 -28%,retained_id_checksum=927964000 前后一致。 门槛:final_digest=953775FAEB2F... 三次一致、performance_determinism=PASS; Kernel 92 / Desktop 143 全绿;--cost-probe 1/5 天 18.7s/18.8GB、90.4s/94.6GB (全模拟分配由逐 tick NPC 快照主导,谣言子系统占比很小,故全模拟基本持平)。
* perf(kernel): P27 第一步 — Rumor 长跑基准与修复前量化Somhairle H. Marisol13 days3-1/+135
| | | | | | | | | | | | | | | | | | | | | 新增 Kernel 层 Rumor 长跑基准(RumorBench.fs + headless --rumor-bench [days npcs chats_per_day]),把「聊天→生成/追溯谣言」路径从 Sim.step 的 NPC 快照分配解耦,隔离测量谣言工作集随世界年龄的分配/耗时;同 Config 的 retained_id_checksum 证明确定性。 复核 M3-1 前提:World.Rumors 已被 M6a(d94ec2d/cc850bf)按 3 天保留窗口收敛, 单日成本平稳(1/5/10 天 ≈18.7/18.1/19.8s、≈19GB/天),超线性项消失。 剩余 Rumor 成本 = 每次聊天的两条 O(N) 扫描 latestRumorFor/rumorIsDuplicate, 且 [<Struct>] NpcId/RumorId 用 = 比较会逐条装箱(Sim.chat 单独测得 N=16000 时 393,736 B/次、随 N 线性)。 修复前基准(30 NPC,--rumor-bench D 30 2000): 3d chat_calls=6000 retained=6000 alloc=930,716,456 ms=1626.7 30d chat_calls=60000 retained=8000 alloc=13,419,045,864 ms=12182.5 60d chat_calls=120000 retained=8000 alloc=27,297,668,608 ms=23769.7 (60d 工作集稳定 8000,不随年龄增长。) docs/维护说明.md 新增 P27 小节记录上述现状与量级。不改任何模拟语义。
* feat(desktop): P26 HUD 常驻元素半透明底色 + 1px ↵Somhairle H. Marisol13 days3-5/+46
| | | | 描边(昼/夜可读)
* feat(desktop): P26 夜晚冷月光 veil(纯渲染层)+ ↵Somhairle H. Marisol13 days4-0/+66
| | | | 灯笼光晕径向无方斑回归
* feat(mapgen): P26 512 ↵Somhairle H. Marisol13 days5-10/+152
| | | | 大图河岸装饰(护岸石垒/芦苇/垂柳)仅视觉层,不挡通行
* feat(desktop): P26 ↵Somhairle H. Marisol13 days3-16/+60
| | | | 民居立面第二变体(挑檐/木格栅窗/院门)沿河沿路交替
* feat(desktop): LV_RIVERSCAPE_VILLAGE_TOUR ↵Somhairle H. Marisol13 days1-0/+15
| | | | | | | | 村民巡游钩子提升屏内可见村民(P25) - NPC 行动目标固定在 Sim 四活动点(厨房/家/集市/工位),原桥/门/核心巡游大多帧 屏内仅 0-3 人;新钩子改为在这些活动点间环游,150s 采样 >=8 村民占 74%(村庄段 89-91%)。 - 仅 Desktop 取证路径,不动 Kernel/Sim 数值。
* fix(mapgen): 大图关闭孤立装饰石块,杜绝草地上游离石板 ↵Somhairle H. Marisol13 days2-17/+54
| | | | | | | | | tile(P25) - 新增 Params.DecorativeStones(默认 true);paramsForSize 对 >256x192 关闭, 512x384 不再产生 292 个孤立石板(stone 非路网计数归零,石块全部属于路网)。 - 64x48/256x192 保持开启,checksum 6042052/1284656962 不变。 - 新增 NoIsolatedStoneTiles / DecorativeStonesDisabledOnLargeMaps 回归;Desktop 134 -> 136。
* feat(art): 生成器民居改用黛瓦/木墙/门窗部件 + ↵Somhairle H. Marisol13 days2-7/+28
| | | | | | | 村民可见性日志钩子(P24) - drawMapStructures 用 RoofRidge/RoofEave + WallWood/WallWindow + Door 精灵替换原矩形色块。 - LV_NPC_VISIBLE_LOG=1 每秒打印 visible-npcs=K of 30,作为大世界村民渲染证据。
* feat(mapgen): 512x384 沿河民居加密到 18 座且门全部可达(P24)Somhairle H. Marisol13 days2-3/+84
| | | | | | | - Params.ExtraRiversideHouses(默认 0);paramsForSize 仅对 >256x192 设为 10, 从既有路网泊松散布 3x2 民居并接门入网(structureRng 确定性),512x384 共 18 座。 - 64x48/256x192 仍 4 座、checksum 6042052/1284656962 不变(新增用例锁定)。 - 新增 512 民居数量/可达/确定性用例;Desktop 130 -> 134。
* feat(desktop): LV_RIVERSCAPE_WIDTH/HEIGHT 取证钩子支持 512x384 ↵Somhairle H. Marisol13 days1-2/+11
| | | | | | 生成器世界(P23) - 默认仍是 256x192,不改默认世界;仅让巡游/性能取证可跑 512x384。
* feat(mapgen): 512x384 尺寸自适应参数与扩程回归(P23)Somhairle H. Marisol13 days2-5/+93
| | | | | | | | | - paramsForSize:河道数量随高度约每 96 行一条(64x48/256x192 仍 2 条,512x384 得 4 条), 第 3 条起在核心上/下方逐层外扩,互不重叠且不压核心。 - 噪声特征尺度封顶 4x,避免 512x384 退化成过度平滑的放大图。 - 64x48/256x192 生成结果逐字节不变(新增 checksum 锁定用例)。 - 新增 512x384 同 seed 逐字节一致/异 seed 分化/四河道连续/30 spawn 与桥两岸可达用例。 - Desktop 测试 124 -> 130。
* test(kernel): 512x384 参数化边界存档 round-trip 与 NPC ↵Somhairle H. Marisol13 days2-0/+50
| | | | | | | | | 边界回归(P23) - Sim.configureBounds 512 384 下 v2 存档 round-trip 且同 world 两次保存逐字节一致, 读回再保存仍与原文一致;v1 的 64x48 兼容由既有用例覆盖。 - DriverHarness 长跑 20000 tick 断言 avatar 与全部 NPC 有限且留在 [0,max] 内。 - Kernel 测试 90 -> 92。
* feat(perf): LV_PERF_SOAK_SECONDS 让 64x48/sample ↵Somhairle H. Marisol13 days1-2/+18
| | | | | | | 世界也能长时帧率采样(P22) - sample 脚本跑完一轮后若未到 soak 秒数则回到开头继续,用于与 256x192 巡游做同口径的解锁帧率对比;默认 0 行为不变。
* feat(perf): LV_UNLOCK_FPS 与 LV_PERF_SUMMARY 实机帧率核对钩子(P21)Somhairle H. Marisol13 days1-2/+40
| | | | | | - LV_UNLOCK_FPS=1 关闭 vsync/固定步长以测真实渲染上限; LV_PERF_SUMMARY=1 退出时用 PerformanceSummary 打印 mean/min/max。 - LV_RIVERSCAPE_SECONDS=N 让巡游循环到 N 秒,支撑 60s 稳定采样。
* feat(perf): 帧率采样汇总纯函数 + 测试(P21)Somhairle H. Marisol13 days4-0/+63
| | | | | - PerformanceSummary.summarize:丢弃 warmup 后求每秒 FPS 的均值/最低/最高, 空样本返回 None;含 3 条单测(TDD)。
* fix(mapgen): sample 录像流程保持 64x48,仅显式巡游用生成器世界Somhairle H. Marisol13 days1-2/+9
| | | | | LV_AUTOPLAY_SAMPLE(非巡游)仍走旧 64x48 以确保既有录像可复现; LV_RIVERSCAPE_TOUR=1 时才启用 256x192 生成器世界。新增 world-mode 启动日志。
* feat(mapgen): 默认可玩世界接入生成器 + 河景细节(P20 ↵Somhairle H. Marisol13 days2-63/+170
| | | | | | | | | | | | 第三步 B) - Game:默认 256x192 生成器世界(核心可达区站位),LV_LEGACY_MAP=1 / LV_MAP_SCALE>1 / LV_MAP_TOUR=1 回退旧路径;StartNewGame 走同一站位。 - VillageArt.drawWorld 新增 pixel 与 mapGen option:Some 时按生成器瓦片绘地面 并叠加桥面/沿河民居/门,跳过 64x48 样例平面与道具;水波沿用 waterFrameTickAt。 - 新增 bridgeLanternTiles;夜间 LanternGlow 沿用既有预乘同心圆(无过曝白芯), 生成器世界用桥头灯笼。 - 新增 LV_RIVERSCAPE_TOUR 真走位巡游与 LV_RECORD_NAME 录屏前缀(证据用)。
* feat(mapgen): 生成器序列化 + 世界站位接入(P20 第三步 A)Somhairle H. Marisol13 days4-7/+79
| | | | | | | | | | | - MapGen.serialize:生成结果的确定性序列化(尺寸/seed/瓦片/Rivers/Bridges/ Paths/Buildings),同 seed 逐字节一致,供回归与跨机核对。 - WorldBootstrap.initialWorldWithPlacement:显式站位建世界;旧 64x48 路径 (initialWorld/initialWorldWithOccupation)字节口径不变。 - WorldBootstrap.initialWorldInMap:用生成器核心可达区做站位,30 spawn 全落 可达核心;新增 serialization/placement 两条测试。 - fsproj:MapGen 先于 WorldBootstrap 编译。 - Desktop 119->121,Kernel 90 不变。
* feat(mapgen): 河道连续性不变量 + 桥/石板路网/沿河民居(P20 ↵p20-map-gen-foundationSomhairle H. Marisol13 days4-65/+287
| | | | | | | | | | | | | 第二步) - 河道改为贯穿全图连续水带(每列一段、宽度 >= RiverWidth),置于核心区上下 两侧且不相交;新增不变量测试:逐列水段数恒定、每段宽度下限、任意水格 >=2 个水邻居(禁止断裂缺口与孤立水点)。 - Result 新增 Rivers/Bridges/Paths/Buildings/BridgeCrossingsOk;每河 2 座桥、 横贯主路 + 垂直连接路 + 远岸路 + 白墙黑瓦民居(门朝路)。 - 公开 isWalkable/floodFill;ReachabilityOk 现覆盖 30 spawn + 所有门 + 所有桥面, BridgeCrossingsOk 保证每桥两岸同连通域。 - 回归:Desktop 115->119、Kernel 90 不变;final_digest 与基线一致。
* feat(mapgen): 参数化确定性生成器与视口裁剪(P20 第一步)Somhairle H. Marisol13 days7-19/+527
| | | | | | | | | | - 新增纯函数 MapGen:尺寸参数化(默认 64x48,可 256x192),splitmix64 随机游走河道 + 2-3 octave value noise + 泊松式布点;核心区整平后以 BFS 校验 5x6=30 个 spawn 全部可达,不可达确定性修整并复验。 - visibleTileRange/visibleTileCount 纯函数,drawWorld 改为调用之(行为不变); drawMapFitted/drawMapViewport 仅证据用。 - 存档沿用 v2/v3 边界字段,补参数化边界 round-trip 测试,未改 Sim 语义。 - 回归:Desktop 109->115、Kernel 89->90;final_digest 与基线一致。
* fix(desktop): P19 白天色调去偏黄(day tint ↵p19-daylight-tamingSomhairle H. Marisol13 days3-4/+35
| | | | 中性白平衡,黄昏暖橙保留)
* feat(desktop): P18 黄昏暖色真实渲染(加性暖色 veil + ↵Somhairle H. Marisol13 days4-23/+68
| | | | 双窗口光照 + 时段标签对齐)
* fix(desktop): P17-FIX 起时钩子在 sample/autoplay ↵Somhairle H. Marisol13 days3-11/+36
| | | | 路径生效(resolveStartTick 纯函数 + 回归 + 重拍证据)
* test(desktop): P17 取证钩子(LV_AUTOPLAY_START_HOUR 纯函数起时)+ ↵Somhairle H. Marisol13 days3-1/+22
| | | | 证据与 docs 记录
* feat(desktop): P17 清晨/黄昏光照精修(暖色天际 + ↵Somhairle H. Marisol13 days2-33/+80
| | | | 过渡窗口参数化,分数小时平滑)
* feat(desktop): P17 村民走路节奏差异化(农夫/货郎/书生 纯 ↵Somhairle H. Marisol13 days2-11/+77
| | | | tick 节奏)
* feat(desktop): P17 ↵Somhairle H. Marisol13 days3-7/+49
| | | | 街边中式细节物(石灯笼/水缸/摊贩摊位)图集扩展 28 格
* feat(desktop): P16-FIX 开始界面截图模式(LV_AUTOPLAY_MENU_SHOT)+ ↵Somhairle H. Marisol13 days3-12/+80
| | | | 真实菜单证据补拍
* feat(desktop): P16 HUD ↵Somhairle H. Marisol13 days8-45/+219
| | | | 顶部窄信息条(时段/时间/倍速/体力/钱币)+ 冬夜冷色 + 面板/提示渐变重绘
* feat(desktop): P16 启动画面淡入(Esc/空格跳过)+ ↵Somhairle H. Marisol13 days12-40/+212
| | | | 开始界面收敛三项(开始/读档/退出)+ CJK 补字 238
* perf(sim): M6a ↵Somhairle H. Marisol13 days1-19/+25
| | | | 谣言窗口扫描去中间表——最新在前早停递归替代 takeWhile/filter/sort,零分配且等价
* test(sim): M6a ↵Somhairle H. Marisol13 days1-0/+87
| | | | 谣言裁剪回归——容量内零拷贝与逐字节一致/按天淘汰/单调 id/DayIndex 存档往返
* feat(sim): M6a 谣言工作集容量上界+按天淘汰——DayIndex ↵Somhairle H. Marisol13 days2-10/+57
| | | | 派生字段/纯函数 trim/窗口化扫描/O(1) nextId
* test(desktop): P15 选职业→第一天任务→完成判定→Done ↵Somhairle H. Marisol13 days1-0/+50
| | | | | | | | | | 全链路回归(既有事件通道) - 从 WorldBootstrap.occupationStateFor(选择职业入口)取四职业第一天 Offered 任务, acceptTask 转 Active,再用该模板对应信号推到 Done:交易/对话模板走 InteractionEvent → signalOfInteraction(玩家买/卖、玩家对话),到达瓦片/夜水边/观察由调用方折叠信号。 - 覆盖农夫送粮、渔夫夜捕、货郎收货、书生观察记事等四职业首日模板,验证池内生成与终态。 - Desktop 94 / Kernel 83 全绿;不改 Sim.step 数值路径。
* feat(desktop): P15 ↵Somhairle H. Marisol13 days5-5/+178
| | | | | | | | | | | | | 开局职业选择页——新档四选一+暂不选择,接入 v3 存档与当日任务 - MenuState:新增 OccupationSelect 页与 StartNewGameWith 命令;occupationOptions=农夫/渔夫/货郎/书生/暂不选择, 默认高亮「暂不选择」= 不写职业的旧行为;四选一确认后发 StartNewGameWith,ESC 返回主菜单(既有 MainMenu 行为与测试不变)。 - WorldBootstrap.occupationStateFor/refreshOccupationToday:按 seed+职业种子生成/跨日刷新当日 Offered 任务。 - Game:主菜单「开始新游戏」→ 职业选择页;选定后 initialWorldWithOccupation 注入 Money/Energy 与 Today, m5View.Task 随之写入 v3 存档;游玩中按日刷新;autoplay/flow 默认走「暂不选择」保持旧演示行为;DrawMenu 渲染职业页。 - 测试 Desktop 93(新增 6):职业页选项顺序/默认 None/标签、确认命令与返回、bootstrap 四职业 Money/Energy+当日池内 Offered 任务、四职业 v3 round-trip(职业+任务逐字段)、T 面板显示所选职业的模板名与「待接受」、跨日刷新保持同日。
* fix(ui): P15 补齐职业/任务中文用字(CJK 图集 ↵Somhairle H. Marisol13 days5-5/+59
| | | | | | | | | | | 197->228),requiredUiLabels 锁定防复发 - CjkGlyphAtlas 字表 + Assets/cjk-glyphs.txt + cjk-glyph-atlas.png 重生成(384x360,15 行): 新增 职/业/收/货/转/事/论/理/粮/工/翻/土/捕/渔/询/送/帮/农/夫/郎/书/生/待/接/受/今/日/任/务/行/中 共 31 字,覆盖职业选择页与 T 面板全部模板/状态文案,消除方框缺字。 - ChineseText.requiredUiLabels 增职业/模板/状态标签,既有 FormalChineseUiLabelsUseTheRealGlyphAtlasBoundary 与 RequiredUiLabelsAreFullyCoveredByTheGlyphTable 继续强制全字形可渲染。 - PrototypeTests 几何常量同步 197->228、13->15 行、312->360 像素。Desktop 87 全绿。
* feat(occupation): P15 补齐货郎/书生各 2 条每日任务模板 + ↵Somhairle H. Marisol13 days3-13/+156
| | | | | | | | | | | | | | 既有事件通道信号桥(Kernel 纯函数 TDD) - TaskTemplateId 扩出 BuyGoods(收货)/Resell(转卖)/ObserveNotes(观察记事)/ReasonDebate(论理), taskPoolOf 货郎=[收货,转卖]、书生=[观察记事,论理],四职业池均非空。 - TaskSignal 增 Purchased(玩家买入)/Observed(观察),satisfiesCompletion 给出四模板完成判定; 新增 occupationSeedOf/refreshToday(跨日才重生成,同日含 Done/Failed 终态保留)。 - signalOfInteraction/advanceTask:仅 playerId 发起的 DialogueEvent/TradeEvent 产生信号, NPC 互动不派任务;Offered 须先 acceptTask,终态不可复活。WorldSave 模板 token 双向同步。 - 测试 83 全绿(新增 6:池非空、货郎书生逐日池内确定、模板中文名、完成信号正负、 事件桥含玩家买/卖与 NPC 忽略、既有 DialogueEvent→accept→Done 全链路、refreshToday 逐日)。 - 不动 Sim.step 数值路径;旧档 v3 模板 token 仅新增合法值,未知模板仍拒绝。
* merge: 采纳 M3-1 ↵Somhairle H. Marisol13 days5-19/+235
|\ | | | | | | 流式可观测性+门槛缩尺+成本量化(独立复验全绿)
| * test(desktop): M3 批次输出格式与流式驱动回归Somhairle H. Marisol13 days2-0/+85
| | | | | | | | | | | | - world 行前缀不变、行尾 elapsed_s;[done k/N] 与 summary 追加字段断言 - runStreaming workers=1 断言逐世界 emit(非收完再打印);并行下不重不漏 - costLine ticks/s 由实测 ticks/墙钟推导
| * feat(headless): 逐世界流式输出 + --cost-probe 成本阶梯Somhairle H. Marisol13 days3-19/+150
| | | | | | | | | | | | | | | | | | - runBatch 改为每个世界一完成立即打印 world= 行(行尾追加 elapsed_s)与 [done k/N] elapsed=…s 进度行并 flush,长批次不再整轮零进度 - batch_summary 旧字段原样保留,追加 workers 与 wall_s 总墙钟 - 新增 BatchOutput 纯格式化与 runStreaming 并行驱动 - 新增只读 --cost-probe [D1,D2,...]:按天阶梯真实测量 ticks/s、墙钟、分配与 GC - 判据语义 check a/b/c 未改
* | test(desktop): CJK 清单唯一性与图集网格防复发断言Somhairle H. Marisol13 days1-0/+33
|/ | | | | - 断言 cjk-glyphs.txt 非空、每行恰 1 字符、字符唯一 - 读 cjk-glyph-atlas.png IHDR,断言 16 列且网格容量覆盖清单、无多余空行
* test(kernel): 用 List.item 替换弃用的 List.nth,全解决方案 ↵Somhairle H. Marisol13 days1-3/+3
| | | | Release 构建归零告警
* test(desktop): 预乘/光晕/水面/站位回归与夜间白块校验脚本Somhairle H. Marisol13 days1-0/+80
| | | | | | | | - premultiply 定点:核心 (255,226,168,34)->(34,30,22,34),(252,196,128,34)->(34,26,17,34), 通道恒 <= alpha、<250 无白 - lanternGlowLayers 径向/预乘/无白、水面 per-tile 三相、角色脚底对齐断言 - scripts/check-no-white-blocks.py:夜晚帧不得有 >=64x64、每通道>=250、alpha>=250 的块 (P13 旧帧 42/69 命中,P14 修复后 0 命中)
* fix(desktop): 灯笼光晕按自身 alpha ↵Somhairle H. Marisol13 days3-28/+110
| | | | | | | | | | | | | 预乘并改径向层叠,消除夜间纯白方块 - 新增 VillageArt.premultiply:MonoGame SpriteBatch 默认预乘混合,直传 Color(r,g,b,a) 会直接加 rgb 导致多层暖色饱和成 75x75 纯白块 - lanternGlowLayers 用同心圆 pixel run 做径向衰减,逐层预乘,只在 RiverLantern 实体处绘制 - 水面相位改 waterFrameTickAt=(tick/32+x+2y)%3,同一帧相邻砖相位不同 - 炊烟改为 drawWorld 末尾独立一遍,位置 offsetTile 0 -3,画在屋瓦/竹子之上 - 角色脚底对齐 characterFeetOffset=16 并加预乘椭圆接触阴影 - 补全 Interaction.itemName 的 ItemKind 匹配(否则非 Food 交易会崩溃且告警)
* test(desktop): 覆盖六帧角色、待机呼吸与三相水面/炊烟Somhairle H. Marisol13 days1-10/+49
| | | | | | - 更新 isMoving 签名、WalkFrame 帧号、characterAtlasWidth=3840 - 水面断言改三相 (0,0,1,1,2,2,0),新增待机呼吸与炊烟三相测试 - Desktop 75/75 通过
* feat(desktop): 接入角色走路/待机动画并参数化录帧Somhairle H. Marisol13 days1-4/+21
| | | | | | | - 新增 avatarMoving(比较前后位置)驱动走路/待机帧切换, 覆盖采样、地图巡游与手动输入三条路径 - 录帧目录与间隔改为环境变量 LV_RECORD_DIR / LV_RECORD_EVERY (默认 /tmp/lv-p5-prompt、25),便于证据落到指定目录
* feat(art): 角色六帧动画与水面/炊烟三相循环Somhairle H. Marisol13 days4-21/+68
| | | | | | | | | | - 角色图集每个 (变体,方向) 由 2 帧扩到 6 帧(4 走路 + 2 待机呼吸), cellIndex=(variant*4+direction)*6+frame,图集 3840x48 - 世界图集扩到 25 格 800x32:水面第 3 相 WaterSpriteC(slot 21)、 炊烟三帧 SmokeSpriteA/B/C(slot 22-24) - 帧选择为纯函数:walk=(tick/4)%4、idle=(tick/24)%2、 water=(tick/32)%3、smoke=(tick/40)%3 - 重生成 jiangnan/cc0 图集(脚本可复现,逐字节一致)
* feat(desktop): P12 中文每日任务面板——T ↵Somhairle H. Marisol13 days3-6/+91
| | | | 键任务页、Offered/Active/Done 三态+职业名,存读档字段级携带职业
* feat(occupation): P12 ↵Somhairle H. Marisol13 days3-0/+93
| | | | 报价偏置纯函数——货郎买卖±3.00%/书生解读±1.00%,4位定点基点,默认无职业=旧行为(TDD 6例)