docs(claude): 编程语言规范新增 C++(GDExtension)极限内核一级
将性能优化定义为逐级逃生梯 GDScript→C#→C++,仅当上一级 profile 证明不够才下探; C++ 用于连 C# 都不够的 SIMD/手工内存密集内核,代价最高须实测背书;接口壳+原生内核回退模式与验证要求统一覆盖 C#/C++。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -8,7 +8,7 @@ Spellforge(万法熔炉)—— Godot 4.6 (Mono) 弹幕射击 Roguelite,SoA
|
||||
|
||||
## 编程语言规范(GDScript / C#)
|
||||
|
||||
本工程为 Mono 双语工程,但**两种语言各有明确定位,绝非平均混用**。核心原则:**用对语言,而非用多语言**;发挥各自长处,以「先测量后优化」驱动性能,不做无凭据的过早优化。
|
||||
本工程为 Mono 工程,为追求性能允许 **GDScript / C# / C++** 三语共存,但**各有明确定位、按需逐级下探,绝非平均混用**。核心原则:**用对语言,而非用多语言**;发挥各自长处,以「先测量后优化」驱动性能,不做无凭据的过早优化。性能优化路线是一条**逐级升级的逃生梯**:GDScript(默认)→ C#(热路径逃生舱)→ C++(极限内核),**仅当上一级被 profile 证明不够时才下探下一级**。
|
||||
|
||||
**现状(务必知悉)**:当前**运行时 100% 为 GDScript** —— 全部 42 个 autoload、法术 VM、子弹/敌人/空间网格等所有热循环均是 GDScript,实测 500 敌 + 1500 弹 `_physics_process` ≈ 0.6ms(约帧预算 3.6%),性能充裕。`csharp/` 下的 3 个 `.cs` 文件是**未激活的死骨架**(无 `.csproj`、从未实例化、`_cs_node` 恒为 `null` 走 GD 回退),**不要假设它们在运行**。C# 热路径迁移是文档记录但**已无限期推迟**的方案(风险 `R-08` / `ADR-L1`)。
|
||||
|
||||
@@ -17,8 +17,10 @@ Spellforge(万法熔炉)—— Godot 4.6 (Mono) 弹幕射击 Roguelite,SoA
|
||||
- **C# 仅为「热路径逃生舱」**:**唯一**动机是 GDScript 已被 profile 证明扛不住的密集数值内循环(大规模弹幕积分、Boid 分离、空间哈希)。C# 长处是原生吞吐、真值类型 `struct`、`Span<T>` 零拷贝、纯 C# 循环内无每次调用的封送开销。**除此之外不要引入 C#。**
|
||||
- 引入门槛(缺一不可):① 有 profile 数据佐证瓶颈;② 补齐可编译的 `.csproj`(当前不存在);③ 遵循 `docs/technical/architecture_design.md` §6.1 / `ADR-L1` 热路径三铁律 —— **(a)** 内循环**禁止** `GodotObject.Call()` / `.Set()`(跨语言封送即性能杀手);**(b)** 经 `PackedFloat32Array.AsSpan()` 零拷贝直读 SoA 数组;**(c)** 事件经 `EventBus.emit_batch` 批量通知,勿逐个跨界回调。
|
||||
- 跨语言边界成本真实(`R-08`):**热数据与热循环须落在边界同一侧**,仅在边界处批量进出。切忌把一个循环拆成 GD↔C# 反复横跳。
|
||||
- **两层架构模式**(如某系统确需 C# 内核):GDScript 侧为接口壳(对外 API、注册、事件),C# 内核作为子节点自注册 `_cs_node`;GDScript **必须保留可用的纯 GD 回退路径**(现有 `bullet_manager.gd` / `spatial_grid.gd` / `enemy_manager.gd` 的 `if not _cs_node:` 即此模式)。
|
||||
- **改动后验证**:GDScript 用 godot-mcp-pro `validate_script`;若真激活 C#,须确保 `.csproj` 能编译且过 `ADR-L1` review,并补基准对比(迁移前后 `_physics_process` 耗时)证明确有净收益,否则不合入。
|
||||
- **C++(GDExtension)为「极限内核」最深一级**:**唯一**动机是连 C# 都被 profile 证明不够、且属计算密集到值得动用原生手段的核心内核(如 SIMD 向量化的弹幕/碰撞积分、需手动内存布局与缓存对齐的空间结构)。C++ 长处是无托管开销、可控内存布局、SIMD/内联汇编、直贴 `PackedArray` 底层指针。代价也最高:需 `godot-cpp` 子模块 + SConstruct/CMake 交叉编译工具链、按平台产出 `.dll`/`.so`/`.dylib`、调试与移植成本远高于前两级 —— **绝不为「感觉会更快」而引入,必须有前一级的实测瓶颈数据背书。** 当前工程**尚无任何 GDExtension**,引入即新增构建维度,须先在文档立项(对齐 `ADR-L1` 同源精神)。
|
||||
- C++ 侧同样遵循边界纪律:接口经 `GDExtension` 绑定暴露给 GDScript 壳,热循环全程在 C++ 内完成,仅在边界批量传 `PackedArray`(零拷贝取原生指针),不在内循环回调 GDScript/C#。
|
||||
- **接口壳 + 原生内核模式**(如某系统确需 C# 或 C++ 内核):GDScript 侧为接口壳(对外 API、注册、事件),原生内核(C# 子节点自注册 `_cs_node`,或 C++ GDExtension 类)承担热循环;GDScript **必须保留可用的纯 GD 回退路径**(现有 `bullet_manager.gd` / `spatial_grid.gd` / `enemy_manager.gd` 的 `if not _cs_node:` 即此模式),确保内核未编译/未加载时游戏仍可运行。
|
||||
- **改动后验证**:GDScript 用 godot-mcp-pro `validate_script`;若真激活 C#/C++,须确保对应工程能编译(`.csproj` / GDExtension 构建)、过 `ADR-L1` review,并补基准对比(迁移前后 `_physics_process` 耗时)证明确有净收益,否则不合入 —— **性能优化以数据论成败,不以语言层级论高低**。
|
||||
|
||||
## Git 提交规范
|
||||
|
||||
|
||||
Reference in New Issue
Block a user