《迷途之梦》续作开发基础 · v0.2
写于「完整通读全部源码 + 用自动操作用户端完整通关一轮」之后。 目的只有一个:下次要往游戏里加东西时,不用再重新读一遍代码。 源码目录:lost-dream/可执行版:E:\godotgame\迷途之梦-未成品\迷途之梦.exe引擎:Godot 4.5 stable(Forward+),1920×1080 设计分辨率,窗口 1280×720,物理 120Hz。 重要事实:用户端迷途之梦.pck(MD50130E5A2…)与源码build/迷途之梦.pck完全一致, 也就是说E:\godotgame\迷途之梦-未成品\里那个 exe 就是当前源码构建的,不存在「exe 比源码旧」的问题。
0. 一句话现状
能玩通的完整流程 9 个屏幕、3 个战斗章、2 个 Boss、1 段现实层探索;内容量约 10–18 分钟。 系统骨架(章节数据化、存档、暂停、音效、后处理)都在,缺的是「第 3 章以后的剧情、第二个现实层场景、结局分支」。
1. 当前版本的完整流程
标题
→ 序章(现实层卧室:失眠 / 吃药 / 时间倒流到 7 月 / 失眠开始 / 快进回 10 月)
→ 入梦白幕
→ 教学关「热身」(空镜头对话 → 美美浮现 → E 拔剑 → 五个练习)
→ 第一章「鹿人店的一天」:5 波训练 → 记忆碎片(解锁重击/斩惑)→ Boss「假面」(26 血,二阶段)
→ 第一章完过场(白 → 白天房间对话 → 黑屏核桃对话 →「第 一 章 · 完」)
→ 第二章「家」(现实层探索:房间 → 客厅 → 书房找蓝色医书 → 读书/纸条/入夜 → 回床边吃药入睡)
→ 第二章梦境(鹿人店夜战 3 波,无 Boss,打完 3 句过渡台词)
→ 第二章「丛林」(3 波:野猪 + 藤蔓)→ Boss「丛 林 石 像」(33 血;血量掉到 17 时**掉头**,变成身体 10 血 + 飞头 7 血)
→ 结束卡「——垂直切片 · 完——」→ 回标题
章节 id:1(鹿人店战斗)→ 2(家,kind=house,睡后 force_arena 复用 id 2 的战斗数据)→ 21(丛林)。 这套「一个 id 同时挂现实层和梦境战斗」的做法见 scenes/chapters.gd 第 61–158 行。
2. 本轮实测通关记录(可复现)
2.1 怎么测的
- 新增了一个仅在
--auto时挂载的自动通关驱动:dev/auto_pilot.gd(约 500 行,不参与正常游玩)。 - 它用真实输入事件(
get_viewport().push_input+Input.action_*)操作游戏,不直接改游戏状态,
唯一的例外是「同一波卡死 150 秒」时临时打开 player.god_mode(本轮没有触发)。
- 战斗交给游戏自带的
--bot(scenes/bot_driver.gd),自动驱动额外补:对话快进、拔剑、
教学五步、记忆碎片、危险翻滚 / 破梦 / 重击控场、看门狗、截图。
命令(源码跑):
E:\godot\Godot_v4.5-stable_win64_console.exe --path <lost-dream> -- --auto --bot --autodir=<截图目录>
2.2 实测时间线(自动操作,含对话快进)
主记录取自第三轮(playtest-通关实录/通关日志-自动操作.txt):
| t(秒) | 事件 | 备注 |
|---|---|---|
| 0.4 | 标题 | 1.5 秒后按键 |
| 2.6 | 进入序章 | |
| 14.9 | 进入教学关 | 32 个序章步骤走完 |
| 34.0 | 进入第一章 | 13 句入梦对话 + 拔剑 + 教学五步共 19 秒 |
| 34–104 | 第一章 5 波 + 碎片 + 假面 | 死亡 2 次(第 4 波 1 次、假面 1 次) |
| 104.8 | 第一章完过场 | 梦醒 / 黑屏 / 章节卡,约 15 秒 |
| 120.0 | 进入第二章「家」 | 卧室 → 客厅 → 书房 → 读书(约 20 秒)→ 回卧室睡觉 |
| 165.9 | 第二章梦境 3 波 | 死亡 1 次 |
| 199.1 | 第二章「丛林」 | 3 波 + 石头 Boss,死亡 1 次 |
| ~252 | 结束卡 | |
| 264 | 自动退出 | 整局 264 秒 |
整局 264 秒(自动操作,死亡 4 次),正常游玩约 10–18 分钟。全流程无卡死、无崩溃、无脚本报错。
对照组:同一套自动操作但不带「危险翻滚 / 破梦 / 重击」辅助时,会在「丛林 · 三」(3 野猪 + 2 藤蔓) 连续死亡 15 次、每次重开同一波满血,永远过不去(日志见 对照组-无战斗辅助-丛林卡死.txt)。 这是本轮最有价值的一条实测结论——丛林关的失败不是操作问题,是数值/机制问题(见 §7.2)。
2.3 截图索引(docs/playtest-通关实录/)
| 文件 | 内容 |
|---|---|
01_enter_title.png | 标题 |
02_enter_prologue.png | 序章卧室 |
03_enter_arena_ch1_tut.png | 教学关(鹿人店夜景) |
04_enter_arena_ch1.png | 第一章第一波 |
05_death_1.png | 第一次死亡(水面浮起) |
06_boss_appear.png | 假面登场 |
07_death_2.png | 死在 Boss 手里 |
08_boss_phase_2.png | 假面二阶段(红眼) |
09_enter_chapter_end.png | 第一章完过场(白幕) |
10_enter_house.png | 进入第二章「家」 |
11–15_house_*.png | 卧室 / 客厅 / 书房 / 回客厅 / 回卧室 |
16_enter_arena_ch2.png | 第二章梦境(鹿人店夜战) |
17_death_3.png | 第二章死亡 |
18_enter_arena_ch21.png | 丛林 |
19_boss_appear.png | 石头 Boss 登场(公告期,本体还没生成) |
20_death_4.png | 石头 Boss 战死亡 |
21_enter_end_card.png | 结束卡进入 |
22_final_end_card.png | 结束卡 |
23_石头Boss本体.png | 石头 Boss 本体(--state=boss3 --auto 补拍) |
24_假面本体.png | 假面本体 + 血条(--state=boss 补拍) |
日志:通关日志-自动操作.txt(每 4 秒一次状态快照,含 t= 时间戳)、 对照组-无战斗辅助-丛林卡死.txt(同一套操作但去掉战斗辅助,证明丛林关卡死)、 关卡单测-丛林.txt(--state=arena3 单章跑通,93 秒)。
2.4 实测确认「真的能用」的东西
- 章节数据化(
Chapters.DATA)确实在驱动波次 / 敌人 / 背景 / 入梦对话 / Boss 类型; - 死亡重入不会把上一波刷回来(上一轮修的两条:
_boss_active+_run_token都生效); - 教学五步都能真的判定(含完美闪避与破梦;练习四贴身起滚成功率最高);
- 第一章完过场 → 第二章探索 → 睡过去 → 梦境战斗 → 丛林 → 结束卡,跨章衔接无断点;
- 存档面板、暂停菜单、历史对话、音量设置都在(本轮未逐个走完 UI,见 §9.3)。
2.5 实测暴露的问题(按影响排序)
1. 第二章丛林是难度断崖:不带战斗辅助时在「丛林 · 三」(3 野猪 + 2 藤蔓)连续死亡 15 次, 每次重开都是同一波满血,等于卡死;加上「看到起手就翻滚 + 破梦 + 重击控场」后才 1 次过关。 2. 藤蔓的减速是死亡螺旋(2026-10-27 已修,见文末「改动记录」):改版前被打中 → 6 秒内移速减半、不能翻滚、跳不高。 而丛林同时有 3 只冲锋野猪。一旦中了第一下,玩家几乎没有任何主动脱身手段(翻滚正是唯一解)。 3. 章节之间不回血:GameState.hp 跨章保留。三轮实测进入第二章梦境时血量分别是 1 / 1 / 2, 也就是第一章打完 Boss 剩多少血就带着多少血进第二章整章,而第二章、第三章都没有任何回血手段 (GameState.heal_player 全项目 0 调用)。 4. 石头 Boss 33 血比假面 26 血还厚,且没有二阶段、招式只有落石 + 石拳(2026-10-27 已加「掉头」两段式)。 5. 存档卡「进度」文字在石头 Boss 段仍显示 「Boss · 假面」(arena.gd:723 写死)。 6. 退出游戏时有 RIDs of type "CanvasItem" were leaked 警告(不影响游玩,属于退出清理不干净)。
3. 代码地图
3.1 目录职责
| 文件 | 行数 | 职责 | 关键点 |
|---|---|---|---|
scenes/main.gd | 276 | 总流程与屏幕切换 | 所有画面都是代码 new 出来的 Node2D;调试入口在 40–63 行 |
scenes/chapters.gd | 173 | 章节数据表 | DATA 9–159 行;get_data 缺 id 时静默回退第 1 章(165) |
scenes/arena.gd | 932 | 战斗关总装 | 波次 / 碎片 / Boss / 死亡重入 / 暂停 / 存档全在这 |
scenes/house.gd | 808 | 第二章现实层探索 | 4 个房间 + 单向平台 + 读书演出 + 花蕊虚影 |
scenes/tutorial_flow.gd | 139 | 教学五步状态机 | 每一步都要求真的做出来 |
scenes/dialogue.gd | 134 | 打字机对话 | 每句可带 who/color/text/hold/sfx |
scenes/prologue.gd | 342 | 序章脚本剧 | SCRIPT 7–40 行;date/line/eat/day/night/rewind/forward/end |
scenes/chapter_end.gd | 147 | 第一章完过场 | 台词 9–29 行;卡片「第 一 章 · 完」写死 64 行 |
scenes/end_card.gd | 66 | 结束卡 | _lines 8–15 行写死 |
scenes/title.gd | 125 | 标题 | 逐字浮现 + 狐狸立绘 |
scenes/arena_bg.gd | 412 | 战斗背景 | 有图用图 / 没图程序化;地面线 86% |
scenes/room_bg.gd | 72 | 现实层卧室背景 | day/night/eaten 三态 |
scenes/bot_driver.gd | 99 | --bot 自动操作 | 只会走位 + 平A + 偶尔翻滚 |
actors/player.gd | 774 | 玩家状态机 | 数值全在 17–49 行 |
actors/enemy.gd | 228 | 敌人基类 | 重力/受击/眩晕/死亡/镜头夹取 |
actors/mask_boss.gd | 376 | Boss「假面」 | 横扫/跃击/突进/扇形弹幕 |
actors/stone_boss.gd | 94 | Boss「丛林石像」 | 继承 MaskBoss,只用落石 + 石拳 |
actors/{shadow_soldier,eye_floater,charger,boar,vine,practice_dummy}.gd | 61–132 | 六个小怪 | 见 §4 |
actors/projectile.gd / rock.gd | 42 / 39 | 敌方投射物 / 落石 | 纯手工判定,不走物理层 |
actors/sprite_rig.gd | 242 | 位图主角 | 两张图(meimei.png / sword.png)+ 变换演动作 |
actors/fox_rig.gd | 366 | 死代码 | 程序化狐狸,已被 SpriteRig 取代,无引用 |
ui/hud.gd | 166 | 战斗 HUD | 血/碎片/连击/波次大字/Boss 血条/冷却/死亡计数 |
ui/pause_layer.gd | 204 | 战斗暂停菜单 | 7 项,纯键盘 |
ui/save_panel.gd | 182 | 存档面板 | 2×2 四格,自己算鼠标命中 |
autoload/game_state.gd | 309 | 全局状态/输入/字体/存档 | MAX_HP=5,4 格存档写在 exe 同级 |
autoload/sfx.gd | 404 | 全程序化音效 + BGM | 15 个合成音色 + 8 条 mp3 切段 |
autoload/feel.gd | 69 | 顿帧/慢动作/震屏 | 直接改 Engine.time_scale |
autoload/router.gd | 32 | 全屏淡入淡出 | layer 200,最高层 |
autoload/history.gd | 56 | U 键历史对话 | 最近 24 条 |
autoload/settings_ui.gd | 180 | 非战斗场景的 Esc 菜单 | 默认隐藏;标题/序章/house 里的读档入口 |
dev/auto_pilot.gd | 500 | 本轮新增:自动通关 | 仅 --auto 时挂载 |
3.2 屏幕切换与信号
main.gd
_goto_title() ──► TitleScreen ──pressed──► _goto_prologue()
_goto_prologue() ──► Prologue ──finished──► _goto_tutorial()
_goto_tutorial() ──► Arena(tutorial=true) ──finished──► _goto_chapter(1)
_goto_chapter(id) ──► (kind=="house") HouseScene ──finished──► _goto_chapter(2, force_arena)
└─► Arena(id) ──finished──► _on_arena_finished(id)
├ id<=1 → ChapterEnd → _goto_chapter(2)
└ id>1 → EndCard
Arena ──chapter_requested(id, wave, boss)──► _goto_chapter(...) # 读档跨章 / 第二章→丛林
_swap()(main.gd:97–102)负责清掉上一个屏幕并解除暂停。
3.3 CanvasLayer 层级(决定了「谁能盖住谁」)
-100 背景(ArenaBG)
0 世界/角色/玩家(z 1~4)
10 后处理 post.gdshader(ColorRect)
15 破梦/斩惑大字 + 屏幕层刀光
18 过场对话
20 HUD
50 ChapterEnd 的白/黑幕
55 HouseScene 的后处理
60 HouseScene 的对话
65/70/80 日期卡 / 章节卡
120 FlashLight 闪白
140 DeathInterlude 床头桌一闪
150 入梦白幕 / HouseScene 的 fade
160 PauseLayer
170 Boss 收尾白幕
180 SavePanel / History
190 SettingsUI
200 Router 转场(最高)
3.4 输入映射(game_state.gd:83–100)
move_left/right=A/D/←→ jump=空格 attack=J/鼠标左 heavy=K/鼠标右 roll=Shift/L interact=E pause=Esc confirm=Enter/空格/E debug_kill=F1 debug_shot=F12 手柄:A=跳、X=攻、Y=重、B=滚、Start=暂停。 注意:Dialogue / Prologue / TitleScreen / PauseLayer / SavePanel 全都直接判 KEY_*, 不吃 InputMap——加键位时这两套都要改。
4. 数值总表(改数值先看这里)
4.1 玩家(actors/player.gd)
| 项 | 值 | 行 |
|---|---|---|
| 血量 | 5(game_state.gd:9) | |
| 移速 / 加速 / 减速 | 430 / 3600 / 3400(空中 2000) | 17–20 |
| 跳跃初速 / 重力 / 截断 | −930 / 2500 / 0.42 | 22–24 |
| 二段跳 | −837(0.9×) | 252 |
| 翻滚 | 0.34s,无敌 0.05–0.26,速度 660,CD 0.10 | 27–30 |
| 空中冲刺 | 1150 速 0.15s,无敌 0.18 | 32–33 |
| 受击无敌 | 0.75s | 34 |
| 三段轻击 | 1/1/2 伤,框 118/124/140 宽,后摇 32% 可取消 | 37–41 |
| 破梦 | 5 伤,360×260,无敌 1.15s,CD 10s | 42 |
| 重击 | 3 伤,245×165,眩晕 1.0s(Boss 0.35s) | 44 |
| 斩惑 | 6 伤,绕身 400×96,0.3s 硬后摇,CD 10s | 47–49 |
| 完美闪避 | 翻滚 0.02–0.26 内被命中 → 0.32 倍慢动作 + 2.5s 窗口 | 525–562 |
| 空中砸地 | 落地半径 130、2 伤 | 566–592 |
| 场地边界 | 90–1830(arena.gd:153–154) |
4.2 敌人
| 敌人 | 文件 | HP | 行为 | 伤害 |
|---|---|---|---|---|
| 影卒 | shadow_soldier.gd | 3 | 走近 96px → 举刀 0.42s → 突刺 470 → 收招 0.55s | 1 |
| 浮瞳 | eye_floater.gd | 2 | 保持 330px 悬浮,蓄力 0.5s → 460 速弹幕 | 1 |
| 奔角 | charger.gd | 4 | 520px 内蓄力 0.7s → 900 速冲锋 → 撞墙硬直 1s | 1 |
| 野猪 | boar.gd | 7 | 同奔角(继承),血更厚,scale 1.7 | 1 |
| 藤蔓 | vine.gd | 3 | 不动,2 秒一次:近身 0.55s 抽打(可跑开)/ 中距离吐绿色种子(330 速,可滚可跳);命中「缠绕」3 秒(可翻滚) | 1 + bind |
| 木桩 | practice_dummy.gd | 9999 | 0.9s 举刀 → 0.26s 挥,0 伤害 | 0 |
4.3 Boss
| Boss | 文件 | HP | 招式 |
|---|---|---|---|
| 假面 | mask_boss.gd | 26 | 横扫(0.55s 单帧判定,半径 236)/ 跃击地震(左右两发冲击波)/ 2–3 连突进 980 速;半血二阶段加扇形 5 连弹 |
| 丛林石像 | stone_boss.gd | 33 | 落石 ×3(0.9s 圈,74px、2 伤)/ 砸地(0.5s 抬手 + 红色落点预警,270px、2 伤);≤17 血掉头 → 身体 10 血 + 飞头 7 血(stone_head.gd:浮瞳同款弹 / 锁定冲撞) |
4.4 章节数据(scenes/chapters.gd)
| id | 标题 | kind | 波次 | 碎片 | Boss |
|---|---|---|---|---|---|
| 1 | 第一章 · 鹿人店的一天 | arena | 5 波(2/4/4/4/5 只) | 第 2 波后 | 假面 |
| 2 | 第二章 · 家 | house | 3 波(梦境) | 无 | 无(打完转 21) |
| 21 | 第二章 · 丛林 | arena | 3 波(3/4/5 只) | 无 | 石像 |
5. 内容接口手册(「我要加 X」→ 改哪里)
5.1 改台词 / 加一段对话(不碰逻辑)
| 想改的 | 文件 | 位置 |
|---|---|---|
| 序章全部 | scenes/prologue.gd | SCRIPT 7–40 行({"t":"line","who":…,"text":…}) |
| 章节入梦对话 | scenes/chapters.gd | 各章 "intro"(第一章 15–29,第二章 67–71,梦境 73–95) |
| 丛林无开场白 | 同上 | 21 章 "intro": [],要加就填 |
| 波次标题/提示 | 同上 | "waves"[i].title / prompt |
| 打完转下一章的过渡台词 | 同上 | "next_lines"(116–120) |
| Boss 登场台词 | 同上 | "boss_intro"(155–157,目前只有 1 句) |
| 第一章完:梦醒台词 / 核桃黑屏 | scenes/chapter_end.gd | WAKE_LINES 9–15 / BLACK_LINES 19–29 |
| 第二章探索:拿书 / 读书 / 纸条 / 入夜 / 吃药 | scenes/house.gd | BOOK_LINES 59–63 / READ_LINES 66–79 / NOTE_LINES 82–100 / NIGHT_LINES 103–110 / BED_LINES 113–132 |
| 结束卡 | scenes/end_card.gd | _lines 8–15 |
| 教学五步文案 | scenes/tutorial_flow.gd | TITLES 8–14 / PROMPTS 16–22 |
| 玩家操作提示 | autoload/game_state.gd | guide_text() 173–193 |
| 敌人/波次提示 | scenes/arena.gd | hud.prompt(...) 调用点 |
注意:Dialogue 会自动折行(每行 46 字,dialogue.gd:57–63),每句停留 0.95 + 0.075×字数 秒。 一行 32 个汉字是舒服的长度。说话人颜色用 "color": "#rrggbb",不写就是浅橙。
5.2 加一波怪
1. scenes/chapters.gd 对应章节 "waves" 数组里加一项:
{"title": "训 练 · 六", "prompt": "提示文字", "enemies": [["boar", 1300.0], ["vine", 1700.0]]}
enemies 里是 [kind, x],地面 y 统一 780,x 建议放在 384–1536 内(镜头可见范围)。 2. 新 kind 要在 arena.gd:_spawn_enemy()(410–434)的 match 里注册。
5.3 加一个新敌人
class_name MyEnemy
extends Enemy
func _ready() -> void:
max_hp = 5
radius = 24.0
body_top = -70.0
super._ready()
scale = Vector2(1.4, 1.4)
func _think(delta: float) -> void: # 状态机:用 state / state_t
...
func _contact_hit_active() -> bool: # 只有这些状态会造成接触伤害
return state == "lunge"
func body_color() -> Color: return Color("#1a1528")
func accent_color() -> Color: return Color("#7d4fd0")
func _draw_ghost(c, w, p) -> void: ...
func _draw_body(col, pulse) -> void: ...
然后在 arena.gd:_spawn_enemy 注册。注意:
Enemy._keep_in_view()会把怪夹在镜头内(±44px),别让招式依赖"跑出画面";take_hit的击退对 boss 组减到 0.35 倍(enemy.gd:147);- 眩晕:
stun(seconds),Boss 覆盖成 0.35s; - 血条只有
hp < max_hp && hp > 0才画(enemy.gd:201)。
5.4 加一个新 Boss
最省事的做法是继承 MaskBoss(stone_boss.gd 就是模板,94 行):
class_name MyBoss
extends MaskBoss
const HP := 30
func _ready() -> void:
super._ready()
max_hp = HP; hp = HP
body_top = -200.0
scale = Vector2(1.8, 1.8)
state = "idle"; _decide_cd = 1.2
func _think(delta: float) -> void: # 覆盖招式表即可
...
func _draw() -> void: # 纯程序化绘制
...
然后在章节数据里写 "boss": true, "boss_kind": "mykind", "boss_title": "...", "boss_prompt": "...", "boss_intro": [...], 并在 arena.gd:635 的 if boss_kind == "stone" 旁边加分支。
Boss 相关的东西现在是参数化的:名字(hud.set_boss_name)、登场大字、提示、登场台词都从章节数据读。 没参数化的:血条右侧的「二阶段」字样(hud.gd:138)、存档进度里的「Boss · 假面」(arena.gd:723)。
5.5 加一整章(重点)
1. scenes/chapters.gd 的 DATA 里加一条:
31: {
"id": 31, "title": "第三章 · …", "save_label": "第三章 · …",
"bg": "res://assets/bg/xxx.jpg",
"intro": [...], # 入梦对话(空镜头)
"dream_intro": [...], # 若 kind=house,这一段是睡过去之后的梦话
"waves": [...],
"fragment_after": -1, # 第几波后出碎片
"boss": true, "boss_kind": "mykind", "boss_title": "...", "boss_prompt": "...",
}
2. scenes/main.gd 决定路由:
- 战斗章直接
_goto_chapter(31); - 现实层章
kind: "house",要同时改house.gd:156的GameState.chapter_id = 2(现在写死 2),否则读的是第二章的intro和房间数据; _on_arena_finished()(230)现在是chapter <= 1 ? 第一章完 : 结束卡,加第三章要在这里加分支;- 加一个
--state=arena4调试入口(40–63 行)。
3. 过场:chapter_end.gd 的卡片写死「第 一 章 · 完」和日期「十 月 23 日」,新章要参数化或复制一份。 4. 存档:不用改,chapter_id 已经存了;但 save_panel.gd 的章节名是读存档里的 chapter 字段,所以要保证新章 save_label 写对。
5.6 换背景图
- 把图放到
assets/bg/,章节数据"bg": "res://assets/bg/xxx.jpg",Arena._build_world会传给ArenaBG.photo_path。 - 地面线算法写死在
arena_bg.gd:91:top = 780 - 0.86 * (1920 * tex_h / tex_w)。
意思是"图片高度的 86% 处"对齐到游戏地面 y=780。新图的地面不在 86% 就会浮空或陷进地里。 要么选一张地面正好在 86% 的图,要么把 PHOTO_GROUND 从 const 改成章节字段(推荐,见 §6)。
- 缺图 / 路径写错会静默回退成鹿人店(
arena_bg.gd:33–37只在文件不存在时回退,没有警告)。 - 照片以下的沙地(y 780–1080)是程序化的,配色
#6e5847 → #211a1c是鹿人店黄昏调,换季节要一起改。
5.7 加音效 / 音乐
- 合成音效:
autoload/sfx.gd的_build_bank()(314–386),加一条_bank["名字"] = _wav(...),然后Sfx.play("名字")。 - 外部采样:
SAMPLE_CUTS(9–18)8 条,字段{sample, from, dur, pitch, db}。
现在 4 条挥剑全是 from: 0.0(只靠 dur/pitch 区分),听起来像同一段开头——想更像不同招式,给 from 填不同起点。
- BGM:
music_calm / music_battle / music_reading(76–90),三首 wav 在assets/sfx/,音量常量 25–27 行。 - 环境 drone:开机即响,
set_drone_pitch/volume调,stop_drone()有实现但从未调用。
5.8 加 UI
- 战斗 HUD:
ui/hud.gd全draw_*手绘,加东西直接_draw()里画,注意 1920×1080 绝对坐标。 - 暂停菜单:
ITEMS数组 +_activate()的 match 必须同步改(pause_layer.gd:13与170–204)。 - 存档面板:4 格写死在
save_panel.gd:11,143和_slot_rect的 2 列网格(46–50),改槽位数会越界崩溃。
6. 阻碍拓展的硬编码清单(按严重度)
【高】加第三/四章之前必须处理
2026-10-28 更新:house 章节 id / 地面线 / 碎片位置 / get_data 报错 / 结束卡 + 路由 已经全部改掉(见 §15.1)。 表里 1–7 号现在都已完成,只剩 8 号(现实层房间数据化)。
| # | 位置 | 问题 | 修法 |
|---|---|---|---|
| 1 | scenes/house.gd:156 | GameState.chapter_id = 2 写死 | 改成从 main 传入的章节 id(HouseScene 加 var chapter := 2,main 里赋值) |
| 2 | scenes/arena_bg.gd:10,91 | 地面线 86% 是 const | 加 photo_ground 字段,章节数据里可覆盖 |
| 3 | scenes/arena.gd:585 | 记忆碎片坐标写死 (960, 520),Chapters.DATA 里没有这个字段 | 加 "shard_pos": [960, 520],Arena 读 |
| 4 | scenes/arena.gd:723 | 存档进度写死「Boss · 假面」 | 改成 String(_data.get("boss_title","Boss")) |
| 5 | scenes/main.gd:231<br>239 / 264 | if chapter <= 1 硬判第一章完;两处 _goto_chapter(2) 写死 | 加 "end_flow" 字段(chapter_end / end_card / custom) |
| 6 | scenes/chapters.gd:162–165 | get_data 缺 id 静默回退第 1 章 | 缺 id 时 push_error 并回退,方便发现漏配 |
| 7 | scenes/end_card.gd:8–15<br>scenes/chapter_end.gd:64,86 | 结束卡文案 / 「第一章·完」/ 日期写死 | 按 GameState.flags 或章节 id 参数化(三结局的前置) |
| 8 | scenes/house.gd:29–56,21–26 | 4 个房间、门位、平台、目标(找书)全写死 | 想做第三个现实层场景,就把 ROOMS/PLATFORMS 提成参数(工作量中等) |
【中】影响体验/手感,建议随内容一起改
| # | 位置 | 问题 | ||||
|---|---|---|---|---|---|---|
| 9 | ~~vine.gd 藤蔓减速 6 秒 + 禁止翻滚~~ | 已修(2026-10-27):缠绕改为 3 秒、移速 ×0.6、跳高 ×0.65、翻滚仍可用;抽打补距离检查;新增种子弹;节奏改 2 秒 | ||||
| 10 | arena.gd 全篇 | 章节间不回血;建议每章开场回满、或给 1 个回血道具/碎片 | ||||
| 11 | autoload/feel.gd:31–56 | hitstop 结束无条件 time_scale = 1.0,会截断正在进行的慢动作;且 Engine.time_scale 没有引用计数 | ||||
| 12 | autoload/router.gd:18–32 | fade_out/fade_in 不 kill 旧 tween;arena.gd:237,300,370 三处调用没有 await,可能和后续 _swap 打架 | 13 | fx/post.gdshader | 15 个 uniform 里 grain/aberration/scanline/brightness/tint 从未被设置,只有默认值生效 | |
| 14 | scenes/arena.gd:702–715 | _reset_post() 没复位 spot_radius(Boss 收尾会压到 0.015,重开后第一次聚光半径不对) | ||||
| 15 | actors/sprite_rig.gd | 没有 "dash" 状态,但 player.gd:649 会写 rig.state = "dash"(空中冲刺没有专属姿态) | ||||
| 16 | actors/fox_rig.gd | 366 行死代码(已被 SpriteRig 取代),改玩法时容易误改 | ||||
| 17 | autoload/sfx.gd | shatter 音效无调用;4 条挥剑 cut from 全 0;stop_drone 无调用 | ||||
| 18 | ui/pause_layer.gd | resume_requested 无人连接、guide_requested 从不 emit(死信号);菜单 7 项写死 | ||||
| 19 | ui/save_panel.gd:78–85 | ↑ 和 ↓ 行为完全相同(都是 (_sel+2)%4),2×2 网格导航其实是坏的 | ||||
| 20 | scenes/prologue.gd:224–247 | return 之后有 20 多行死代码 | ||||
| 21 | autoload/history.gd:40–56 | 打开时 paused=true,关掉时若 PauseLayer 可见就提前 return,可能留下"面板开着但没暂停"的状态 | ||||
| 22 | 退出游戏 | RIDs ... leaked / ObjectDB instances leaked(退出清理,不影响游玩) | ||||
| 23 | actors/enemy.gd:108–126 | _keep_in_view() 只夹中心点,Boss 体型 1.55–1.9 倍时会有半个身子露在屏幕外(23_石头Boss本体.png 里就能看到,玩家在左端时石头 Boss 被裁到只剩一半) |
【低】文档与实现不一致(别照着文档改)
- README 说重击有「235px 突进」,实际位移只有约 6–8px(
player.gd:411)。 - 「从背面打」没有背击加成,只有横扫判定圆心在身前所以背后安全。
操作说明.txt说「本版本是战斗验证版」,但现在已经包含第二章探索 + 丛林。剧本-v1-待填.txt/文案-待修改.txt停在 v0.1(还没有第二章、丛林、石头 Boss 的条目)。
7. 设计层面的实测结论
1. 翻滚仍然是一招通吃:0.34s 里 0.21s 无敌、0.1s 冷却、无消耗 → 48% 时间可以无敌。 上一版文档的这条结论本轮再次被验证(bot 靠"看到起手就滚"就能撑过大部分场面)。 2. 丛林章是当前唯一的难度断崖:3 野猪 + 2 藤蔓(2026-10-27 改了藤蔓后缓和了不少,但仍是全游戏最难的一段)。 建议在加第三章之前先把它调到"死 2–3 次能过"。 3. 石头 Boss 的问题不是难,是磨:33 血、无二阶段、招式只有两种,熟练后是重复劳动。 要么降到 26–28 血,要么加一个二阶段(它继承 MaskBoss,加招式成本很低)。 4. 章节之间的资源没有重置:血、碎片、死亡计数全部跨章带走。碎片数在第三章还显示第一章捡的那 1 个, 而第二章、第三章都没有碎片可捡 → 这个数字现在没有意义。 5. 剧情是"骨架占位":第二章探索的文本(医书、纸条、花蕊大夫)反而比战斗章完整,说明文本质量不是瓶颈, 瓶颈是"每一章都要新做一套场景/敌人/过场"。
8. 下一步路线建议(按性价比排序)
| 优先级 | 事项 | 工作量 | 收益 |
|---|---|---|---|
| P0 | 把 §6 的 1–8 号硬编码参数化(house 章节 id、地面线、碎片位置、Boss 名、结束卡、章节路由、存档进度文字) | 0.5–1 天 | 后面每加一章都省事;现在不改,加第三章时会一次性撞上 |
| P0 | 藤蔓减速改短 / 允许翻滚;每章开场回满血 | 2–3 小时 | 直接解决唯一的难度断崖 |
| P1 | 标题页加「继续游戏」(现在只能进关卡后按 Esc 读档) | 半天 | 玩家体验最大的一个缺口 |
| P1 | 石头 Boss 加二阶段(继承 MaskBoss,抄假面的扇形弹幕) | 半天 | 让丛林 Boss 不再只是血包 |
| P2 | 第三章:按 剧本-v1-待填.txt 的「新增场景申请表」填 → 我接进 Chapters.DATA | 看你填多少 | 内容推进 |
| P2 | 结局系统:GameState.flags 已就绪,end_card.gd 参数化后按 flags 走不同结尾 | 1 天 | 三结局的前置 |
| P3 | 存档改到 user://(现在写在 exe 同级,装 Program Files 会写不进去) | 2 小时 | 上架前必须做 |
| P3 | 字体子集化(msyh 19.7MB + simhei 9.7MB 占了 pck 大头) | 半天 | 包体从 32MB 降到 ~6MB |
9. 工具与命令
9.1 跑源码
E:\godot\Godot_v4.5-stable_win64.exe --path <lost-dream> # 有窗口,带调试
E:\godot\Godot_v4.5-stable_win64_console.exe --path <lost-dream> # 带控制台输出(看 print)
9.2 调试入口(main.gd:40–63)
-- --state=title|prologue|tutorial|arena|arena2|dream2|arena3|boss|boss3|fragment|chapterend|chapter2end|epilogue|end
-- --bot 自动战斗(BotDriver)
-- --auto 自动通关(dev/auto_pilot.gd,本轮新增)
-- --autodir=<路径> 自动通关的截图目录
-- --god 无敌(注意:god 下完美闪避触发不了)
-- --tutskip 教学关自动推进
-- --slow 0.25 倍速
-- --keybinds 直接打开按键设置面板
-- --keytest 按键绑定自检(改键/冲突/存读/恢复默认)
-- --sfxtest 音效试听
-- --spottest 小必杀效果常开
-- --shot=<路径> --delay=秒 截图后退出
-- --shots=<前缀> --count=N --interval=秒 连拍
-- --savetest[=load] / --pausetest 直接打开存档面板 / 暂停菜单
-- --room=study|living|kitchen|bedroom HouseScene 直接进某间房
两个坑:
--state=arena3直接跳丛林时,重击是没解锁的(GameState.reset_run()清空 unlocked),
想测重击要从第一章打上去或加 --state=fragment。
--state=arena2进的是 HouseScene(因为 chapter 2 的kind是 house),--state=dream2才是第二章的梦境战斗。
9.3 自动通关(本轮新增)
E:\godot\Godot_v4.5-stable_win64_console.exe --path <lost-dream> -- --auto --bot --autodir=<截图目录>
行为:自动点标题 → 快进序章 → 教学五步 → 战斗(bot + 危险翻滚/破梦/重击)→ 第一章完 → house 导航(找书/读书/回床睡觉)→ 第二三章战斗 → 结束卡截图 → 自动退出。 每 4 秒打一行状态;同一波卡 150 秒会临时开无敌并警告。
用途:每次加完章节后跑一遍,5 分钟内验证"全流程不崩、能到结束卡",并自动出一套截图。 实测 264 秒通关,跑完进程自己退出。
9.4 打包(2026-10-27 实测:只导 pck 不需要导出模板)
exe + 外置 pck 的结构下,更新游戏内容只要重打 pck,exe 完全不用动:
E:\godot\Godot_v4.5-stable_win64_console.exe --headless --path <lost-dream> \
--export-pack "Windows Desktop" <输出目录>\迷途之梦.pck
然后把产物覆盖到 exe 同级目录(同名 迷途之梦.pck)。
exclude_filter已排除shots/ docs/ build/和几个 txt。这一步很重要:
docs/playtest-通关实录/ 现在有 23MB 实机截图,不排除的话 pck 会从 34MB 涨到 56MB。
- 只有需要重新导出可执行文件(162MB 模板)时才要装 4.5.stable 导出模板,本机没装。
- 本轮已导出并替换到
E:\godotgame\迷途之梦-未成品\(旧 pck 备份迷途之梦.pck.bak-改版前),
新 pck 同时存进 build/迷途之梦.pck(34,244,384 字节)。
- 校验:用户目录的 exe + 新 pck 跑完整
--auto --bot,25 张截图一直到final_end_card。
10. 需要你拍板的问题
1. 下一步是「补第二章体验」还是「开第三章」? 我建议先花一天把 P0 的硬编码和藤蔓/回血改掉,再开新章——否则新章会把这批债再复制一遍。 2. 第三章的场景是什么?(梼杌洞府 / 天庭 / 回忆里的某个地方 / 继续现实层) 如果是新的现实层地点,house.gd 那套 4 房间结构要参数化,工作量比战斗章大。 3. 要不要保留「每章一个 id 两套内容(现实层 + 梦境)」这个模式? 现在 chapter 2 同时是 house 和梦境战斗,靠 force_arena 复用;第三章如果也这样,建议加个 "dream_battle_waves" 字段分开。 4. 结局要不要现在做? 如果要,end_card.gd 必须先参数化,GameState.flags 已经是现成的。 5. 难度目标:你想要「死 2–3 次能过」还是「一命通关」?这决定藤蔓/野猪/Boss 血的调整幅度。
*附:本轮的实测证据(截图 + 日志)在 docs/playtest-通关实录/;自动通关代码在 dev/auto_pilot.gd。*
11. 改动记录 · 2026-10-27(藤蔓 / 石像 / 第二章对话)
11.1 藤蔓(actors/vine.gd 重写 · 新增 vine_seed.gd、fx/vine_bind.gd)
| 项 | 改版前 | 改版后 |
|---|---|---|
| 攻击节奏 | 0.95 秒一轮、无冷却 | 2 秒一次(两招共用) |
| 抽打判定 | 无距离检查(必中) | 出手那一帧判 absf(dx) < 250,跑出去能躲 |
| 新招式 | — | 绿色种子:330 速、半径 10、1 伤、命中挂缠绕;近身 45% 概率也会吐 |
| 缠绕时长 | 6 秒 | 3 秒 |
| 缠绕时翻滚 | 禁用 | 仍可用(0.85 倍速) |
| 缠绕跳跃 | ×0.2 | ×0.65 |
| 缠绕表现 | 只有闪白 | 身上缠三圈绿藤 + 叶子(VineBind) |
关键修复:apply_vine_slow() 不再被"必中"的无条件调用触发;Projectile 新增 bind 字段,由种子命中时挂上。
11.2 石像(stone_boss.gd 重写 · 新增 stone_head.gd)
- 掉头:HP ≤ 17 时
_split()→ 身体max_hp/hp = 10,生成飞头(7 血)。总血量仍是 17。 - 飞头:悬停离地 250px,两招——浮瞳同款种子弹(0.45s 蓄力、460 速)/ 锁定冲撞(0.55s 红虚线 + 落点圈、700 速、1 伤 + 420 击退,之后 1.25s 恢复)。
- 砸地预警:抬手期间画红色落点圈 + 范围线(原来只有抬手动作)。
- 掉头演出:慢动作 0.45×/0.9s、震屏、白闪、10 颗碎石、玩家 1.6 秒无敌、HUD「头 掉 了」。
- Arena:新增
_boss_parts数组,血条按「全部个体剩余 / 33」每帧计算,所有个体都死才播收尾。
11.3 第二章入梦对话(scenes/arena.gd:_intro)
改成和第一章教学关一致:
入梦白幕 → 空镜头对话(主角隐藏 + 物理停用)→ 恍惚(去色/扭曲/淡入)→ 主角浮现 → E 拔剑 → 波次
改版前是"拔剑之后、角色已经能动的时候"播对话(边跑边说话),现在是独立的过场。
11.4 顺手修掉的两处
arena._progress_text():Boss 存档进度不再是写死「Boss · 假面」,改用boss_title。player.speed_scale:不再被缠绕逻辑每帧覆盖(原来会把 Boss 收尾的 0.1 倍速冲掉)。
11.5 验证
--state=arena3 --auto --bot:种子发射、掉头、双个体击杀全部正常。- 完整
--auto --bot通关:281 秒(改版前 264 秒),死亡 4 次。 - 章节 2 对话:
--state=dream2连拍确认「空镜头 → 恍惚 → 浮现 → 拔剑」。 - 导出版验证:
--export-pack重打 pck(34.2MB)→ 覆盖E:\godotgame\迷途之梦-未成品\迷途之梦.pck
→ 用原 exe 跑完整 --auto --bot,25 张截图直到 final_end_card,说明打包产物里的新脚本/新类都正常。
注意:新增了class_name(VineSeed / VineBind / StoneHead),需要在编辑器里打开一次项目(或跑godot --headless --path . --import)让 Godot 重建全局类缓存,否则会报Could not find type。
12. 键位系统(2026-10-27 新增)
12.1 结构
| 文件 | 职责 |
|---|---|
autoload/keybinds.gd | 动作表 BINDABLE、改键/冲突/恢复默认、读写 keybinds.json、apply_all() 重建 InputMap |
ui/keybind_panel.gd | 全屏手绘面板(9 行列表,↑↓ 选择,Enter 改键,Del 恢复该项,Backspace 全部恢复) |
ui/pause_layer.gd | 菜单新增「按 键 设 置」(第 7 项),发 keybind_requested |
autoload/settings_ui.gd | 非战斗菜单同样新增一项,自己持有面板 |
scenes/arena.gd | 创建面板(CanvasLayer 195),接 keybind_requested |
12.2 可绑的 9 个动作
move_left / move_right / jump / attack / heavy / roll / interact / pause / history
不绑的:confirm(对话/菜单确认,固定 Enter/空格/E)、方向键导航、debug_*。 这样保证"改键之后菜单还能操作"。
12.3 三个实现要点(改这块之前先看)
1. 只重建键盘事件:apply_all() 会把 InputEventKey 剔掉再加新的,手柄/鼠标事件原样保留(否则接手柄的玩家会被改键踢掉)。 2. 配置值 vs 生效值:_raw_keys() 是 json 里写的,keys_of() 是 apply_all() 算出来的"实际生效"。 两者分开是为了处理"手改 json 造成跨动作撞键"——现在按 BINDABLE 顺序先到先得,后面的显示「未绑定」。 3. 关闭菜单跟随 pause 动作:PauseLayer / SettingsUI 的关闭不再判 KEY_ESCAPE,改成 event.is_action_pressed("pause"); History 也改成跟随 history 动作。但对话继续、菜单导航仍然是裸 keycode(见 §6 第 18 条)。
12.4 存档
keybinds.json 写在 exe 同级(和 save1.json 一起),写不进去时退到 user://keybinds.json,读的时候两边都找。 格式:
{"version":1,"keys":{"jump":[32],"attack":[74],"roll":[4194325,76], ...}}
值是 physical_keycode(不是 keycode),对非 QWERTY 布局更友好。
12.5 验证
--keytest:改键 → InputMap 生效 → 存盘 → 重载 → 恢复默认,全绿(自检会打印每一步)。--keybinds:直接开面板截图。- 实机:
E:\godotgame\迷途之梦-未成品\下跑--keytest生成了keybinds.json;手写{"attack":[85]}后启动,面板显示「轻击 U / 历史对话 未绑定」,与预期一致。
13. 第二章结尾过场(2026-10-27 新增)
13.1 流程
丛林石像被打死(身体 + 飞头都死)
→ Arena._stone_epilogue()
慢动作 → 画面虚化(wave 1.0 / desaturate 0.9 / 暗角 2.3)
→ 主角淡出消失(rig.modulate.a → 0,物理停用)
→ 核桃的 11 句对话(画面里没有人)
→ Router.fade_out 到暗
→ main._goto_chapter2_end()
→ Chapter2End(scenes/chapter2_end.gd)
黑屏 + 闹钟音效(新增 Sfx "alarm")→「叮叮叮……(闹钟响了)」
→ 黑屏上缓缓浮出日期卡「十 月 24 日」(上浮 + 淡入)
→ 黑幕淡开露出白天的房间 → 醒来 5 句(发现没有闹钟 → 慌了 → 喊花大夫)
→ 旁白「空的药瓶被撞翻……慕容雪川离开了房间」
→ 黑幕压上 → 黑屏对话 8 句(核桃 + 梼前辈:闹钟/纸条/「当初为什么活下来」)
→ 「第 二 章 · 完」
→ 结束卡
13.2 和第一章的区别
第一章完(chapter_end.gd) |
第二章完(chapter2end.gd) |
|
|---|---|---|
| 结尾演出 | Arena 的白圈收尾(全屏白 → 灰 → 黑) | 不播白圈,改成场景虚化 + 主角消失 |
| 对话位置 | 醒来之后(房间里) | 斩杀瞬间(梦里),画面里没有主角 |
| 过渡 | 白 → 白天房间 | 黑 → 闹钟 → 睁眼 |
| 音效 | 无(只有对话) | 新增 alarm 三连「叮」 |
第二章故意不用白圈:白圈是"战斗胜利"的符号,而这一场要的是"梦突然醒了"的错位感。
13.3 新增的调试入口
--state=epilogue:直接进丛林关、跳过战斗,播尾声(虚化 + 核桃对话 + 变暗)。改这段演出的验收就用它。--state=chapter2end:直接看「叮叮叮 → 睁眼 → 第二章完」。
13.4 顺手修的一处
_stone_epilogue() 开头 hud.set_boss(-1.0):原来 Boss 血条会留在屏幕上和尾声对话叠在一起(调试入口第一次截图时发现的)。
14. 改动记录 · 2026-10-28(章节回血 / 可读性 / HUD 重排)
这一轮只做「让当前版本能验收」的事,石像与野猪的数值一律没动(按你的要求)。
14.1 章节之间回满血
- 新增
GameState.refill_hp()(autoload/game_state.gd,紧挨heal_player)。 - 调用点只有 4 处「换章瞬间」:
main._on_tutorial_finished(进第一章)、main._on_chapter_end_finished(进第二章·家)、 main._on_house_finished(进第二章梦境)、arena._next_stage(梦境 → 丛林)。
- 读档不回血:读档走
Arena._load_slot → GameState.apply_save,不经过上面 4 个函数。 - 验证:全自动通关里,进入第二章梦境、进入丛林时 HUD 都是 5 个菱形
(switch/final/15_enter_arena_ch2.png、16_enter_arena_ch21.png)。
14.2 亮背景可读性(新增 GameState.draw_text)
static func draw_text(ci, font, pos, text, align, width, font_size, color): 先 draw_string_outline(描边宽度 = 字号 × 0.10,最低 2,Color(0.03,0.02,0.05,alpha×0.7))再 draw_string。 它只加字周边的暗边,不改基线、不改排版宽度,所以原有坐标全部照旧。
用在这些地方:
| 文件 | 用到的位置 |
|---|---|
ui/hud.gd | 碎片计数、连击、波次大字(Boss 登场名也走这里)、Boss 名、二阶段、破梦/斩惑、冷却、提示、死亡计数 |
scenes/dialogue.gd | 说话人名字、正文(逐字显示也走它) |
没动的:标题、结束卡、章节卡、日期卡(都在深色底上,加了反而脏)。
14.3 HUD 底部重排(消除叠字)
| 元素 | 旧 y | 新 y |
|---|---|---|
| Boss 血条 | 980 | 952 |
| 操作提示 | 1020 / 26px | 1020 / 24px |
| 破梦·斩惑 | 1040 / 1072 | 1052 / 1074 |
| 冷却文字 + 条 | 1040 / 1046 | 1052 / 1060 |
| 死亡计数(右) | 1060 | 1064 |
| Dialogue 底部提示 | 988 | 976 |
以前「提示 / 破梦 / 完美闪避后 2.5 秒 / 冷却条」四层挤在 60px 里,实测会压字;现在每层至少隔 7px。
14.4 文案与版本号
scenes/end_card.gd:去掉两行开发者留言,改成
「梦到这里就断了。」/「—— 垂 直 切 片 · 完 ——」/「如果有明天的话。」/「下一段梦,还没做完。」
scenes/title.gd:版本号 →「垂直切片 v0.2 · 第一 / 二章」操作说明.txt:开头改成「两章可玩版」,Esc 菜单补全 8 项,补一条「每章开头自动回满血」README.md:标题 v0.2,补一条回血说明
14.5 验收
- 全自动
--auto --bot:407 秒通关到结束卡,死亡 7 次
(第一章 1 次、第二章梦境 0 次、丛林石像 6 次 —— 石像段仍是唯一的卡点)。
- 导出版 pck:
34,289,368字节 / MD544C412AF6AA68CF337AABD8C69BB634B,
已覆盖 E:\godotgame\迷途之梦-未成品\迷途之梦.pck,旧包备份为 迷途之梦.pck.bak-调平前。
- 截图:
switch/final/(26 张)、switch/verify4/announce_jungle.png(丛林里的描边效果)。
15. 改动记录 · 2026-10-28(工程收口:硬编码参数化 / 主菜单 / 存档改 user://)
15.1 §6 的 1–5 号硬编码全部改掉
| # | 原来 | 现在 |
|---|---|---|
| 1 | house.gd 写死 GameState.chapter_id = 2 | HouseScene 新增 var chapter := 2,main._goto_chapter 在 add_child 前赋值;入梦对话也读 Chapters.get_data(chapter) |
| 2 | arena_bg.gd 地面线写死 const PHOTO_GROUND = 0.86 | 实例变量 photo_ground,Arena._build_world 用章节数据 "photo_ground" 覆盖(不写就还是 0.86) |
| 3 | arena.gd 碎片坐标写死 (960, 520) | 章节数据 "shard_pos": [x, y](第一章已显式写 960/520) |
| 4 | chapters.get_data 缺 id 静默回退 | 先 push_error 报出缺哪个 id,再回退第一章 |
| 5 | end_card.gd 文案写死 + main 用 chapter <= 1 / == 21 硬判 | 章节数据新增 "end_flow"(chapter_end / chapter2_end / end_card)、"end_next"(过场之后进哪章)、"end_card"(结束卡文案数组);main._on_arena_finished 只读 end_flow |
顺手一起的:
- Boss 名兜底从「假 面」改成
"Boss"(名字一律来自boss_title)。 save_panel遇到老存档没有chapter字段时,用chapter_id反查Chapters.title(),不再硬写「第一章 · 鹿人店」。- 新增章节只要写
end_flow+end_next,main不用再改。
15.2 新的一页:主菜单 scenes/main_menu.gd
标题(任意键)→ 主菜单 → 开始游戏 / 继续游戏 / 音量设置 / 按键设置 / 攻略 / 退出游戏
└─ Esc 回标题
- 没有标题页里塞「继续游戏」,按你说的另起一页。
- 继续游戏:
GameState.latest_slot()在 4 格里按stamp挑最近的一份,
直接 apply_save + 进章,不弹面板;列表下方常驻「最近存档:章节 时间(存档 N)」。 没有存档时这一项是灰的,后面带「(没有存档)」。
- 音量设置 / 攻略:这一页自己的覆盖层(← → 调 BGM;Esc 返回),走
Sfx.music_get_gain/set_gain。 - 按键设置:复用
ui/keybind_panel.gd,面板打开时主菜单不再画列表(避免字透出来)。 SettingsUI在_input里检测到main_menu组就不再抢 Esc,否则会在主菜单上叠一个暂停菜单。- 调试入口:
--state=menu直接进主菜单;--menutest=N用真实按键事件按 N 次 ↓ 再 Enter。
15.3 存档改到 user://(上架前置)
GameState.slot_path()→user://save%d.json;Keybinds.save_path()→user://keybinds.json。
Windows 实际位置:%APPDATA%\Godot\app_userdata\迷途之梦\。
- 启动时
migrate_legacy_saves()一次性搬家:先搬save1~4.json,最后才搬更老的save.json
(反过来的话,老的 save.json 会抢掉第 1 格——实测踩过一次)。原文件不删。
keybinds读档顺序:user://→ exe 同级(只读兼容);写只写user://。- 存档失败的提示从「目录不可写」改成「写不进 user:// 目录」。
15.4 存档字段新增
| 字段 | 用途 |
|---|---|
in_arena | 继续游戏时决定落在 Arena 还是 HouseScene(第二章的「家」和「梦境」共用一个 id) |
tutorial | 存在教学关里的档,继续时回到教学关而不是第一章 |
SettingsUI 的 load_requested 信号同步加了这个参数(4 个参数),main._on_settings_load 负责分流; 战斗关自己的 chapter_requested 一律 force_arena = true。
15.5 验收
--menutest=0/1/2/3/4实机按键走一遍:→prologue/arena(读最近档)/ 音量覆盖层 / 按键面板 / 攻略页。- 存档迁移实测:exe 目录的
save1~3.json搬到%APPDATA%\…\迷途之梦\,第 1 格 219 字节 = 原save1.json。 - 完整
--auto --bot:479 秒通关(标题 → 主菜单 → 序章 → 教学 → 第一章 → 梦醒 → 家 → 第二章梦境 → 丛林 → 第二章完 → 结束卡),
丛林石像那段死了 10 次、触发 150 秒看门狗无敌——石像数值按你的要求没动。
- 导出版 pck 已覆盖
E:\godotgame\迷途之梦-未成品\迷途之梦.pck。