mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-05-07 00:39:00 +08:00
docs(source-generators): 收口 AutoRegister 文档语义
- 更新 auto-register-exported-collections 专题页,补齐 frontmatter 并按当前源码与测试收口成员形状、匹配规则、null-skip 行为与诊断边界 - 补充 documentation-governance-and-refresh 的 RP-012 恢复点,记录 godot-integration tutorial 仍残留旧 API 的跟进风险
This commit is contained in:
parent
214f52b6c2
commit
aec1931c74
@ -7,13 +7,13 @@
|
||||
|
||||
## 当前恢复点
|
||||
|
||||
- 恢复点编号:`DOCUMENTATION-GOVERNANCE-REFRESH-RP-011`
|
||||
- 恢复点编号:`DOCUMENTATION-GOVERNANCE-REFRESH-RP-012`
|
||||
- 当前阶段:`Phase 3`
|
||||
- 当前焦点:
|
||||
- 已建立统一公开 skill:`.agents/skills/gframework-doc-refresh/`
|
||||
- 文档重构入口已从“按 guide/tutorial/api 类型拆 skill”收口为“按源码模块驱动文档刷新”
|
||||
- PR #268 的当前未解决 review 线程已进入收口:Scene/UI 标题层级修正、共享脚本 review 修复、`gframework-pr-review` 多 AI reviewer 支持补齐
|
||||
- `Godot.SourceGenerators` 的 3 个高风险专题页已按当前实现重写,下一轮转入剩余生成器页与 PR thread 收口
|
||||
- `Godot.SourceGenerators` 的 4 个高风险专题页已按当前实现重写,下一轮转入 tutorial 收口与 PR thread 收口
|
||||
|
||||
## 当前状态摘要
|
||||
|
||||
@ -63,6 +63,8 @@
|
||||
明确只有缺少 `_Ready()` 时才会生成 `OnGetNodeReadyGenerated()`
|
||||
- `docs/zh-CN/source-generators/bind-node-signal-generator.md` 已改成“CLR event 绑定职责、生命周期接线要求、与 `[GetNode]` 的调用顺序、签名约束与命名冲突”的结构,
|
||||
明确当前不会自动生成 `_Ready()` / `_ExitTree()`
|
||||
- `docs/zh-CN/source-generators/auto-register-exported-collections-generator.md` 已补齐 frontmatter,并改成“成员形状、registry 匹配规则、null-skip 行为、编译期诊断与 CoreGrid 真实采用路径”的结构,
|
||||
明确生成器依赖的是实例可读集合成员与可读 registry 成员,不要求成员必须带 `[Export]`
|
||||
- `.agents/skills/gframework-doc-refresh/SKILL.md` 已改成标准 YAML frontmatter skill,并明确支持模块输入、证据顺序、输出优先级与验证步骤
|
||||
- `.agents/skills/gframework-doc-refresh/SKILL.md` 的 `description` 已加引号,修复 `Recommended command:` 中冒号导致的
|
||||
invalid YAML skill 加载警告
|
||||
@ -80,8 +82,12 @@
|
||||
|
||||
- 旧专题页示例失真风险:`docs/zh-CN/game/*` 与 `source-generators/*` 中仍可能保留看似合理但与真实实现不一致的示例
|
||||
- 缓解措施:`game/scene.md`、`ui.md`、`source-generators/context-aware-generator.md` 与 `priority-generator.md` 已完成收口;
|
||||
`godot-project-generator.md`、`get-node-generator.md` 与 `bind-node-signal-generator.md` 已完成收口;
|
||||
`godot-project-generator.md`、`get-node-generator.md`、`bind-node-signal-generator.md` 与 `auto-register-exported-collections-generator.md`
|
||||
已完成收口;
|
||||
继续按源码、测试、`*.csproj` 与 `ai-libs/` 下已验证参考实现核对剩余 Godot 相关页面,不把旧文档当事实来源
|
||||
- 教程失真回流风险:`docs/zh-CN/tutorials/godot-integration.md` 仍保留旧 API 与旧模块叙述,可能把已清理掉的旧说法重新带回专题页
|
||||
- 缓解措施:本轮已确认 `GetNodeX`、`AbstractGodotModule`、`InstallGodotModule` 与 `GFramework.Godot.Pool` 等旧引用仍存在;
|
||||
下一轮优先按当前 `GFramework.Godot` / `Godot.SourceGenerators` 实现重写或拆分该教程
|
||||
- 采用路径误导风险:根聚合包与模块边界若再次被写错,会继续误导消费者的包选择
|
||||
- 缓解措施:保持“源码与包关系优先”的证据顺序,改动采用说明时同步核对包依赖与生成器 wiring
|
||||
- 模块映射不全风险:统一 skill 若遗漏模块别名、测试项目或 docs 栏目映射,会让后续扫描阶段直接失焦
|
||||
@ -125,10 +131,11 @@
|
||||
- `bash .agents/skills/gframework-doc-refresh/scripts/validate-all.sh docs/zh-CN/source-generators/godot-project-generator.md`
|
||||
- `bash .agents/skills/gframework-doc-refresh/scripts/validate-all.sh docs/zh-CN/source-generators/get-node-generator.md`
|
||||
- `bash .agents/skills/gframework-doc-refresh/scripts/validate-all.sh docs/zh-CN/source-generators/bind-node-signal-generator.md`
|
||||
- `bash .agents/skills/gframework-doc-refresh/scripts/validate-all.sh docs/zh-CN/source-generators/auto-register-exported-collections-generator.md`
|
||||
- `cd docs && bun run build`
|
||||
|
||||
## 下一步
|
||||
|
||||
1. 继续核对 `auto-register-exported-collections-generator.md`,确认其示例、诊断与 `Godot.SourceGenerators` 当前实现一致
|
||||
1. 优先重写或拆分 `docs/zh-CN/tutorials/godot-integration.md`,先移除 `GetNodeX`、`AbstractGodotModule`、`InstallGodotModule` 等旧 API 叙述
|
||||
2. 下一次推送后先重新执行 `$gframework-pr-review`,确认 PR #268 的 CodeRabbit / Greptile open thread 是否按预期收敛
|
||||
3. 继续复核 `docs/zh-CN/tutorials/godot-integration.md`,避免旧教程重新把过时 Godot 说明带回专题页
|
||||
3. 若 tutorial 收口后 active 内容再次变长,把本阶段已完成的 Godot 生成器专题历史迁入 topic `archive/`
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
## 2026-04-22
|
||||
|
||||
### 当前恢复点:RP-011
|
||||
### 当前恢复点:RP-012
|
||||
|
||||
- 本轮从 PR #268 的最新 review 数据恢复,未发现失败检查;CTRF 报告显示 2139 个测试全部通过
|
||||
- 本轮复核确认当前 PR 的 latest-head open thread 同时来自 `coderabbitai[bot]` 与 `greptile-apps[bot]`
|
||||
@ -22,6 +22,9 @@
|
||||
- `bind-node-signal-generator.md`
|
||||
- 新页面统一收口到“包关系、最小接入路径、真实生成语义、生命周期边界、诊断约束”,不再沿用旧教程式长篇 API 罗列
|
||||
- 本轮额外复核了 `ai-libs/CoreGrid` 的真实采用方式,确认 `[GetNode]` / `[BindNodeSignal]` 组合使用时应先注入节点再绑定事件
|
||||
- 本轮继续收口 `auto-register-exported-collections-generator.md`,补齐 frontmatter,并把“导出集合”纠正为“实例可读集合成员 + registry 成员 + 单参数实例方法”的真实契约
|
||||
- 本轮复核 `docs/zh-CN/tutorials/godot-integration.md`,确认其中仍残留 `GetNodeX`、`AbstractGodotModule`、`InstallGodotModule`、
|
||||
`GFramework.Godot.Pool` 等旧 API / 旧模块叙述,tutorial 已成为下一轮高优先级清理对象
|
||||
|
||||
### 当前决策
|
||||
|
||||
@ -31,6 +34,8 @@
|
||||
声明与实际抓取能力再次漂移
|
||||
- `Godot.SourceGenerators` 专题页继续采用“源码 / 测试 / README 优先,`ai-libs/` 只补消费者 wiring”的证据顺序
|
||||
- `BindNodeSignal` 页面明确记录“当前不自动生成 `_Ready()` / `_ExitTree()`”,避免继续把它写成自动生命周期织入器
|
||||
- `auto-register-exported-collections` 页面明确区分“运行时 null 时跳过注册”和“配置错误时编译期报错”,避免旧文档把两类边界混为一谈
|
||||
- `godot-integration.md` 不再适合作为当前 Godot 采用路径的事实来源;后续只能把它当待修输出,而不是事实输入
|
||||
|
||||
### 验证
|
||||
|
||||
@ -44,10 +49,12 @@
|
||||
- `bash .agents/skills/gframework-doc-refresh/scripts/validate-all.sh docs/zh-CN/source-generators/godot-project-generator.md`
|
||||
- `bash .agents/skills/gframework-doc-refresh/scripts/validate-all.sh docs/zh-CN/source-generators/get-node-generator.md`
|
||||
- `bash .agents/skills/gframework-doc-refresh/scripts/validate-all.sh docs/zh-CN/source-generators/bind-node-signal-generator.md`
|
||||
- `bash .agents/skills/gframework-doc-refresh/scripts/validate-all.sh docs/zh-CN/source-generators/auto-register-exported-collections-generator.md`
|
||||
- `cd docs && bun run build`
|
||||
- `rg -n "GetNodeX|AbstractGodotModule|InstallGodotModule|GodotGameArchitecture|GFramework\\.Godot\\.Pool" docs/zh-CN/tutorials/godot-integration.md`
|
||||
|
||||
### 下一步
|
||||
|
||||
1. 下一次推送后重新执行 `$gframework-pr-review`,确认 PR #268 的 CodeRabbit / Greptile open thread 是否关闭或减少
|
||||
2. 继续使用 `gframework-doc-refresh` 对 `Godot.SourceGenerators` 做真实模块扫描
|
||||
3. 优先刷新 `auto-register-exported-collections-generator.md`,并复核 `tutorials/godot-integration.md` 是否仍残留旧叙述
|
||||
3. 优先重写或拆分 `tutorials/godot-integration.md`,先清掉已确认失真的 Godot 旧 API 与旧模块示例
|
||||
|
||||
@ -1,21 +1,26 @@
|
||||
---
|
||||
title: AutoRegisterExportedCollections 生成器
|
||||
description: 说明批量注册生成器当前会生成什么、可匹配哪些集合与注册器成员,以及 null-skip 与编译期诊断的边界。
|
||||
---
|
||||
|
||||
# AutoRegisterExportedCollections 生成器
|
||||
|
||||
> 为 Godot 导出集合生成批量注册方法,收敛启动入口里的重复 `foreach + Registry(...)` 样板。
|
||||
`[AutoRegisterExportedCollections]` 用来把“遍历一组配置并逐项调用 registry 方法”的启动样板收敛成一个生成方法。
|
||||
|
||||
## 概述
|
||||
它最常见的落点确实是 Godot Inspector 导出的数组,但当前生成器真正依赖的不是 `[Export]` 本身,而是:
|
||||
|
||||
在游戏启动入口中,常见的一类样板是:
|
||||
- 宿主类型被标记了 `[AutoRegisterExportedCollections]`
|
||||
- 某个实例字段或可读实例属性被标记了 `[RegisterExportedCollection(...)]`
|
||||
- 该成员可枚举,且元素类型可在编译期推导
|
||||
- 目标 registry 成员存在,并能找到兼容的单参数实例方法
|
||||
|
||||
- 在 Inspector 中导出一批配置、资源映射或预制体条目
|
||||
- 从某个 Registry 成员拿到注册器
|
||||
- 遍历集合逐项调用 `Register(...)` / `Registry(...)`
|
||||
## 当前包关系
|
||||
|
||||
`AutoRegisterExportedCollections` 会把这类样板收敛成声明式配置。
|
||||
- 特性来源:`GFramework.Godot.SourceGenerators.Abstractions.UI`
|
||||
- 生成器实现:`GFramework.Godot.SourceGenerators`
|
||||
- 典型消费者:Godot 启动入口、资源入口节点、配置引导节点
|
||||
|
||||
它特别适合 `GameEntryPoint`、资源根节点、配置引导节点这类“导出即注册”的场景。
|
||||
相关特性当前位于 `GFramework.Godot.SourceGenerators.Abstractions.UI` 命名空间。
|
||||
|
||||
## 基础使用
|
||||
## 最小用法
|
||||
|
||||
```csharp
|
||||
using System.Collections.Generic;
|
||||
@ -39,13 +44,6 @@ public sealed class TextureConfig : Resource, IKeyValue<string, Texture2D>
|
||||
{
|
||||
}
|
||||
|
||||
public sealed class TextureRegistry : IAssetRegistry<Texture2D>
|
||||
{
|
||||
public void Registry(IKeyValue<string, Texture2D> mapping)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[AutoRegisterExportedCollections]
|
||||
public partial class GameEntryPoint : Node
|
||||
{
|
||||
@ -57,119 +55,169 @@ public partial class GameEntryPoint : Node
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_textureRegistry ??= new TextureRegistry();
|
||||
_textureRegistry ??= ResolveTextureRegistry();
|
||||
__RegisterExportedCollections_Generated();
|
||||
}
|
||||
|
||||
private static IAssetRegistry<Texture2D> ResolveTextureRegistry()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
为了让示例具备完整的调用路径,这里在 `_Ready()` 里先初始化了 `_textureRegistry`。
|
||||
实际项目里,这个字段通常来自架构容器、服务定位或外部注入;关键点是调用 `__RegisterExportedCollections_Generated()`
|
||||
之前,注册器成员必须已经可用,否则生成代码会按设计静默跳过注册。
|
||||
当前生成器不会自动调用 `__RegisterExportedCollections_Generated()`。你需要在 registry 成员和集合成员都准备好之后手动调用。
|
||||
|
||||
## 生成的代码
|
||||
## 当前会生成什么
|
||||
|
||||
对于上面的成员,当前生成器会产出:
|
||||
|
||||
```csharp
|
||||
// <auto-generated />
|
||||
#nullable enable
|
||||
|
||||
partial class GameEntryPoint
|
||||
private void __RegisterExportedCollections_Generated()
|
||||
{
|
||||
private void __RegisterExportedCollections_Generated()
|
||||
if (this._textureConfigs is not null && this._textureRegistry is not null)
|
||||
{
|
||||
if (this._textureConfigs is not null && this._textureRegistry is not null)
|
||||
foreach (var __generatedItem in this._textureConfigs)
|
||||
{
|
||||
foreach (var __generatedItem in this._textureConfigs)
|
||||
{
|
||||
this._textureRegistry.Registry(__generatedItem);
|
||||
}
|
||||
this._textureRegistry.Registry(__generatedItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 参数说明
|
||||
最重要的运行时语义只有两条:
|
||||
|
||||
### `[AutoRegisterExportedCollections]`
|
||||
- 集合成员为 `null` 时,本次注册直接跳过
|
||||
- registry 成员为 `null` 时,本次注册直接跳过
|
||||
|
||||
类级标记,声明该类型允许生成 `__RegisterExportedCollections_Generated()`。
|
||||
这里的“跳过”只针对运行时 `null` 情况;配置错误、方法不匹配、元素类型无法推导等问题都会在编译期直接给出诊断,而不是静默吞掉。
|
||||
|
||||
### `[RegisterExportedCollection(registryMemberName, registerMethodName)]`
|
||||
## 当前支持的成员形状
|
||||
|
||||
| 参数 | 类型 | 说明 |
|
||||
|----------------------|----------|----------------------------------|
|
||||
| `registryMemberName` | `string` | 当前类型上用于执行注册的字段或属性名 |
|
||||
| `registerMethodName` | `string` | 注册方法名,例如 `Register` 或 `Registry` |
|
||||
### 集合成员
|
||||
|
||||
推荐优先使用 `nameof(...)` 表达式,而不是手写字符串。
|
||||
`[RegisterExportedCollection]` 可以标在:
|
||||
|
||||
## 支持的匹配规则
|
||||
- 实例字段
|
||||
- 可读、非索引器的实例属性
|
||||
|
||||
生成器会在编译期验证:
|
||||
它们不必一定带 `[Export]`,但在 Godot 项目里通常会配合 `[Export]` 使用。
|
||||
|
||||
- 集合成员必须是实例字段,或可读的实例属性
|
||||
- 集合类型必须可枚举
|
||||
- 集合元素类型必须能在编译期推导
|
||||
- 注册器成员必须是实例字段,或可读的实例属性
|
||||
- 注册方法必须是单参数实例方法,且参数类型能接收集合元素类型
|
||||
### registry 成员
|
||||
|
||||
当前版本还支持从以下位置解析注册方法:
|
||||
`registryMemberName` 指向的目标也必须是:
|
||||
|
||||
- 注册器具体类型本身
|
||||
- 注册器基类
|
||||
- 注册器实现的接口
|
||||
- 实例字段,或
|
||||
- 可读、非索引器的实例属性
|
||||
|
||||
静态字段、静态属性、只写属性都不受支持。
|
||||
|
||||
## 当前匹配规则
|
||||
|
||||
### 可枚举集合
|
||||
|
||||
集合成员必须实现 `System.Collections.IEnumerable`,并且生成器还要能推导出元素类型。
|
||||
|
||||
因此:
|
||||
|
||||
- `List<int>`、`Godot.Collections.Array<TextureConfig>` 这类泛型集合可以
|
||||
- 非泛型 `IEnumerable` / `ArrayList` 这类只能枚举 `object` 的集合不可以
|
||||
|
||||
### 注册方法
|
||||
|
||||
当前会查找名称匹配、且满足以下条件的方法:
|
||||
|
||||
- 实例方法
|
||||
- 只有一个参数
|
||||
- 对宿主类型可访问
|
||||
- 参数类型能接收集合元素类型
|
||||
|
||||
查找范围不只限于 registry 具体类型本身,还包括:
|
||||
|
||||
- 基类
|
||||
- 直接实现的接口
|
||||
- 继承链上的接口
|
||||
|
||||
这意味着像 `IAssetRegistry<T>` 继承 `IRegistry<TKey, TValue>` 的项目结构也能正常生成,不必再把注册器字段改成具体实现类型。
|
||||
所以像下面这种接口继承链是受支持的:
|
||||
|
||||
## 适用场景
|
||||
```csharp
|
||||
[RegisterExportedCollection(nameof(_registry), "Registry")]
|
||||
public List<IntConfig>? Values { get; } = new();
|
||||
```
|
||||
|
||||
推荐用于:
|
||||
只要 `_registry` 的接口链上能找到兼容的 `Registry(...)` 即可。
|
||||
|
||||
- `GameEntryPoint` 中的资源注册
|
||||
- 场景启动时的配置条目注册
|
||||
- Inspector 预配置的纹理、音频、Prefab、场景映射批量接入
|
||||
### 明确不支持的情况
|
||||
|
||||
不推荐用于:
|
||||
当前测试明确覆盖了这些边界:
|
||||
|
||||
- 注册前需要复杂过滤、去重、排序、条件判断的集合
|
||||
- 需要记录失败项、错误聚合或回滚逻辑的批量导入
|
||||
- 每个元素注册时都依赖额外上下文或副作用控制的流程
|
||||
- 只显式实现接口方法,未在具体类型上暴露可访问成员
|
||||
- 注册方法存在,但对宿主类型不可访问
|
||||
- 集合元素类型无法推导
|
||||
- registry 成员不存在
|
||||
- 注册方法名存在但签名不兼容
|
||||
|
||||
这些情况都会直接触发编译期诊断。
|
||||
|
||||
## 真实采用路径
|
||||
|
||||
`ai-libs/CoreGrid/global/GameEntryPoint.cs` 是当前最直接的消费者参考:
|
||||
|
||||
- `UiPageConfigs`
|
||||
- `GameSceneConfigs`
|
||||
- `PrefabSceneConfigs`
|
||||
- `TextureConfigs`
|
||||
|
||||
这几个 `Array<T>` 成员都通过 `[RegisterExportedCollection(...)]` 声明 registry 目标,并在 `_Ready()` 里调用
|
||||
`__RegisterExportedCollections_Generated()`。
|
||||
|
||||
这个例子说明两件事:
|
||||
|
||||
1. 这项能力适合“启动时集中接入一批静态配置”的节点
|
||||
2. 生成器只负责循环调用,不负责 registry 的获取、生命周期或错误恢复
|
||||
|
||||
## 使用约束
|
||||
|
||||
- 目标类型必须是 `partial class`
|
||||
当前最重要的约束有这些:
|
||||
|
||||
- 宿主类型必须是顶层 `partial class`
|
||||
- 不支持嵌套类
|
||||
- 生成器不会自动调用 `__RegisterExportedCollections_Generated()`
|
||||
- 非泛型 `IEnumerable` 之类无法推导元素类型的集合不受支持
|
||||
- 注册方法必须对宿主类型可访问
|
||||
- 生成器不会自动接入 `_Ready()` 或其他生命周期方法
|
||||
- 宿主类型若已声明 `__RegisterExportedCollections_Generated()`,会触发命名冲突诊断
|
||||
- 只有当至少一个成员成功通过验证时,才会生成方法
|
||||
|
||||
## 诊断信息
|
||||
## 诊断速查
|
||||
|
||||
| 诊断 ID | 含义 |
|
||||
|-----------------------|-------------------------------------------------------------|
|
||||
| `GF_Common_Class_001` | 目标类型不是 `partial`,生成被跳过 |
|
||||
| `GF_Common_Class_002` | 宿主类型已声明 `__RegisterExportedCollections_Generated()`,与生成代码冲突 |
|
||||
| `GF_AutoExport_001` | `AutoRegisterExportedCollections` 不支持嵌套类 |
|
||||
| `GF_AutoExport_002` | 指定的注册器成员不存在 |
|
||||
| `GF_AutoExport_003` | 注册器成员上找不到兼容的注册方法 |
|
||||
| `GF_AutoExport_004` | 被标记的成员不是可枚举集合 |
|
||||
| `GF_AutoExport_005` | 无法推导集合元素类型 |
|
||||
| `GF_AutoExport_006` | 集合成员不是实例可读成员 |
|
||||
| `GF_AutoExport_007` | 注册器成员不是实例可读成员 |
|
||||
| `GF_AutoExport_008` | `RegisterExportedCollectionAttribute` 参数无效 |
|
||||
| 诊断 ID | 含义 |
|
||||
| --- | --- |
|
||||
| `GF_Common_Class_001` | 宿主类型不是 `partial class` |
|
||||
| `GF_Common_Class_002` | 已手写 `__RegisterExportedCollections_Generated()`,与生成代码冲突 |
|
||||
| `GF_AutoExport_001` | 不支持嵌套类 |
|
||||
| `GF_AutoExport_002` | 指定的 registry 成员不存在 |
|
||||
| `GF_AutoExport_003` | 找不到兼容且可访问的注册方法 |
|
||||
| `GF_AutoExport_004` | 被标记成员不可枚举 |
|
||||
| `GF_AutoExport_005` | 无法安全推导集合元素类型 |
|
||||
| `GF_AutoExport_006` | 集合成员不是实例可读成员 |
|
||||
| `GF_AutoExport_007` | registry 成员不是实例可读成员 |
|
||||
| `GF_AutoExport_008` | `RegisterExportedCollectionAttribute` 构造参数无效 |
|
||||
|
||||
## 调用时机建议
|
||||
## 何时适合用它
|
||||
|
||||
推荐在以下时机之一调用生成方法:
|
||||
适合:
|
||||
|
||||
- `_Ready()` 中,且在注册器字段已经准备好之后
|
||||
- 启动入口的显式 `Initialize()` 或 `Bootstrap()` 方法中
|
||||
- 测试中的装配阶段
|
||||
- 启动入口里有多组“集合 -> registry”的重复注册代码
|
||||
- 每个元素都只需要一次简单的单参数注册
|
||||
- 你想把“注册到哪个 registry、调用哪个方法”直接挂在成员声明上
|
||||
|
||||
不要在构造函数中调用,因为此时 Godot 导出字段和外部依赖通常还未准备完毕。
|
||||
不适合:
|
||||
|
||||
## 相关文档
|
||||
- 注册流程需要排序、过滤、去重或事务式回滚
|
||||
- 每个元素注册前后还要插入复杂副作用
|
||||
- 注册规则依赖运行时动态上下文,而不是静态成员绑定
|
||||
|
||||
- [源码生成器总览](./index)
|
||||
- [游戏内容配置系统](/zh-CN/game/config-system)
|
||||
## 推荐阅读
|
||||
|
||||
1. [/zh-CN/source-generators/index](./index.md)
|
||||
2. [/zh-CN/game/config-system](../game/config-system.md)
|
||||
3. [/zh-CN/source-generators/godot-project-generator](./godot-project-generator.md)
|
||||
4. `GFramework.Godot.SourceGenerators/README.md`
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user