《魔法植物》开发手册(dev_manual)¶
本文件是 magic-plant-demo 的正式设计 + 开发手册,是开发过程中的唯一权威来源。 产品意图/卖点见 promote001.md;技术实现的"为什么"与"怎么做"以本文为准。
- 引擎:Godot 4.7.2 mono(GDScript 为主,mono 仅保留 C# 后备能力)
- 二进制:
D:\Program Files (x86)\Godot_v4.7.2-stable_mono_win64\Godot_v4.7.2-stable_mono_win64.exe - CLI/控制台版:
Godot_v4.7.2-stable_mono_win64_console.exe(headless / CI 用) - 工作目录:
d:\Repo\waste_aesthetic\magic-plant-demo - 当前里程碑:preview(一次性、可玩的移动端最小闭环)
- 建档日期:2026-09-02
0. 项目总览¶
扮演魔法少女,在魔法森林里种植魔法植物来获取能力 → 用合成道具解锁地图物理阻碍 → 探索/战斗带回更多材料 → 养成+得分。核心一句话:种田不是为了换钱,而是探索的钥匙。
0.1 版本规划¶
| 版本 | 目标 | 关键约束 |
|---|---|---|
| preview(当前) | 跑通 + 验证关键部分,能快速发布看玩家反应 | 性能 + 移动端兼容;一次性游戏、无存档;用色块/程序化占位,发布时补少量正式美术 |
| demo | 多平台免费发布 + 开启募资 + Steam 愿望单 | 需要美术完善、存档、关卡扩展 |
| 正式版 | Steam 发布 | 完整内容、皮肤解锁、经济/图鉴等长期留存 |
preview 的定义:一个完整跑通、能玩的移动端游戏,跑通「种→收→合成→开门→打怪→死一次→boss→得分」整条链,没有太多细节。验证点是这条链是否成立、好不好玩,而不是充实的打磨。
1. 核心体验与循环¶
1.1 核心循环(preview 闭环)¶
种作物(基地种植区)
│
▼ 睡觉推进天 / 作物生长
收获材料 ──► 背包(Inventpry)
│
▼ 合成(配方)
钥匙/装备/消耗品
│
▼ 开门(物理阻碍)解锁新区域
探索 + 打怪(掉落材料)
│
├─ 死亡 → 在死亡点掉落背包材料 → 回基地复活 → 可回原处捡尸
└─ 收集更多材料 ──► 更强配方 ──► BOSS ──► 解锁新地图(占位) ──► 得分结算
1.2 玩家驱动力¶
- 探索解锁:每种材料 → 新配方 → 新钥匙 → 新区域 → 更好的材料(metroidvania-lite 结构)。
- 成就/得分:没有金币,用得分系统充当"我在变强/在积累"的统一反馈(成就累计得分)。
- 战斗乐趣:靠怪物机制差异(不是数值碾压)带来变化。
- 皮肤解锁为长期留存,留到 demo/正式版,不进 preview。
1.3 关键设计取舍(已拍板)¶
- 种田不为换金币,产出的都是消耗品 + 合成材料,是探索的钥匙与补给。
- 战斗少数值、多机制,数值线性成长很无聊 → 核心是读怪物机制。
- 魔法类统一自动瞄准(桌/移两端一致,移动端友好,无需鼠标瞄准)。
- 能力由蘑菇驱动:开局仅 2 个基础攻击;治疗+4 buff 靠首次采集特定蘑菇解锁,并能用蘑菇升级(见 content_manual §2)——这是"种田=变强"的落点。
2. 核心系统设计¶
2.1 时间系统(连续时钟 / 昼夜双环境)¶
Autoload GameClock 是唯一时间源。
- 维护
day(第几天)与game_min(当日游戏内分时刻)。 - 一天 = 现实 24 分钟(
GameConfig.day_real_seconds,数值待后续优化)。时间连续流逝,形成 白天→黄昏→夜晚 的流动循环。 - 昼夜 = 两种外出冒险环境(重点,不止作物):白天与黑夜的敌怪种类、可得材料、可用事件不同(两套配置),玩家要"挑时段出门"。昼夜是环境/内容区分,不是时间压力——无行动点、无工作时段上限。
- 昼夜视觉:用
CanvasModulate(低成本)或随时刻变化的半透明覆盖层,随game_min过渡。 - 睡觉(跳过整天):在基地床点触发。效果:
- 时刻跳到次日清晨(默认 06:00),
day += 1; - -饱食度(固定/按天递减);
- +满蓝(蓝回满);
- +少量回血(红心小量回复)。
- 作物按"天"粗粒度成熟(见 2.3),成熟度随"过了几天"推进,而非逐分钟。
设计意图:24 分钟一天的连续时钟用于营造昼夜两套冒险环境的节奏;玩家可自由选白天/黑夜出门,也能睡觉跳过整天快速推进作物成熟。所有数值(一天时长、睡觉消耗、昼夜内容)集中在
GameConfig,后续统一微调。preview 不因连续时钟给玩家时间压迫。
2.2 资源系统(preview 三维:红心 / 蓝 / 饱食度)¶
已定稿:preview 用三维,无独立"精力"——精力并入蓝,或闪避改用纯冷却/少量蓝。
| 资源 | 作用 | 消耗/恢复 |
|---|---|---|
| 红心 HP | 生命值;归零 → 猫车(力竭/死亡) | 被怪物伤害扣;睡觉小量回;食物/消耗品可回 |
| 蓝色 MP | 施法 + 闪避耗能 | 施法/闪避扣;随时间缓慢回复 + 睡觉回满 |
| 饱食度 Satiety | 生存压力来源 | 随时间缓慢降;睡觉额外扣;吃作物/食物回 |
- 闪避:耗少量蓝,或纯冷却(数值待调)。
2.3 种植系统¶
- 基地种植区:靠近家的若干作物格。
- 作物 =
CropData资源,生长分阶段:种子 → 发芽 → 成熟 → 可收。 - 生长按"天"粗粒度成熟:作物纪录已过天数,每过一个游戏日成熟度 +1 阶段,而非逐分钟计(与连续时钟解耦,见 2.1)。
- 收获:成熟作物进背包,产出
ItemData。 - 消耗品定位:作物既是合成材料(开门/装备),也可直接食用(回饱食度/回血)——承接"作物是消耗品"的核心定位。
2.4 合成系统¶
- 合成台:基地炼药/合成台。
- 配方 =
RecipeData:inputs[] → outputs[](材料→钥匙/装备/消耗品)。 - 开门道具、装备、食物均走此表。种什么→出什么→开哪扇门 全数据驱动,不写死。
2.5 战斗系统¶
俯视角 2D 即时动作,难度简单,核心是读机制。
- 玩家操作:移动 / 攻击(
绽华近距AoE ·星刺远距,自动瞄准)/ 治疗 / buff / 闪避 / 交互 / (睡觉)。 - 自动瞄准:施法(及普攻)自动锁定最近敌人或朝移动方向——两端一致,移动端无瞄准压力。
- 敌怪机制优先:每个
MonsterData一种行为(巡逻/追击/前摇攻击/远程弹幕/冲撞),数值差异小,机制是主要差异来源。 - 伤害与击退:命中玩家扣红心,带击退 + 短暂无敌帧防止连续秒杀。
- 能力获取【定】:开局仅 2 个基础攻击(
绽华/星刺);治疗+4 buff 通过首次采集特定蘑菇解锁进魔法书;能力可用蘑菇升级(等级/每级加成/升级消耗,见 content_manual §2.3)。施法是战斗+种植的核心耦合。 - 施法耗能:
AbilityData定义耗蓝;能力等级/装备可降低施法耗能(对应"从作物获得能力后减少施法耗能")。
2.6 探索与开锁(gates)¶
- 单张封闭地图,基地居中、口袋外扩(hub-and-spoke),小而密,便于移动端与测试(详见 map_progress.md)。
- 地形高低 = 基础物理隔离层:高崖/溪谷把地图切成既定区域,让玩家沿既定路线与区域探索——它给整张图"划线路",不是一扇具体的门。
- 3 个交互门(preview):魔法门(合成魔钥)/ 水域(河侧放装置→投入道具→桥从水中升起)/ 黑暗(用灼心芝合成光明晶石,强绑昼夜)。每个门只能由门之前可达区域的材料合成(开锁无环,见 map_progress §2)。
- 白天/黑夜是同一张地图上的两套环境(不同怪物/材料/事件,见 2.1;昼夜双态 A4 甲)。
- 难度原则:少数值多机制、无等级数值墙(A2)——区域难度来自机制组合/密度 + 工具与视野门槛(黑暗降视野),而非数值上调。
- metroidvania-lite:门可设计成"兼具回程捷径",但不强求。
- BOSS 解锁新地图:preview 里 boss 击败后触发"新地图解锁"占位(锁/动画/结算),真正新地图留到 demo(地牢位置见 map_progress §1、§3)。
2.7 死亡与捡尸(A1:掉死亡点、可捡回)¶
- 红心归零 → 力竭/猫车:把背包中收集的材料(采集的植物 + 捡到的道具)掉落在死亡点的一个"遗物包"里。
- 装备不丢,等级/经验不掉(preview 无等级机制,故无此项损失)。
- 回基地复活后,可回死亡点捡回遗物包。
- 魂系规则:若在捡回前再次死亡,旧遗物包内容永久丢失(新遗物包覆盖/取代旧包)→ 制造"要不要冒险去捡"的策略张力。
- 不做死亡点标记/引路(已定)。因地图不大、死亡点距基地较近,跑尸成本可控,无需额外引导。
2.8 BOSS¶
- 末尾一个机制型 boss,作为闭环收尾。击败 → 结算得分 +「新地图解锁」占位。
- 封闭地牢:进入 boss 场后不能离开。
- 入场动画封门:boss 一发场,荆棘/结晶从四周隆起封死出口(视觉上是 boss 的"筑巢/结界"技能),由入场动画加载封门物理障碍。
- 多攻击模式 + 会躲避(复用 3 小怪机制混搭 + 一个签名技;具体机制/数值以 content_manual §3.2 为准)。
2.9 得分与成就(A10:无金币 + 得分系统)¶
- 无金币/交易。
ScoreManager:成就触发即累计得分,HUD / 结算页展示。- 示例成就:初次播种 / 第一次收获 / 开门 / 击败 boss / 猫车后归来(死后捡回遗物包)/ 夜行者(夜晚采到夜之蘑菇)…(用
AchievementData定义,score_value累加;完整名单见 content_manual §5)。 - 一次性游戏(无存档),得分每局重置——作为单局的"表现反馈"。
3. 内容清单(preview 占位,待定稿)¶
具体内容(名字/机制/数值)统一以 content_manual.md 为准;本表只列类别与规模。以下为跑通闭环所需的最小编号集,为【占位】,M3 后按实际填充。
| 类别 | preview 最小集(占位) | 内容框架位置 |
|---|---|---|
| 作物(统一为蘑菇) | 从 10 种中选子集(含至少 1 种食料 + 1 种能力解锁) | content §1.3 |
| 能力 | 2 基础攻击(开局)+ 1 治疗 + 4 buff | content §2.2 |
| 怪物 | 3 小怪(每种一个机制)+ 1 boss | content §3 |
| 配方 | 1 门钥匙 + 1 装备 + 1 装备升级 + 1 食物 | content §4 |
| 门/障碍 | 地形高低(隔离) + 3 交互门(魔钥/水域桥/光明晶石) | map_progress §2–3 |
| 成就 | 5–8 个得分成就 | content §5 |
| NPC | preview 暂不纳入 | — |
4. 数据模型(.tres 数据驱动)¶
一套 Resource 脚本 + 大量 .tres 数据文件。设计期在 Inspector 改数据、不改代码。
| 脚本(extends Resource) | 关键字段 |
|---|---|
CropData.gd |
id, name, stages[](各阶段名), growth_days[](各阶段所需天数,按天成熟), yields[](ItemData+数量), wild_spawn(野外可采/昼或夜), desc, texture |
ItemData.gd |
id, name, type(枚举: MATERIAL/CONSUMABLE/ABILITY/EQUIP/GATE_KEY), stack_max, icon, desc |
AbilityData.gd |
id, name, type, mana_cost, cooldown, effect(枚举: projectile/aoe/buff/heal), power(伤害/治疗量/buff强度), duration(buff时长), auto_target(true), grant_mushroom(首次采集解锁), level/max_level, effect_per_level(每级加成%), upgrade_cost(该蘑菇×n + 虹髓芝×m), texture |
MonsterData.gd |
id, name, hp, contact_damage, speed, behavior(枚举), drops[](ItemData+概率), texture |
RecipeData.gd |
id, name, inputs[](ItemData+数量), outputs[](ItemData+数量), station |
GateData.gd |
id, name, required_item(ItemData), region_tag, unlock_text, texture |
AchievementData.gd |
id, name, desc, score_value, predicate(触发类型), icon |
GameConfig.gd |
一天真实时长、睡觉消耗饱食度、初始 HP/MP/饱食度、作物生长速度系数等全局可调项 |
写代码红线(godot-master 输血):
- .tres 是唯一真相,运行时不改 .tres 文件;用前 duplicate() 或对动态实例开「Local to Scene」。
- 高频率查找用 StringName(&"key")做字典键,不用字符串。
- Resource 适合 ID/数值;逻辑包(如攻击请求、伤害包)用 RefCounted,真正需要进场景树才用 Node。
5. 架构与分层¶
分层铁律:信号向上、调用向下;Presentation 绝不直接改 Data。
PRESENTATION HUD / 背包 / 结算 / 提示 / 昼夜覆盖层 ← 只听信号
LOGIC 状态机(战斗)/种植/门/游戏流 ← 编排、查询数据
DATA .tres 资源(第 4 节)
INFRASTRUCTURE Autoload:GameClock · GameManager ·
PlayerState · Inventory · ScoreManager ·
InputManager · EventBus
5.1 Autoload 清单¶
| Autoload | 职责 | 关键信号 |
|---|---|---|
GameClock |
天数/时刻/昼夜 | minute_ticked, day_started, sleep_advanced |
GameManager |
游戏状态(INTRO/PLAY/DEAD/BOSS/END)、场景流、复活/捡尸编排 | state_changed, player_fainted, respawned |
PlayerState |
HP/MP/饱食度/已装备 | health_changed, mana_changed, satiety_changed |
Inventory |
背包增删、遗物包(损坏) | inventory_changed |
ScoreManager |
得分累计、成就判定 | score_changed, achievement_unlocked |
InputManager |
输入归一化(桌面/移动) | — |
EventBus |
全局信号(≤15 个)+ 一次性 toast 文案通道 | 把跨系统的关键事件 + toast(text) 集中 |
信号总线纪律:
EventBus只放全局生命周期事件(run_started / player_fainted / run_ended / settings_changed)+ 跨系统 UI 提示toast(text),数量 <15。系统内部通信走局部/父子信号,避免调试风暴。
5.2 实体组件化¶
- Player(
CharacterBody2D+ 组件):Health / Mana / Satiety / AbilitySystem / Inventory / Visual(换皮层)。 - 敌人:
CharacterBody2D+ 状态机(不同behavior)。所有实体过 F6 测试(单独运行该场景不崩,无场景外依赖)。 - 门:
Area2D/StaticBody,读GateData决定是否解锁。 - 手记:组件对父级只发信号、不直接调父方法。
6. 目录结构(按 Feature 分)¶
magic-plant-demo/
project.godot
autoload/
game_clock.gd game_manager.gd player_state.gd
inventory.gd score_manager.gd input_manager.gd event_bus.gd
features/
player/ player.tscn player.gd components/
farming/ crop.tscn crop.gd plot.tscn
combat/ monster.tscn ability.gd
exploration/ gate.tscn gate.gd level_map.tscn
progression/ crafting.tscn recipe_ui.gd magic_book.tscn magic_book.gd
death/ death_bag.tscn corpse_run.gd
score/ hud.tscn score.gd achievements.gd
resources/
crops/ items/ abilities/ monsters/ recipes/ gates/ achievements/
scenes/ levels/ ui/ tools/
doc/ promote.md dev_manual.md
7. 平台与渲染(preview 关键——移动端兼容)¶
7.1 渲染器:Compatibility(GLES3)¶
要桌面 + 移动同时,且是 2D 像素,必须用 Compatibility(全平台跑得动)。不用 Forward+(桌面专属、吃 GPU)。
7.2 像素管线¶
- 全纹理
texture_filter = NEAREST。 stretch mode = canvas_items+ 整数缩放(scale_mode = integer),aspect = keep。- 基分辨率压低(如
640×360放大到 32px 视感);Camera2D平滑 + 像素对齐(position_smoothing_enabled,必要时关闭平滑保像素锐利)。
7.3 输入抽象(desktop / mobile 一致)¶
InputManager 把所有动作归一化:move_* / attack / dodge / cast / interact / sleep / bag / back。
- 桌面:WASD/方向键 + 键盘(因自动瞄准,本作基本不需要鼠标瞄准)。
- 移动端:内置虚拟摇杆(4.7+)(左)+ 动作按钮(右,触摸目标 ≥44px)+ 安全区适配。
- 用
OS.has_feature("mobile")/ 自定义 feature tag 判端,不要用OS.get_name()。 - 桌面用一个「移动端测试模式」开关显示虚拟摇杆,方便桌面开发时验证移动手感。
7.4 换皮层(占位 → 少量正式美术)¶
- 每个实体的视觉是独立子节点(
Sprite2D/AnimatedSprite2D,或占位PlaceholderSprite,两者共用同一状态接口:idle/walk/attack/cast/hurt/dead)。 - preview 用程序化占位 + 色块跑通;发布补少量正式美术 = 纯换纹理资源,不碰玩法逻辑(避免重做上一项目那样要动代码的换皮)。
8. 性能预算(移动端)¶
| 指标 | 预算 | 备注 |
|---|---|---|
| Draw Calls | <100 | 合批;重复物用 MultiMeshInstance2D |
| Script Time | <4ms/帧 | 热路径不 load(),用 preload/ResourceLoader |
| 粒子 | <2000 | GPU 粒子,设 visibility_aabb |
| 着色器 | 简单 | 昼夜用 CanvasModulate(整个画布一次调色),不逐节点调 |
| 移动 | 无行动点压迫 | 昼夜是环境循环(24分钟/天),非紧张实时 |
不用 Forward+;不叠 SDFGI/VoxelGI(2D 游戏用
DirectionalLight2D/CanvasModulate就够)。
9. 开发调试与验证¶
9.1 无存档(一次性)¶
preview 不做 Save/Load,每局重开。遗物包、得分、已解锁门均单局内存态。存档留到 demo。
9.2 开发者调试(仅开发者可见)¶
- 快速成熟:调试键按下即让作物瞬间成熟——只在 debug 构建生效(用
OS.is_debug_build()或自定义 feature tag 门控),release 不可见。玩家侧没有此功能。 - 其他调试:跳天、开关门、回满资源、直接给材料、刷怪、快速到 boss 等,统一收在
tools/调试入口。
9.3 逻辑冒烟测试(headless)¶
tools/logic_test.gd(SceneTree 脚本)串起整条链做冒烟:
godot --headless --path <proj> --script res://tools/logic_test.gd
覆盖:种→收→合成→开门→打怪→死→捡尸→boss→得分,任一环节断言失败即退出非零。用 --headless + 显式 quit(),不要用 create_timer 驱动(不可靠)。
9.4 截图/录制(发布支撑,后期)¶
发布视频需要镜头素材,预留 tools/capture.gd(按事件/时间定格画面)。性能/headless 已确认:截图需窗口模式(headless 渲染不到纹理),帧取样用等时间或事件驱动。此部分面向发布管线,preview 后期再补。
10. 里程碑路线(preview 分阶段构建)¶
| 阶段 | 交付 | 验证点 |
|---|---|---|
| M1 | 工程 + Compatibility 渲染器 + 输入层 + 可移动的 Player + Camera2D + 占位地图 + 基地 | 桌面 F6 跑通,移动端虚拟摇杆可动 |
| M2 | GameClock(一天=24分钟可配)+ 昼夜双环境 + 睡觉跳天 + 三维资源(HUD) | 睡觉扣饱食度/回满蓝/小回血 |
| M3 | 种植:种植区 + 作物生长(GameClock 驱动) + 收获进背包 | 种→收闭环 |
| M4 | 合成:RecipeData + 开门配方 + 门解锁 | ✅ 合成台(炼金) + 3 配方(魔钥/桥钥/光明晶石) + 3 交互门(魔法门/水域装置/黑暗) |
| M5 | 战斗:自动瞄准 普攻/施法/闪避 + 1 种机制怪 + 掉落 | ✅ 绽华AoE/星刺弹道 自动瞄准 + 闪避 + 3 机制怪(夜行兽冲撞/孢子巫弹幕/腐根虫毒沼) + chance 掉落拾取 |
| M6 | 死亡 + 捡尸:死亡点遗物包 + 复活 + 回捡 | ✅ 掉包→清背包→基地复活→走回按 F 拾回;再死旧包丢失 |
| M7 | Boss + 结算 + 得分/成就 | boss→得分 |
| M8 | 移动端打磨:虚拟摇杆/触摸/安全区/性能 + 占位→少量正式美术 + 一键可跑 | 移动端可玩、可发布 |
M8 完成即 preview 达成「完整跑通、可玩、移动端、少量正式美术」。
11. 风险与待定项¶
| 项 | 现状/风险 | 建议 |
|---|---|---|
| 一天=24分钟 | 数值为起点,需实测优化 | 集中到 GameConfig.day_real_seconds,发布前微调 |
| 内容清单(植物等) | A9 未定稿 | 留占位集,M3 后按实际填充 |
| 作物按天成熟 | 一天 1 阶段;一天=24分钟 | 调 GameConfig 天长 + 作物"所需天数",让节奏适合一次性体验 |
| 跑尸 | 无标记/引路 | 地图紧凑、死亡点近 → 成本可控;若后期嫌远再加标记 |
| 美术投入 | preview 需"少量正式美术" | 只挑关键物(玩家/1-2作物/1怪/HUD/门)上真美术,其余程序化 |
12. 附录:常用命令¶
# 运行(窗口)
"D:/Program Files (x86)/Godot_v4.7.2-stable_mono_win64/Godot_v4.7.2-stable_mono_win64.exe" --path .
# 导入/重建类缓存(新增 class_name 后必需)
"..."_console.exe --headless --path . --import
# headless 冒烟测试
"..."_console.exe --headless --path . --script res://tools/logic_test.gd
说明:mono 版含
_console.exe(stdout 可捕获),CLI/headless 一律用 console 版;跑游戏用 GUI 版。