针对Godot-GridGame(网格游戏)的DI注入+RefCounted数据驱动信号流架构设计的研究(全程开源)

前言

阅读本网站前请读者需了解 Godot 节点 / 信号 / 场景基本概念, 若是不太熟悉可以参考针对Godot(2D)游戏架构的研究_CSDN博客 ,文章中介绍了使用 Godot 的一些基本尝试,但是需要注意的是信号机制需要额外学习

在2026年4月6日的时候,我曾经发表过一篇CSDN博客研究 Godot 中设计游戏的架构(针对Godot(2D)游戏架构的研究_CSDN博客)这个老架构采用的是 Godot 全局单例驱动的游戏架构设计,针对这篇文章中架构设计的游戏组件还包括我后面的 全局存档系统 以及 AutoLoad网络管理中心实现​​​​​​ 等文章介绍的游戏组件。后来在设计游戏的过程中我发现全局单例过度使用 会使得游戏几乎完全无法扩展联机,同时游戏的世界,玩家等都高度依赖全局单例,而且单例程序的膨胀导致全局单例成为了上帝类,各个单例几乎完全分走了全部的游戏逻辑,当我尝试新增功能的时候发现由于单例的调用耦合使得这种尝试非常的困难。

后续我在设计网格生存游戏(类似Minecraft, terraria)这类游戏的时候,不再使用 Godot 全局单例,而是使用全局类(class_name)来分开构造各个游戏系统,比如世界逻辑,物品,瓦片,渲染,尝试使用这种方式来使得各个系统之间尽可能的分开来避免到处都是全局单例的情况。

本篇博客就是详细介绍新设计的针对Godot网格游戏的,使用 DI 注入 以及 RefCounted数据驱动 构造的网格游戏结构,由于本人在此之前设计过 Minecraft 的模组,所以本架构会比较偏向 Minecraft 类似的游戏设计架构。这篇文章将会作为架构总篇开头,主要介绍架构设计思想,具体子系统的设计将作为子博客分开介绍。

此外本框架选用 RefCounted + class_name 设计当作系统类,主要由于系统类在本框架作为逻辑层并不需要节点的实际创建,同时 class_name 还省去了导入场景的操作,RefCounted作为被继承的纯计数,逻辑类用起来干净简洁,比较适合当作脚本。

本框架的注册表结构采用 JSON,第一是因为写 Minecraft 模组的时候收到了 Minecraft 的 JSON 贴图以及合成表的启发,第二是 JSON 的数据看起来清晰,若是采用 .tres Godot的二进制数据则需要解析,调试较为麻烦,为了方便开发,先使用 JSON 数据作为注册表结构。

这篇游戏文章架构对应的游戏源码开源地址放在文章末尾,供读者随意取用。

1. 架构总览

先给出架构总设计图如下,方便后续读者理解游戏架构
BackpackTest・五层架构与联动链路

本架构当前有 5 层设计:数据层、逻辑层、实体/物品层、桥接层、UI层

架构中不使用 Godot 提供的全局单例加载,同时每层之间的设计尽可能的不引入其他层的类变量以及对应功能,层间调用只通过注入的参数和信号,不跨层持有引用,同时游戏的循环由主脚本(DI容器)分发给逻辑层等需要的层级

逻辑层对外只发信号 ,由 DI 绑定转发,数据层 / 实体层以引用注入,每层之间启动前互不认识,通过核心的主脚本 (DI 容器) 绑定对应各层之间的信号连接,转发数据。

主脚本( DI 容器 ) 是游戏启动的程序入口。DI 启动游戏的时候会创建除了 实体/物品层 之外的所有层级的数据类,同时 DI 会将各层级需要的初始化参数注入到对应的层级中(比如将 Godot 的 TileMapLayer 注入到渲染桥中)。

管理实体节点的层级(比如 UI 层,桥接层)由 DI 对数据进行转发,避免和数据层和逻辑层之间通讯

对于本架构的总启动顺序(简要图)

需要额外注意的是,本架构目前仍未实现: 存档(Chunk.is_dirty/ EntityStorage.next_uid 已埋点),

多人(on_player_removed 已定义未接线), 分层地形生成逻辑当前未完成,未来会在5个层级介绍文章完成后补全。

2. 各层级详细设计

