Skip to content

docs(config): 添加游戏内容配置系统文档和集成测试#186

Merged
GeWuYou merged 2 commits into
mainfrom
feat/add-game-content-config-with-source-generator
Apr 6, 2026
Merged

docs(config): 添加游戏内容配置系统文档和集成测试#186
GeWuYou merged 2 commits into
mainfrom
feat/add-game-content-config-with-source-generator

Conversation

@GeWuYou

@GeWuYou GeWuYou commented Apr 6, 2026

Copy link
Copy Markdown
Owner
  • 新增游戏内容配置系统完整文档,包含 YAML 配置、JSON Schema 结构描述
  • 添加推荐目录结构和配置示例,支持怪物、物品、技能等静态内容管理
  • 实现 Source Generator 自动生成配置类型、表包装和注册访问辅助功能
  • 集成 VS Code 插件提供配置浏览、raw 编辑、schema 打开和校验功能
  • 添加生成查询辅助,为顶层标量字段生成 FindBy* 与 TryFindFirstBy* 方法
  • 实现开发期热重载功能,支持配置文件修改后自动刷新运行时表
  • 添加跨表引用校验,支持 x-gframework-ref-table 声明的引用关系检查
  • 新增集成测试验证生成器自动拾取 schema 并支持强类型访问入口
  • 添加 IsExternalInit 类型支持低版本 .NET 框架的 init-only setter 功能

Summary by CodeRabbit

  • New Features

    • Added generated query helpers on config tables for top-level scalar fields (e.g., FindByName, TryFindFirstByName/ByHp)
    • Monster config now includes a required "faction" field
  • Documentation

    • Added guidance on which query helpers are generated and recommended architecture integration patterns
  • Tests

    • New integration tests validating config loading, generated queries, and architecture initialization behavior

- 新增游戏内容配置系统完整文档,包含 YAML 配置、JSON Schema 结构描述
- 添加推荐目录结构和配置示例,支持怪物、物品、技能等静态内容管理
- 实现 Source Generator 自动生成配置类型、表包装和注册访问辅助功能
- 集成 VS Code 插件提供配置浏览、raw 编辑、schema 打开和校验功能
- 添加生成查询辅助,为顶层标量字段生成 FindBy* 与 TryFindFirstBy* 方法
- 实现开发期热重载功能,支持配置文件修改后自动刷新运行时表
- 添加跨表引用校验,支持 x-gframework-ref-table 声明的引用关系检查
- 新增集成测试验证生成器自动拾取 schema 并支持强类型访问入口
- 添加 IsExternalInit 类型支持低版本 .NET 框架的 init-only setter 功能

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @GeWuYou, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@deepsource-io

deepsource-io Bot commented Apr 6, 2026

Copy link
Copy Markdown

DeepSource Code Review

We reviewed changes in fb3bf49...7fad677 on this pull request. Below is the summary for the review, and you can see the individual issues we found as inline review comments.

See full review on DeepSource ↗

PR Report Card

Overall Grade   Security  

Reliability  

Complexity  

Hygiene  

Code Review Summary

Analyzer Status Updated (UTC) Details
C# Apr 6, 2026 4:25a.m. Review ↗
Secrets Apr 6, 2026 4:25a.m. Review ↗

@coderabbitai

coderabbitai Bot commented Apr 6, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

This PR adds generated per-property query helpers (FindBy*/TryFindFirstBy*) for top-level scalar config fields, updates the monster schema/tests to exercise them, extends generator tests and docs, and includes minor whitespace/line-ending normalizations.

Changes

Cohort / File(s) Summary
Whitespace Normalization
GFramework.Core.Abstractions/Internals/IsExternalInit.cs
Normalized line endings and trailing newline; no semantic changes to conditional compilation or class.
Schema Updates
GFramework.Game.Tests/schemas/monster.schema.json
Added required faction string property to monster schema to enable non-unique query testing.
Query Helper Generation
GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs, GFramework.SourceGenerators.Tests/Config/snapshots/SchemaConfigGenerator/MonsterTable.g.txt
Generator now collects eligible top-level scalar properties and emits FindBy{Prop} (IReadOnlyList) and TryFindFirstBy{Prop} (bool + out) methods that perform linear scans over All().
Generator Tests
GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.cs
Added test ensuring helpers are generated only for top-level scalar properties and not for arrays, objects, references, or key fields.
Integration Tests
GFramework.Game.Tests/Config/ArchitectureConfigIntegrationTests.cs, GFramework.Game.Tests/Config/GeneratedConfigConsumerIntegrationTests.cs
Added architecture-level integration test wiring ConfigRegistry and YamlConfigLoader; updated generated-config test instances and assertions to exercise new query helpers (FindByFaction, TryFindFirstByName, etc.).
Documentation
docs/zh-CN/game/config-system.md
Documented "Query Helper Generation" rules and added an Architecture.OnInitialize() integration template showing registry/loader registration and access patterns.

