vaststars科技树实现解析:techtree与laboratory研究队列系统全攻略
【免费下载链接】vaststarsA game demo for Ant engine项目地址: https://gitcode.com/gh_mirrors/va/vaststars
vaststars 是一款基于 Ant 引擎的火星工厂模拟游戏,其科技树系统(techtree)与实验室(laboratory)研究队列是游戏成长线的核心。本文带你从 C++ 内核到 Lua 表现层,完整拆解这套"数据驱动 + 状态机"的科研系统是如何实现的,帮助新手理解游戏科技树设计的通用思路。
整体架构:三层分工各司其职 🏗️
科技树系统横跨项目的三层代码,职责清晰:
| 层级 | 位置 | 职责 |
|---|---|---|
| C++ 内核 | clibs/gameplay/src/core/techtree.cpp | 进度存储、队列管理、材料匹配 |
| 实验室逻辑 | clibs/gameplay/src/system/laboratory.cpp | 研究状态机、每帧推进 |
| Lua 表现层 | startup/pkg/vaststars.gamerender/ | 科技列表过滤、UI 数据模型、3D 渲染 |
C++ 层负责"算得快",Lua 层负责"配得灵活"——所有科技节点、前置条件、解锁效果都写在 Lua 原型文件里,无需重新编译 C++ 即可调整玩法。
techtree_mgr:四个核心数据结构
打开clibs/gameplay/src/core/techtree.h,整个科技树管理器只有四个成员,麻雀虽小五脏俱全:
progress:techid → 当前进度的映射,记录每项科技研究到哪一步researched:已完成科技的集合,UI 层的"待研究/已研究"分类全靠它queue:研究队列,玩家点"开始研究"时科技 ID 入队cache:材料匹配缓存,避免每个实验室每帧重复计算配方
两个细节值得关注:
research_add的完成判定(techtree.cpp第 43 行):每次实验室交付一批材料,进度 +1;当进度达到原型的count值时,科技自动进入researched集合,同时清掉缓存——因为研究完成后该科技不再需要材料匹配。- 队列是"后进先出":
queue_top()取的是queue.back(),玩家最新选定的科技会立即抢占实验室,符合"随时改研究方向"的操作直觉。
研究队列如何驱动全部实验室 🔄
队列与实验室的联动逻辑在laboratory.cpp的lupdate函数中:
- 每帧取出队列头部科技(
queue_top()); - 若某台实验室当前研究的科技 ≠ 队列头部,调用
laboratory_next_tech切换目标; - 切换时,旧科技已收取但没研究完的材料会退还箱内,保证玩家随时改方向不亏材料;
- 一旦某台实验室完成一项科技(
research_add返回完成),弹出队列尾部,并广播通知所有实验室切换下一项。
这套机制意味着:全局只有一条研究流水线,多台实验室可以并行消耗材料、分摊研究时间——和《异星工厂》的科研站设计如出一辙。
实验室状态机:三态流转详解 🔬
laboratory.cpp用三个状态驱动整个研究流程:
IDLE ──收取材料成功──▶ DONE ──进度交付完成──▶ 切换/下一批 ▲ │ └──材料不足/无电──────────┘ (科技材料无法匹配时进入 INVALID 挂起)- IDLE(等料):从箱子
chest::pickup收取该科技要求的材料;收齐则进入 DONE,否则原地等待物流送料 - DONE(倒计时):
progress按每秒 100 计初始化,每帧progress -= l.speed(实验室速度),归零后把 1 点研究进度交付给全局 techtree - INVALID(不可研究):由
get_ingredients判定——它拿实验室的输入槽位类型(inputs)与科技所需材料列表(ingredients)做匹配,若实验室收不了科技要求的某类材料,直接判无效
get_ingredients是理解"实验室为什么不能研究某科技"的关键:它按实验室槽位顺序生成实际收取配方并缓存到cache,槽位数量与科技材料种类必须一一对应。
数据驱动的科技原型配置 📋
所有科技节点定义在startup/pkg/vaststars.prototype/tech/tech1.lua~tech5.lua,按章节拆分。每个科技原型包含:
prerequisites:前置科技,形成树状依赖count/time:总进度需求与每点进度耗时ingredients:研究材料effects.unlock_recipe:研究完成后解锁的配方列表
列表过滤逻辑在startup/pkg/vaststars.gamerender/gameplay/interface/science.lua的update_tech_list:遍历整棵tech_tree,已研究的归入finish_list,前置全部满足的归入tech_list,其余对玩家隐藏。这样玩家在任何时刻看到的,都是"当前可研究"的精确集合,科技树 UI 无需自行判断依赖关系。
UI 层:从面板到 3D 货架 🖥️
- 科研面板数据模型:
startup/pkg/vaststars.gamerender/ui_datamodel/science.lua组装每个科技的名称、材料图标、进度条、"开始研究/暂停"按钮状态,并通过research_queue {name}或research_queue {}控制研究启停 - 实验室货架渲染:
startup/pkg/vaststars.gamerender/render_updates/laboratory.lua在实验室模型上挂载 6 个货架挂点(slot1~slot6),按箱内物品动态生成/销毁 3D 物品模型,玩家一眼就能看出每台实验室在"吃什么"
总结:可以复用的设计要点 ✅
- C++ 管状态,Lua 管配置——科技树数据热更无需重编译
- 全局单队列 + 多实验室并行——简单的队列即可实现灵活的科研调度
- 三态状态机 + 材料退还——方向随时可改,玩家零损失
- 槽位-材料匹配缓存——把"能不能研究"的计算从每帧降到一次
如果你想动手研究源码,建议按techtree.h→laboratory.cpp→science.lua的顺序阅读,从数据结构到状态机再到表现层,一天即可吃透整个系统。
【免费下载链接】vaststarsA game demo for Ant engine项目地址: https://gitcode.com/gh_mirrors/va/vaststars
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考