对于下文的5个层级,简要流程为

  1. 数据层 JSON 注册表对应数据注入数据层的 ItemAttributes、ItemInstances 等物品,方块数据,TileSetBuilder 等类拿取数据,完成 Godot 图集映射后注入到 TileMapLayer 等,建立各个相关数据之间的映射表数据,为后续层级的功能使用提供支持

  2. 逻辑层 通过世界的初始数据(比如种子)使用 **TerrainGenerator (Simplex+FBM)**按需构建世界区块存入存储容器(按需懒加载 + 超距卸载),并启用实体管理器,掉落物管理器等逻辑管理器。

  3. 实体/物品层 将存在的实体从运行数据层(被逻辑层载入内存的那一部分,也就是逻辑层通过数据层创建的运行时数据)拿出,并构建游戏持有实体 Item 类等,并存入 BackPack (继承于InventoryBase) ,用作玩家真正操作的物品等一系列东西

  4. 桥接层 将玩家操作,游戏真正使用的 Item,TileCell 物品数据使用 DropBridge 等渲染出来,并通过 DI 同步回逻辑层(主要因为要使用Godot的物理引擎,数据层没法直接参与运算),逻辑层更新运行内存中的数据,地图也在这一步渲染

5 . Ui层 将对应 uid 的玩家的背包等数据通过 UiBridge 作为UI渲染在屏幕上,DI容器负责中转

以玩家挖掘一块 stone 为例:

1. InputController 发出 block_destroy_request

2. 逻辑层 World 修改区块数据并发 tile_cell_updated(渲染桥刷新这一格)

3. 同时 MappingTool 将方块实例的 drop_item 名字映射为 Item 模板

4. 掉落管理器生成掉落物数据,DropBridge 实例化掉落物视图(物理引擎驱动,位置经信号回传逻辑层)

5. 玩家走近拾取,物品进入背包

6. InventoryBase 发出 inventory_changed

7. 经 DI 中转

8. UiBridge 刷新对应格子。

下文的 5 个层级都将对应上面的各个层级的流程进行详细介绍,每个层级都将单独更新文章介绍,同时保持递进关系,后介绍的层级将默认读者已经阅读过前文层级设计。

1. 数据层

Godot-GridGame架构数据层篇-CSDN博客

2. 逻辑层

( 当前正在更新,未来将会更新文章 )

3. 实体/物品层

( 当前正在更新,未来将会更新文章 )

4. 桥接层

( 当前正在更新,未来将会更新文章 )

5. UI 层

( 当前正在更新,未来将会更新文章 )

3. 各层级联动设计

层级之间采用信号联动等方式,具体如何设计接口请参考更新的文章

( 当前正在更新,未来将会更新文章 )

4. 开源以及补充

本框架下的网格游戏添加一个物品,仅需往 itemsAttributes.json 以及 ItemInstances.json 中添加对应格式的数据,再在对应三个贴图文件夹下补充注册名字的贴图即可,瓦片方块同理。

本游戏架构程序开源地址:looooiiui/voxel-2d-game: 体素游戏开发,可以查看 (github.com)

相关推荐
坤坤子吖1 小时前
C++继承:友元、静态成员、多继承与组合
开发语言·c++·笔记·学习·1024程序员节
科学熊1 小时前
OBS Studio 新手入门
1024程序员节
贵州诚鑫致达科技有限公司1 小时前
PHP两个9.2分RCE漏洞,速查版本
服务器·php·1024程序员节
漫天转悠1 小时前
Vue3白屏排查实录-Transition与多根模板
vue.js·1024程序员节
不老刘1 小时前
异构双 Agent 协同:构建无人值守的长任务自动化研发流水线
运维·人工智能·自动化·ai编程·1024程序员节
lusklusklusk1 小时前
Python使用pymysql连接Mysql数据库操作笔记:连接、游标与 execute、executemany——含手动管理与 with 自动管理两种写法
1024程序员节
迷途呀1 小时前
强化学习概念
人工智能·深度学习·机器学习·强化学习·1024程序员节
技术小甜甜1 小时前
【Cursor】Skill 被标黄色警告,怎么改成合格的 SKILL.md
开发语言·javascript·ai编程·cursor·1024程序员节·ai agent·skills
syounger2 小时前
SAP季度营收首次突破100亿欧元:云增长强劲,AI贡献仍需进一步量化
1024程序员节