summaryrefslogtreecommitdiff
path: root/docs/维护说明.md
diff options
context:
space:
mode:
authorSomhairle H. Marisol <[email protected]>2026-09-22 02:28:31 +0800
committerSomhairle H. Marisol <[email protected]>2026-09-22 02:28:31 +0800
commitef78374c316587fb585b72e6d427cd6e61203655 (patch)
tree9eb176889054c07449debaf2a9d169ffe1851a0d /docs/维护说明.md
parent5e036da9dfb1fe7f9e4f5e48414a8a1176292655 (diff)
downloadliving-village-ef78374c316587fb585b72e6d427cd6e61203655.tar.gz
feat(mapgen): 参数化确定性生成器与视口裁剪(P20 第一步)
- 新增纯函数 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 与基线一致。
Diffstat (limited to 'docs/维护说明.md')
-rw-r--r--docs/维护说明.md32
1 files changed, 32 insertions, 0 deletions
diff --git a/docs/维护说明.md b/docs/维护说明.md
index b22c6bf..2c8f406 100644
--- a/docs/维护说明.md
+++ b/docs/维护说明.md
@@ -245,6 +245,30 @@ dotnet src/LivingVillage.Headless/bin/Release/net8.0/LivingVillage.Headless.dll
- 门槛:clean rebuild 0 警告 0 错误;`final_digest=953775FAEB2FDDE97289491AA260BD8D390C571E48A7A13AD2CB6FB7124F7F6C`
一致、`performance_determinism=PASS`。
+## P20 第一步:参数化确定性生成器与视口裁剪(大地图扩程前置)
+
+- 新增纯函数模块 `src/LivingVillage.Desktop/MapGen.fs`:`generate : Params -> Result`,尺寸参数化
+ (默认仍是 64x48;可用 `generateWithSize 256 192 seed`)。组成:
+ splitmix64 随机游走河道(`RiverCount`/`RiverWidth`)、2-3 octave value noise 地形(草地/泥炭)、
+ 泊松式最小间距布点(石头装饰);核心活动区先整平为草地,再由 **BFS(4 邻接、非水可走)**
+ 从核心中心洪泛校验 5x6=30 个 spawn 全部可达,不可达则沿直线确定性修整并复验,结果写入 `ReachabilityOk`。
+ 纯函数、无时钟/随机源:同 seed 两次生成逐字节一致(`Array.mapi` 校验 + checksum)。
+- 视口裁剪纯函数 `MapGen.visibleTileRange`/`visibleTileCount`(与既有 `VillageArt.drawWorld` 的
+ `tx0..tx1/ty0..ty1` 窗口一致),`drawWorld` 已改为调用它,行为不变;`drawMapFitted`/`drawMapViewport`
+ 为证据专用绘制(整图等比 + 1:1 裁剪),不进正常游戏循环。
+- 存档兼容:沿用既有 v2/v3 的 `mapWidthTiles`/`mapHeightTiles` 边界字段(读旧档仍按 64x48),
+ P20 只补参数化边界测试,未改 Sim 数值语义;`final_digest` 与基线一致。
+- 回归:`MapGenTests`(同 seed byte-identical、异 seed 不同、256x192 30 spawn 全可达、默认尺寸 64x48、
+ 裁剪范围/端点钳制)6 条;Kernel `SaveRoundTripsParameterizedMapBounds`(256x192 v2 round-trip)1 条。
+ Desktop **109 -> 115**,Kernel **89 -> 90**。
+- 实测性能(Xvfb,本机):生成 256x192 = **52 ms**、64x48 = **1.9 ms**;256x192 生成
+ `reachable_ok=true`、`reachable_tiles≈47684`;裁剪后单帧仅绘制 **1050/49152 = 2.1%**
+ (`culled=97.9%`),离屏单帧 **0.62 ms/帧**(implied ≈1610 fps,仅 harness 立即模式)。
+- 证据:`/tmp/opencode/lv-p20-art/`(`mapgen-256x192-seed{4242,7,99}.png` 整图三 seed、
+ `mapgen-culled-256x192-seed{...}.png` 裁剪帧、harness 计数日志)。白块回归 0 命中。
+- 门槛:clean rebuild 0 警告 0 错误;`final_digest=953775FAEB2FDDE97289491AA260BD8D390C571E48A7A13AD2CB6FB7124F7F6C`
+ 3 次一致、`performance_determinism=PASS`。
+
## 已验证命令
```bash
@@ -290,6 +314,12 @@ for pair in noon:12.0 dusk:20.75 night:0.5; do name=${pair%%:*}; hour=${pair##*:
LV_RECORD_DIR=/tmp/opencode/lv-p19-art/$name LV_RECORD_EVERY=2 \
dotnet src/LivingVillage.Desktop/bin/Release/net8.0/LivingVillage.Desktop.dll; done
+# P20 大地图生成器取证(整图 + 裁剪帧;每 seed 一拍即退,日志打印 gen_ms/drawn/culled)
+for seed in 4242 7 99; do timeout 120 xvfb-run -a -s "-screen 0 1280x720x24" env \
+ LV_MAPGEN_SHOT=1 LV_MAPGEN_WIDTH=256 LV_MAPGEN_HEIGHT=192 LV_MAPGEN_SEED=$seed \
+ LV_RECORD_DIR=/tmp/opencode/lv-p20-art \
+ dotnet src/LivingVillage.Desktop/bin/Release/net8.0/LivingVillage.Desktop.dll; done
+
# P18 黄昏暖色取证(20:45 真实帧;深夜把 20.75 换成 0)
timeout 100 xvfb-run -a -s "-screen 0 1280x720x24" env LV_AUTOPLAY_SAMPLE=1 \
LV_AUTOPLAY_START_HOUR=20.75 LV_AUTOPLAY_RECORD=1 \
@@ -329,6 +359,8 @@ python3 scripts/check-no-white-blocks.py evidence/night-run
- `/tmp/opencode/lv-p13/evidence/`(P13:`walk-idle-frames.png`、`water-3phase.png`、
`smoke-3phase.png`、`water-2frame.png`、`smoke-2frame.png`、`day-panorama.png`、
`night-lantern.png`、`day-night-compare.png`、`walk-real-run.png`、`day-run/`、`night-run/`)
+- `/tmp/opencode/lv-p20-art/`(P20:`mapgen-256x192-seed{4242,7,99}.png` 整图、
+ `mapgen-culled-256x192-seed{4242,7,99}.png` 裁剪帧)
- `/tmp/opencode/lv-p19-art/`(P19:`p19-noon-12h-0{1,2}.png`、`p19-dusk-20h45-01.png`、
`p19-night-00h30-01.png`、`p19-before-noon-yellow.png`/`p19-after-noon-neutral.png`;同一份拷入 `evidence/`)
- `/tmp/opencode/lv-p18-art/`(P18:`p18-dusk-20h45-0{1,2}.png`、`p18-night-deep-01.png`、