《魔法植物》大地图设计(promote004 定向多区域)¶
本文介绍 magic-plant-demo 在 promote004(promote004.md)落地的大地图设计:从"66×38 一张径向小图"扩到 400×320 定向多区域大地图。 配套:map_progress.md(进度区域设计原则)· dev_manual.md §6(地图/生成) · m6_append_review.md(实现复盘)。 日期:2026-09-03 · 版本:0.1-preview · 程序化种子:
MapGenerator.generate(seed)(同 seed 必同图)
0. 一句话概述¶
把地图从"基地居中、径向五档"改成"沿东北↔西南主轴做定向分区的 45° 菱形大地图":陆地划成 T0基地 → T1林缘 → T2中环 → T3洞窟 → Boss预留 五段,沿 p = x − y(NE 大、SW 小)从东北到西南依次排开;水做整图外缘,河流/石墙做区域交界的门带。每个区域面积精确 = 当前图面积 × 指定倍数。
T2 中环(东北 · 跨河)
▲ 桥 bridge
T1 林缘(中 · 包基地四周,四向延申不同)
▲ 魔法门 magic_gate(西南石墙)
T3 洞窟(西南 · 无光)
▲ 最终门 final
Boss 预留(最西南 · 占位)
1. 世界与网格¶
| 量 | 值 | 说明 |
|---|---|---|
MapGenerator.TILE |
16 px | 每格边长 |
MapGenerator.GRID |
Vector2i(400, 320) |
格数;x∈[-200,200)、y∈[-160,160) |
MapGenerator.HALF |
Vector2i(200, 160) |
半宽/半高 |
| 世界尺寸 | 6400 × 5120 px | 400×16 × 320×16 |
BASE_CENTER |
Vector2i(0,0) |
基地中心(世界原点) |
SAFE_R |
10 (tile) | 基地安全半径,无怪无危险 tile |
AREA0 |
66×38 = 2508 格 |
当前图面积,用作"倍数"基准 |
坐标换算:
cell_world(c) = Vector2(c.x*16+8, c.y*16+8);world_cell(p) = Vector2i(floor(p.x/16), floor(p.y/16))(逆用,供region_at_world判玩家所在区)。
2. 区域模型(RegionMap.Region)¶
enum Region { BASE, T1, T2, T3, BOSS }
每格一个区域标签,供怪/菇/门/黑暗定位。面积目标 = AREA0 × 倍数(用户拍板口径):
| 区域 | 倍数 | 目标面积(格) | 构成 |
|---|---|---|---|
| BASE T0 | — | 安全区 | 基地(家/田/床/合成台/魔法书),无怪 |
| T1 林缘 | 12× | 30,096 | 围绕基地四周展开,教学与首战 |
| T2 中环 | 6× | 15,048 | 东北,跨河 |
| T3 洞窟 | 9× | 22,572 | 西南,无光 |
| BOSS | 4× | ≥10,032 | 最西南,占位(兜底吸收剩余陆地) |
陆地总数 = (12+6+9+4)×2508 = 31×2508 = 77,748 格;其余(128,000 − 77,748 = 50,252 格)为水/外缘。
3. 布局与方向(为什么是 45° 菱形)¶
地图不是正方形,而是沿 NE↔SW 主轴旋转了 45° 的菱形(见 §10 截图 map_regions.png)。原因是分区用 p = x − y 做主序,q = x + y 做带宽:
p = x − y:东北角(x 大、y 小)→ p 最大;西南角 → p 最小。分区从东北到西南按 p 降序。q = x + y:夹角带|q| ≤ qmax内的格子才算陆地;qmax 由二分校准(见 §4)。
各方向延申(用户要求,对应 GATE_TARGETS 落点):
| 方向 | 延申 | 处理 |
|---|---|---|
| 右上(NE / 东北) | 最多 | T2 跨河,主门 bridge 落点 (46,-46) |
| 左上(NW) / 右下(SE) | 适当 | 各拓出一块后直接水缘作外轮廓障碍 |
| 左下(SW / 西南) | 最少 | 却画石墙当障碍,需 magic_gate 通关 |
4. 分区几何(p-轴定向分区 + qmax 二分校准)¶
MapGenerator._calibrate_partition():
- 二分找
qmax:让|q|≤qmax(且排除基地安全区)的陆地格数 =LAND_TARGET(77,748)。lo=60, hi=260,逐步收敛。 - 收集陆地格,按
p降序(NE→SW)排序land.sort_custom(_p(a) > _p(b))。 - 沿 p 降序分切:
ZONE_ORDER = [T2, T1, T3, BOSS]。从最大的 p(东北)开始,依次填满CAPS目标面积;Boss 用cap=∞兜底,吸收剩余全部陆地(故 ≥4×)。 - 记录各区边界 p 值
_pcut_t2/_pcut_t1/_pcut_t3,作为后续画河/画墙的切割线。
面积精确:T2/T1/T3 严格 = 倍数;Boss ≥ 4×(无上限,吃尾)。
5. 门的布局(GATE_DEFS / GATE_TARGETS)¶
const GATE_DEFS := {
&"bridge": {"before": T1, "after": T2, "dir": Vector2i(1,-1), "tile": "RIVER"},
&"magic_gate": {"before": T1, "after": T3, "dir": Vector2i(-1,1), "tile": "WALL"},
&"final": {"before": T3, "after": BOSS, "dir": Vector2i(-1,1), "tile": "WALL"},
}
const GATE_TARGETS := {
&"bridge": Vector2i(46,-46), # NE(T1 臂端 / 河对岸)
&"magic_gate": Vector2i(-22,22), # SW 石墙
&"final": Vector2i(-96,96), # 更远 SW(T3↔Boss)
}
画交界带 → 穿门洞:
_cut_for(gid)取对应区域边界 p 值;在边界|p − cut| ≤ 厚处铺WATER(桥,厚 2)或WALL(石墙,厚 2)。_punch_gate(gid)在交界带内找"before 侧距目标最近的一格",沿dir往 after 侧穿。关键修复(promote004 bug):不停在"第一个 after 格"(那格仍裹在河/墙带里),而是穿到_is_dry(nxt)(非 WATER/WALL 的干地)才停——保证门洞两侧都落在可走地面,经_carve_path主路 +Gate挡板即可"先连通、用门阻碍"。记录门{cell, across, rect, before, after}(rect 供Gate.setup摆碰撞/交互)。
开锁无环(map_progress §2 关键红线):每个开锁物只能由该门之前已可达区域的材料合成——桥钥←T1、魔法门钥←T2、光明晶石←T2夜(灼心芝挪到 T2 夜可采)、最终钥←T3。绝不出现"所需材料在门后"的卡死。
6. 地表与障碍¶
- 地表(
_sample_terrain):FastNoiseLite(TYPE_SIMPLEX、frequency=0.018、fractal_octaves=4) - 每格先设
GRASS;噪声>0.52→FARM(农田块);< -0.86且靠近带缘 → 局部水袋(NW/SE 边缘)。 - 没有任何 zone 认领的格(带外、四角)→
WATER—— 这就是"水做整图外缘"。 - 基地安全区强制回填草地。
- 交界:
_place_gates_and_features在 T1/T2 画河、T1/T3 与 T3/Boss 画石墙(见 §5)。 - 主路径:
_carve_paths从基地沿Drunkard's Walk挖一条主路穿三处门 gap(wobble=0.25),门内直线贯通(wobble=0.0)。 - 障碍(
_plant_obstacles):Poisson 撒树(约 6% 草地)、矿(约 8%,仅 T2/T3),避开基地与路径,且_near_any去重。 - 装饰(
_scatter_deco):草点/花/小石(约 5% 草地)。
7. 区域内容规则(level_map.gd spawn)¶
怪物与蘑菇按 MonsterData.region / CropData.region 分带(_region_for_tag:T2/T3 精确,其余归 T1):
- 怪物成群 3–5(promote004 集群遇敌):
_spawn_monsters在目标区选簇中心,_nearest_n取最近 3–5 格各放一只,clusters = min(2, cells/5)最多两簇。 - 蘑菇按 zone 分散、稀疏(
_spawn_wild):count = clamp(cells/400, 3, 28),按 crop.region 落区,昼夜决定可见。 - 远离基地安全半径(
_safe_spawn_cells:SAFE_R+3内、障碍格上不刷)。
8. T3 无光洞窟(DarknessCave)¶
features/lighting/darkness.gd(class_name DarknessCave extends CanvasLayer,放在 Main 的 UI CanvasLayer 之前,故遮世界、露 HUD):
| 状态 | 遮罩 alpha | 视觉 |
|---|---|---|
| 不在 T3 | 0 | 正常 |
在 T3 且未戴 light_crystal |
0.965 | 近全黑(Color(0,0,0.02)) |
在 T3 且戴着 light_crystal |
0.22 | 微弱洞窟调性(可辨认) |
- 逻辑:
_target_alpha()读level_map.region_at_world(player.global_position),只在== T3时才非 0;再读PlayerState.is_equipped(&"light_crystal")分档。 - 过渡:
_process用lerpf平滑淡入/淡出。 - 纯表现层:只读 PlayerState/LevelMap,不改数据。
9. 进度闭环(开锁无环 ladder)¶
基地(T0) 种田/采集/睡觉
│ 靠「T1 蘑菇 + 林缘怪掉」合成 桥钥
▼
过河 bridge ──► T2 中环 采蘑菇/打怪
│ 靠「T2 蘑菇 + 中环怪掉」合成 魔法门钥;夜间采 灼心芝 → 光明晶石
▼
魔法门 magic_gate ──► T3 洞窟(须戴光明晶石才看得见)
│ 靠「T3 蘑菇 + 洞窟怪掉」合成 最终钥
▼
最终门 final ──► Boss 地牢(预留占位)
- 种田 = 变强:合成/升级所需蘑菇数大幅上调(见 §11),采集几下不够,必须回家种。
- 昼夜驱动:灼心芝(光明晶石原料)只在 T2 夜间可采 → 强迫"挑时段出门"。
- 首个法术:开局解锁 绽华/星刺(基础攻击),其余靠首次采集对应蘑菇解锁。
10. 截图对照¶
| 截图 | 内容 | 验证点 |
|---|---|---|
![]() |
45° 菱形分区配色:青=T2(NE)/绿=T1(中)/紫=T3(SW)/红=Boss(最SW)/白圈=基地 | 定向分区:五区沿 NE→SW 排开,基地居中 |
![]() |
实地景:绿色草地/棕色农田/蓝色水外缘与河流、黑色石墙带、土黄 Drunkard's Walk 主路 | 地形系统:水外缘、河/墙交界带、主路径穿门 |
![]() |
魔法书·魔药祭坛:列出带 upgrade_cost 的蘑菇法术,显示 升阶效果/消耗(锥心芝 10/4) |
系统层:法术升级 UI 读 upgrade_cost 扣料 |
![]() |
背包:光明晶石带绿框=已穿戴 | 系统层:装备入口(点击穿/脱,绿框标注) |
![]() |
T3 未戴光明晶石:近全黑 | T3 黑暗:无光门槛(alpha≈0.965) |
![]() |
T3 戴上光明晶石:视野恢复、洞窟色调 | T3 黑暗:穿戴恢复(alpha≈0.22) |
11. 数据从哪改(用户核心问题)¶
改 .tres(Content 懒加载自取),别信 tools/generate_content.gd(已与 .tres 脱节):
| 想改 | 目录/文件 | 字段 |
|---|---|---|
| 配方材料量 | resources/recipes/*.tres |
inputs[].count(桥钥=8银芒+1魔牙、魔法门钥=8晶铠+1孢粹、光明晶石=8灼心芝+1腐脂、最终钥=8绯泪+1洞窟之核) |
| 法术升级消耗 | resources/abilities/*.tres |
upgrade_cost(第1级基数 = 本系菇×4 + 虹髓芝×1;cost_for_rank(rank) 按 rank 递增=越升越贵) |
| 作物产量 | resources/crops/*.tres |
yields[].count(3→5) |
| 野生菇所属 zone | resources/crops/*.tres |
region = &"T1"/"T2"/"T3" |
| 怪物所属 zone | resources/monsters/*.tres |
region |
| 装备/穿戴 | resources/items/light_crystal.tres |
type=3(EQUIP);player_state.gd 的 equip/unequip/is_equipped |
| 区域面积倍数 | scenes/map_generator.gd |
CAPS + AREA0 |
| 门落点/方向 | scenes/map_generator.gd |
GATE_DEFS/GATE_TARGETS |
12. 验证¶
--importexit 0(无解析错)。tools/map_gen_test.gd:35/0(网格 / 面积比 / 基地安全 / 各门 gap 连通 / 各区可达 / seed 复现 / 成群 + 新增:门洞落干地(across 非水、cell→across 全程 PATH))。- 多 seed 复检:12 seed × 3 门洞 → across 均落干地、桥洞跨河连续(防随机 seed 复现"缺区块")。
--headless主场景引导 exit 0。tools/sys_verify.gd:22/0(升级扣料/升阶/材料不足 false/无素材基础法术不可升、穿脱、T3 黑暗 0.96↔0.33)。tools/sys_shot.gd(窗口模式,勿--headless):shots/sys_{upgrade,bag,dark_no,dark_yes}.png目视核验。





