关于VoidNovelEngine的能力边界和架构综述
Lkcuy
2026年05月07日 02:27

出于种种原因得稍微魔改下这个引擎,所以有了这篇文章[热词表情_世萌双冠]

部分内容由codex与deepseek生成

所有内容均基于0.1.0-dev.2版本


当前版本能力边界:

完全零代码可实现的类型:

线性视觉小说

多分支 Galgame

带少量 Flag 判断的剧情游戏

具备章节选择、路线选择、CG 式立绘演出、BGM / 视频 / 字幕 / 对话框的作品

当前版本尚不支持的能力:

没有真正的通用运行时 UI 框架

没有可用的 UI 设计器

没有库存、任务、地图、日志、装备、商店等系统的标准节点

输入基本仍为硬编码交互,缺少统一输入映射

没有成熟的存档菜单 / 读档菜单 / 设置菜单等完整产品化 UI 流程


运行链路串讲

main.cpp 创建 Lua 虚拟机,执行 RaycastEngine/main.lua。

RaycastEngine/main.lua 进入 RaycastEngine/application/application.lua。

RaycastEngine/application/application.lua:136 加载项目设置、资源和流程图。

发布模式下,将主场景设为 RaycastEngine/application/scene/scene_released.lua。

RaycastEngine/application/scene/scene_released.lua:7 根据 project.vne 中的 entry_flow 找到入口流程并开始执行。

每帧在 RaycastEngine/application/scene/scene_released.lua:25 处:

推进流程节点;

更新当前的 scene_context;

渲染当前的 scene_context。

scene_context 是一个 Scene 对象,内部挂载了背景、字幕、按钮等所有运行时对象。


架构综述

该引擎本质上是 “C++ 宿主 + Lua 应用层 + 流程图数据驱动” 的结构。C++ 层仅负责启动 Lua 虚拟机并注册底层能力,入口非常薄(见 RaycastEngine/main.cpp 与 RaycastEngine/module.cpp)。当前暴露给 Lua 的核心能力主要包括 SDL、Raylib、ImGUI、JSON、Util、MicroPather。

真正的应用逻辑基本全部位于 Lua 侧。启动后依次加载设置、资源和流程图,并根据是否为发布模式切换到编辑器场景或运行场景,主循环在 RaycastEngine/application/application.lua:136 处。

发布态使用 RaycastEngine/application/scene/scene_released.lua:25,每帧完成三件事:推进流程节点、更新当前运行场景、渲染当前运行场景。

流程图并非导出为另一套脚本语言,而是在运行期直接加载 .flow / .bp 文件,并组装成 Blueprint 对象。Blueprint 内部维护 node / pin / link pool,运行时根据连线推进 _next_node → _current_node。相关逻辑详见 RaycastEngine/application/framework/blueprint.lua 与 RaycastEngine/application/scene/scene_released.lua:25。流程图本身只是将已有节点串联起来,节点能力的上限由 node_factory.lua 决定。

每帧的具体逻辑为:

若存在 _next_node,先切换至下一节点并执行;

更新当前蓝图的 _scene_context;

调用当前节点的 on_exetute_update。

进一步分层如下:

节点定义层:NodeDef

节点实例化与执行层:NodeFactory

场景承载层:Scene

运行对象层:GameObject

运行对象层虽简单却极为关键。RaycastEngine/application/framework/scene.lua:39 显示场景本质上是一个 GameObject 容器,仅提供以下能力:

add_object

del_object

find_object

on_update

on_render

场景会按照 z_idx 排序,并逐个调用对象的 on_update / on_render。当前引擎内置的“背景图、前景图、字幕、对话框、转场、分支按钮、Tween、Timer、视频播放”等,实际上都是由节点在运行时动态创建的 GameObject。

每个对象均基于 RaycastEngine/application/framework/game_object.lua 定义的轻量结构,仅包含:

_id

_z_idx

_valid

on_update

on_render

因此,引擎当前的运行时 UI、背景、字幕、对话框、转场等,本质上都只是“往 Scene 里挂载了若干 GameObject”。

运行时内容层采用清晰的 Scene + GameObject 模型。节点执行时会向当前场景添加各类对象,例如背景、前景、字幕、对话框、分支按钮、转场遮罩、Timer、Tween 等。已有的节点已覆盖叙事型视觉小说的主要演出组件,包括但不限于:

背景切换、前景增删改、字幕、对话框、分支按钮

音频播放 / 停止、视频播放

延时、等待交互、分支、循环、场景切换

全局上下文存取(save_global / load_global)

自定义 Lua 场景切换(switch_to_game_scene)


关于定义Lua场景节点:

自定义场景节点在蓝图流程中充当一个可暂停的场景段,但它本身并不是蓝图节点。真正的节点是 switch_to_game_scene。该节点会临时创建并接管一个 Scene 对象,然后向该场景对象注入一个“继续执行蓝图”的回调,从而让场景能够在恰当的时机恢复蓝图运行。