# AGENTS.md — SBE(Seek-Battle-Evacuate)
单人 3d 类吸血鬼幸存者游戏原型。Unity 2022.3.62f3,框架为 GameFramework(UGF,源码在 `Assets/GameFramework/`),配置表用 Luban,插件有 UniTask、DOTween 等。
## 主要目录
| 路径 | 内容 |
| --- | --- |
| `Assets/GameMain/Scripts/Base/` | 程序集 `SepCore.Base`:常量、存档数据结构(`Definition/DataStruct/`)、Luban 生成代码(`Gen/`) |
| `Assets/GameMain/Scripts/Runtime/` | 程序集 `SepCore.Runtime`:战斗内核(`Battle/`)、自定义组件(`CustomComponent/` 下 Luban、Random、Run、Save)、UIBase |
| `Assets/GameMain/Scripts/UI/` | 程序集 `SepCore.Presentation`:各界面 Form/View |
| `Assets/GameMain/Scripts/Procedure/`、`Editor/` | UGF 流程、编辑器工具 |
| `Assets/GameMain/Scripts/Tests/EditMode/` | EditMode 测试 |
| `数据表/` | Luban 源:`Datas/*.xlsx`(`__tables__.xlsx` 注册)、`Defines/`、导出脚本 `gen_cli.sh` / `gen_cli.bat` |
| `Docs/GameDesign/`、`Docs/Tech/` | 设计文档;技术文档(Luban、存档、UI、战斗 TODO) |
## 生成代码不可手改
- `Scripts/Base/Gen/` 全部由 Luban 导出。改表只改 `数据表/Datas/` 源表,再运行 `数据表/gen_cli.sh`(Windows 也可 `gen_cli.bat`)。
- `Scripts/UI/` 下的 `XxxForm.cs` / `XxxView.cs` 由 `UIAssetsTools` 生成(文件头有 `// `)。业务逻辑写在同名 `XxxForm.Logic.cs` partial 中;prefab 上要暴露给代码的组件在 `UISerializationItem` 登记变量名后重新构建(编辑器菜单 `Utility/UI/Build UI Prefabs`)。
## UI 常见坑(详见 `Docs/Tech/UIMaintenance.md`)
- UGF 只对顶级 Form 调用 `OnInit/OnOpen/OnClose` 生命周期;**嵌套 Form 的这些方法永远不会执行**。事件绑定用幂等模式(`_listenersBound` 标志 + `EnsureXxx()`),放在能力入口(如 `Refresh`)里。
- 子 Form 只提供能力(public 方法,幂等可重入),数据由调用方传入;只有顶级 Form 有编排权。子组件向上通信用 `GameEntry.Event.Fire` + `XxxEventArgs`(放 `Scripts/Base/Event/UIForm/`,`ReferencePool` + `Create`/`Clear`),禁止反向持有父 Form。
## Luban 约定(详见 `docs/tech/01_LubanDataTable.md`)
- 表名小写 `tbxxxconfig`:Excel 表名、导出文件名、`Tables` 构造参数、`TableNames` 数组四处必须一致。
- 访问入口 `GameEntry.Luban.Get(id)` / `GetTable()`;单行表(`mode=one`,如 `tbglobalconfig`)不注册访问器,走 `Tables.TbXxxConfig.Data`。
- 从 Luban 里取出的数据默认其有效,业务代码不对其是否有效做判断。
## 判空与错误处理
- 声明处已经初始化赋值的变量,之后**不再对它判空**。
- 不做静态回退(不用默认值/兜底逻辑静默继续);异常路径直接 `Log.Error(...)` 抛出(UGF 的 `Log`,支持格式串,如 `Log.Error("Entity data is invalid.")`)。
- UI 的序列化字段(`[SerializeField]` 及 View 生成的引用)**不做判空检查**,默认已在 Inspector 中赋值。
- GameEntry 中提供的静态入口不对其进行判空,默认其不为空。
## 代码风格
- 命名:public 成员大驼峰(`EncounterId`、`RoundNumber`);私有字段 `_` 前缀 + 小驼峰(`_random`、`_view`),序列化字段写作 `[SerializeField] private XxxView _view = null;`;方法(含 private)大驼峰。
- 程序集拆分为 `SepCore.Base / Runtime / Presentation / Procedure / Editor` + `Tests`(仅 Editor 平台)+ `Luban.Runtime`;跨程序集引用参考各 `.asmdef` 的 GUID 列表。
- 命名空间跟随程序集根(如 `SepCore.Battle`、`SepCore.Definition`)。