Sequence Diagram(s)

sequenceDiagram
  participant Arch as ConsumerArchitecture
  participant CReg as ConfigRegistry
  participant Loader as YamlConfigLoader
  participant FS as FileSystem

  Arch->>CReg: Register ConfigRegistry (RegisterUtility)
  Arch->>Loader: Construct with temp root
  Arch->>Loader: LoadAsync(schema files)
  Loader->>FS: Read monster.schema.json, slime.yaml, goblin.yaml
  FS-->>Loader: Return schema and YAML contents
  Loader->>CReg: Parse & Populate MonsterTable (calls generated Table wrappers)
  CReg-->>Arch: MonsterTable available via Context.GetUtility<ConfigRegistry>()
  Arch->>Arch: OnInitialize uses MonsterTable.FindByFaction(...)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • Feat/ai first config system #175: Modifies the config source generator and generated table helpers, tests, and docs—directly related to the query-helper generation changes in this PR.

Poem

🐰 Hop, I scurry through the code,
Helpers bloom where schemas sowed,
FindBy, TryFind — swift and neat,
Tables sing with each small feat,
Bunny cheers for query row! 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 78.57% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title describes adding documentation and integration tests for the game content configuration system, which directly aligns with the main changes (new documentation file, integration tests, and schema updates).

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/add-game-content-config-with-source-generator

Comment @coderabbitai help to get the list of available commands and usage tips.

Comment thread GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
GFramework.Game.Tests/Config/ArchitectureConfigIntegrationTests.cs (1)

16-57: 建议复用现有 Architecture 测试基建,减少样板和生命周期分支。

这里的初始化/销毁与目录治理逻辑较多,后续可考虑迁移到现有测试基类模式以提高一致性与可维护性。

Based on learnings: Reuse existing architecture test infrastructure when relevant: ArchitectureTestsBase<T>, SyncTestArchitecture, AsyncTestArchitecture.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@GFramework.Game.Tests/Config/ArchitectureConfigIntegrationTests.cs` around
lines 16 - 57, Replace the manual setup/teardown and temp-dir handling in
ArchitectureConfigIntegrationTests with the shared test infrastructure: inherit
from ArchitectureTestsBase<ConsumerArchitecture> (or use
SyncTestArchitecture/AsyncTestArchitecture helper) so the base class manages
lifecycle and temp config root; update the test to obtain a ConsumerArchitecture
instance from the base (or create it via the provided Sync/Async factory),
remove CreateTempConfigRoot/DeleteDirectoryIfExists, and call the base
init/destroy helpers instead of directly calling InitializeAsync/DestroyAsync to
eliminate duplicated boilerplate and lifecycle branches.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@GFramework.Game.Tests/Config/ArchitectureConfigIntegrationTests.cs`:
- Around line 81-88: 当前清理块只捕获 IOException,当调用 Directory.Delete(path, true)
在某些环境可能抛出 UnauthorizedAccessException,导致非预期失败;修改
ArchitectureConfigIntegrationTests.cs 中执行 Directory.Delete(path, true) 的
try-catch,使其同时捕获 UnauthorizedAccessException(或改为 catch (Exception)
但保留“best-effort”注释),确保删除失败被静默吞掉并保留现有注释和意图。

In `@GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.cs`:
- Around line 338-347: Add negative assertions to the test to ensure the
generator does not produce TryFindFirstBy* overloads for excluded fields: update
the Assert.Multiple block that currently checks Does.Not.Contain("FindById("),
"FindByDropItems(", "FindByTargetId(", "FindByReward(") to also assert
Does.Not.Contain("TryFindFirstById("),
Does.Not.Contain("TryFindFirstByDropItems("),
Does.Not.Contain("TryFindFirstByTargetId("), and
Does.Not.Contain("TryFindFirstByReward(") so the test verifies both FindBy* and
TryFindFirstBy* are not generated (referencing TryFindFirstByName and
TryFindFirstByHp as examples of the positive assertions to mirror).

---

