From 2da6d6e94ec5ac0b0e9797c7fa55a616f1dfbd3c Mon Sep 17 00:00:00 2001 From: Joywayer Date: Thu, 23 Jul 2026 15:23:42 +0800 Subject: [PATCH] =?UTF-8?q?docs(claude):=20=E6=96=B0=E5=A2=9E=E7=BC=96?= =?UTF-8?q?=E7=A8=8B=E8=AF=AD=E8=A8=80=E8=A7=84=E8=8C=83=EF=BC=88GDScript/?= =?UTF-8?q?C#=EF=BC=89=E2=80=94=E2=80=94=20GDScript=20=E4=B8=BA=E4=B8=BB?= =?UTF-8?q?=E5=8A=9B=E3=80=81C#=20=E4=BB=85=E7=83=AD=E8=B7=AF=E5=BE=84?= =?UTF-8?q?=E9=80=83=E7=94=9F=E8=88=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 明确双语定位与「用对语言而非用多语言」原则:记录运行时现状(100% GDScript、csharp/ 为死骨架)、 GDScript 性能纪律、C# 引入门槛(profile + .csproj + ADR-L1 三铁律)、跨界成本 R-08、两层回退模式。 Co-Authored-By: Claude Opus 4.8 (1M context) --- CLAUDE.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/CLAUDE.md b/CLAUDE.md index e7f5e39..75f36a4 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -6,6 +6,20 @@ Spellforge(万法熔炉)—— Godot 4.6 (Mono) 弹幕射击 Roguelite,SoA / ECS-Lite 架构,法术管道系统。工程概览见 [`README.md`](README.md)。 +## 编程语言规范(GDScript / C#) + +本工程为 Mono 双语工程,但**两种语言各有明确定位,绝非平均混用**。核心原则:**用对语言,而非用多语言**;发挥各自长处,以「先测量后优化」驱动性能,不做无凭据的过早优化。 + +**现状(务必知悉)**:当前**运行时 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`)。 + +- **GDScript 为默认与主力语言**:游戏逻辑、系统管线、UI、`@tool` 编辑器插件、数据驱动胶水(JSON 加载/注册表/事件)、场景树与信号交互 —— 一律用 GDScript。它的长处是迭代快、与引擎/场景树/信号无缝、动态灵活。**新功能默认写 GDScript**,除非有实测数据证明是瓶颈。 + - GDScript 内的性能纪律:热循环用 SoA(`PackedFloat32Array` / `PackedInt32Array` + 整数实体 ID),避免每帧 `new`/字典/lambda;分支用 `match`/`for` 而非闭包;变量与函数签名标注静态类型(`: float` / `-> void`)以启用引擎优化;缓存跨节点引用,勿在内循环反复 `get_node`。 +- **C# 仅为「热路径逃生舱」**:**唯一**动机是 GDScript 已被 profile 证明扛不住的密集数值内循环(大规模弹幕积分、Boid 分离、空间哈希)。C# 长处是原生吞吐、真值类型 `struct`、`Span` 零拷贝、纯 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` 耗时)证明确有净收益,否则不合入。 + ## Git 提交规范 - **及时提交**:完成一个逻辑完整的改动(一个功能点、一处修复、一批相关文档更新)后应立即提交,不要将多个无关改动堆积在一个大提交里。