Nitpick comments:
In `@GFramework.Game.Tests/Config/ArchitectureConfigIntegrationTests.cs`:
- Around line 16-57: Replace the manual setup/teardown and temp-dir handling in
ArchitectureConfigIntegrationTests with the shared test infrastructure: inherit
from ArchitectureTestsBase<ConsumerArchitecture> (or use
SyncTestArchitecture/AsyncTestArchitecture helper) so the base class manages
lifecycle and temp config root; update the test to obtain a ConsumerArchitecture
instance from the base (or create it via the provided Sync/Async factory),
remove CreateTempConfigRoot/DeleteDirectoryIfExists, and call the base
init/destroy helpers instead of directly calling InitializeAsync/DestroyAsync to
eliminate duplicated boilerplate and lifecycle branches.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: f8069136-12a1-4ccb-aad9-8bd8ef43c1d9

📥 Commits

Reviewing files that changed from the base of the PR and between fb3bf49 and 2b30e85.

📒 Files selected for processing (8)
  • GFramework.Core.Abstractions/Internals/IsExternalInit.cs
  • GFramework.Game.Tests/Config/ArchitectureConfigIntegrationTests.cs
  • GFramework.Game.Tests/Config/GeneratedConfigConsumerIntegrationTests.cs
  • GFramework.Game.Tests/schemas/monster.schema.json
  • GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.cs
  • GFramework.SourceGenerators.Tests/Config/snapshots/SchemaConfigGenerator/MonsterTable.g.txt
  • GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs
  • docs/zh-CN/game/config-system.md

Comment thread GFramework.Game.Tests/Config/ArchitectureConfigIntegrationTests.cs
- 添加 ArchitectureConfigIntegrationTests 测试验证配置注册表初始化功能
- 实现 SchemaConfigGenerator 源代码生成器解析JSON schema文件
- 生成配置类型类、配置表包装器和运行时绑定辅助代码
- 支持嵌套对象、对象数组、标量数组的类型安全访问
- 提供强类型的配置表查询方法如 FindByProperty 等
- 实现跨表引用元数据生成和验证机制

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
GFramework.Game.Tests/Config/ArchitectureConfigIntegrationTests.cs (1)

145-153: Blocking async call is acceptable here but worth documenting.

The .GetAwaiter().GetResult() at line 151 is necessary because OnInitialize() is synchronous (as shown in the Architecture lifecycle). This works in test code without a SynchronizationContext, but the pattern could cause deadlocks in other contexts (e.g., UI threads, ASP.NET Classic).

Consider adding a brief inline comment explaining why synchronous blocking is used here:

📝 Optional: Add clarifying comment
         protected override void OnInitialize()
         {
             RegisterUtility(Registry);

             var loader = new YamlConfigLoader(_configRoot)
                 .RegisterMonsterTable();
+            // OnInitialize is synchronous; block here since test runner has no SynchronizationContext.
             loader.LoadAsync(Registry).GetAwaiter().GetResult();
             MonsterTable = Registry.GetMonsterTable();
         }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@GFramework.Game.Tests/Config/ArchitectureConfigIntegrationTests.cs` around
lines 145 - 153, Add a short inline comment in OnInitialize next to the
loader.LoadAsync(Registry).GetAwaiter().GetResult() call explaining that
synchronous blocking is used intentionally because OnInitialize is synchronous
in the Architecture lifecycle and tests run without a SynchronizationContext;
mention the risk of deadlocks in contexts with a SynchronizationContext (e.g.,
UI threads or classic ASP.NET) so future maintainers understand why
GetAwaiter().GetResult() is necessary and to avoid using it outside test/setup
code.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@GFramework.Game.Tests/Config/ArchitectureConfigIntegrationTests.cs`:
- Around line 145-153: Add a short inline comment in OnInitialize next to the
loader.LoadAsync(Registry).GetAwaiter().GetResult() call explaining that
synchronous blocking is used intentionally because OnInitialize is synchronous
in the Architecture lifecycle and tests run without a SynchronizationContext;
mention the risk of deadlocks in contexts with a SynchronizationContext (e.g.,
UI threads or classic ASP.NET) so future maintainers understand why
GetAwaiter().GetResult() is necessary and to avoid using it outside test/setup
code.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 952c07d8-1b9c-4223-b53b-2948282b92e5

📥 Commits

Reviewing files that changed from the base of the PR and between 2b30e85 and 7fad677.

📒 Files selected for processing (3)
  • GFramework.Game.Tests/Config/ArchitectureConfigIntegrationTests.cs
  • GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.cs
  • GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs
🚧 Files skipped from review as they are similar to previous changes (2)
  • GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.cs
  • GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs

@GeWuYou GeWuYou merged commit 77f67c8 into main Apr 6, 2026
10 checks passed
@GeWuYou GeWuYou deleted the feat/add-game-content-config-with-source-generator branch April 6, 2026 04:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant