mirror of
https://github.com/oshima-studios/OshimaGameModule.git
synced 2026-06-04 19:42:13 +00:00
docs: add AGENTS.md and CLAUDE.md for AI coding agents (#4)
Introduce a Chinese-language project guide at AGENTS.md (cross-tool standard read by Cursor/Aider/Copilot CLI) covering build commands, required sibling repos, plugin architecture, the ID-switch entity registration pattern, persistence layers, lifecycle hooks, scheduled jobs, and project conventions. CLAUDE.md is a short pointer to AGENTS.md so the two stay in sync without duplicate maintenance. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
d844084c09
commit
d59878f75a
126
AGENTS.md
Normal file
126
AGENTS.md
Normal file
@ -0,0 +1,126 @@
|
||||
# AGENTS.md
|
||||
|
||||
本文档为 Claude Code(claude.ai/code)以及其他 AI 编码代理(Cursor、Aider、Copilot CLI 等)在本仓库工作时提供项目指引。
|
||||
|
||||
## 仓库概述
|
||||
|
||||
这是 **Oshima Studios 为 FunGame 引擎制作的模组(addon pack)**,并非独立可运行的应用程序。每个项目都会生成一个 DLL,由宿主 FunGame 运行时作为插件加载。上游引擎仓库:<https://github.com/project-redbud/FunGame-Core>。
|
||||
|
||||
代码中的大多数标识符、角色 / 技能 / 物品类名以及游戏内字符串均为**中文(CJK)**。源文件统一使用 UTF‑8 编码,请勿"规范化"这些标识符名称。
|
||||
|
||||
## 构建与运行
|
||||
|
||||
解决方案目标框架为 **`.NET 10.0`**(WPF 项目使用 `net10.0-windows7.0`)。使用标准 .NET SDK 构建:
|
||||
|
||||
```sh
|
||||
dotnet build OshimaGameModule.sln # 构建全部项目
|
||||
dotnet build OshimaWebAPI/OshimaWebAPI.csproj # 构建单个项目
|
||||
dotnet run --project OshimaWebAPI # 开发服务器: https://localhost:11108, http://localhost:11109
|
||||
```
|
||||
|
||||
### 必需的同级仓库
|
||||
|
||||
`OshimaGameModule.sln` 通过相对路径引用了**本目录以外**的项目:
|
||||
|
||||
| 引用 | 被谁依赖 |
|
||||
| ------------------------------------------------------ | --------------------------------- |
|
||||
| `../FunGame.Core/FunGame.Core.csproj` | 所有项目 |
|
||||
| `../FunGame.Extension/FunGame.SQLQueryExtension/...` | `OshimaWebAPI`、`OshimaServers` |
|
||||
| `../FunGame.Desktop/FunGame.Desktop/...` | 仅出现在 `.sln` 中 |
|
||||
|
||||
构建前请将这些仓库克隆为 `OshimaGameModule/` 的**同级目录**,否则 restore 阶段会失败。
|
||||
|
||||
### 输出目录布局
|
||||
|
||||
各类库项目均设置 `<BaseOutputPath>..\bin\</BaseOutputPath>`,因此所有构建产物会汇集到解决方案根目录的 **`OshimaGameModule/bin/`**,而不是各项目自己的 `bin/` 文件夹。宿主 FunGame 运行时正是从此聚合目录中发现并加载插件。
|
||||
|
||||
### 平台说明
|
||||
|
||||
- `OshimaModes` 是 WPF 项目(`UseWPF=True`、`net10.0-windows7.0`),**只能在 Windows 上构建**。在 macOS / Linux 上请单独构建非 WPF 项目,整体 `.sln` 构建会因 `OshimaModes` 失败。
|
||||
- `OshimaWebAPI` 是 ASP.NET Core 项目(`FrameworkReference Microsoft.AspNetCore.App`),跨平台运行。
|
||||
|
||||
仓库中**没有测试项目**。
|
||||
|
||||
## 架构:各插件如何协作
|
||||
|
||||
```
|
||||
OshimaCore ──┐
|
||||
├── OshimaModules ──┐
|
||||
OshimaMaps ───┤ ├── OshimaServers ──┐
|
||||
│ │ ├── OshimaWebAPI
|
||||
└────────── OshimaModes (WPF) ──────────┘ (同时依赖 Modules + Maps)
|
||||
```
|
||||
|
||||
每个项目的 `RootNamespace` 都按 `Oshima.FunGame.$(MSBuildProjectName)` 的模板生成(`OshimaCore` 例外 → `Oshima.Core`)。
|
||||
|
||||
### 各项目职责
|
||||
|
||||
| 项目 | 职责 | 插件类与 FunGame 基类 |
|
||||
| ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
|
||||
| `OshimaCore` | 常量、基于 JSON 的设置(`GeneralSettings`、`Daily`、`SayNo`、`Ignore`、`QQOpenID`、`BlackList`) | `OSMCore.InitOSMCore()` 启动入口;本身不是插件类 |
|
||||
| `OshimaModules` | 实体定义(角色、技能、物品、特效、地区、单位) | `CharacterModule`、`SkillModule`、`ItemModule` —— 继承自 FunGame 的 `Library.Common.Addon.*Module` |
|
||||
| `OshimaMaps` | `GameMap` 实现 | `FastAutoMap`、`AnonymousMap` |
|
||||
| `OshimaServers` | 游戏服务器插件 + 业务服务层(`Service/FunGameService.cs`、`FunGameSimulation.cs`、`OnlineService.cs`、`SQLService.cs`、`CSBettingService.cs`) | `OshimaServer`(`ServerPlugin`)、`FastAutoServer` 与 `AnonymousServer`(`GameModuleServer`) |
|
||||
| `OshimaWebAPI` | ASP.NET Core 控制器 + 定时任务 + QQ / RainBOT 集成 | `OshimaWebAPI : WebAPIPlugin, IHotReloadAware, ILoginEvent` |
|
||||
| `OshimaModes` | 游戏模式的 Windows 桌面 UI(WPF) | 仅承载模式,本身不是 FunGame 插件 |
|
||||
|
||||
### 插件标识符集中在常量表中
|
||||
|
||||
所有插件名、addon ID 以及 `GameModuleDepend` 依赖图都集中在 **`OshimaCore/Constant/Constant.cs`** 的 `OshimaGameModuleConstant` 类中。新增一种 addon 时,请在此注册它的 kebab-case ID —— 宿主引擎正是通过这些字符串来连接依赖关系的。
|
||||
|
||||
### 实体注册模式(重要)
|
||||
|
||||
`CharacterModule` / `SkillModule` / `ItemModule` 各自覆写一个 `*Factory()` 方法,返回的委托通过一个庞大的 `switch` 按整数 ID 分派(见 `OshimaModules/Modules/*.cs`)。要新增一个角色 / 技能 / 物品,需要:
|
||||
|
||||
1. 在合适的目录下定义实体类(如 `Characters/`、`Skills/魔法/`、`Items/Weapon/`)。
|
||||
2. 在对应的 ID 枚举中加一项(`SkillID`、`MagicID`、`SuperSkillID`、`PassiveID`、`ItemPassiveID`、`WeaponID` 等 —— 见 `Skills/SkillID.cs`、`Items/ItemID.cs`)。
|
||||
3. 在该模块的工厂 `switch` 中加一行 `case (long)YourEnum.X => new X()`。
|
||||
|
||||
仓库中**没有**基于反射的自动发现机制;这些 `switch` 表就是唯一的事实来源。
|
||||
|
||||
### 持久化
|
||||
|
||||
通过宿主 FunGame 运行时提供两层持久化:
|
||||
|
||||
- **`PluginConfig`**(位于宿主配置目录下的 key/value JSON 文件,例如 `new PluginConfig("rainbot", "config")`)—— 用于 `GeneralSettings`、每日 / 黑名单状态、各服务器的统计数据(`FunGameSimulation.StatsConfig`、`FastAutoServer.StatsConfig`)。
|
||||
- **`SQLHelper`**(在插件中通过 `Controller.GetSQLHelper()` 获取,配合 `NewTransaction()` / `Rollback()` / `Commit()` 使用)—— 用于用户、库存、角色 / 物品所有权。`OshimaWebAPI/Constant/*.sql` 下的脚本是游戏专属表(如 `CSBetting.sql`)的参考 SQL。
|
||||
|
||||
### 生命周期钩子(FunGame addon 契约)
|
||||
|
||||
所有插件都实现 `IHotReloadAware`。扩展时请留意以下方法:
|
||||
|
||||
- `AfterLoad(loader, params object[] objs)` —— 接入 DI / `SQLHelper` / 事件处理器。对于 `OshimaWebAPI`,`objs[0]` 是 `WebApplicationBuilder` —— 在此注册 scoped 服务。
|
||||
- `OnWebAPIStarted(params object[] objs)` —— 对 `WebAPIPlugin` 而言,`objs[0]` 是已运行的 `WebApplication`。此处会调用 `FunGameConstant.InitFunGame()`、`FunGameSimulation.InitFunGameSimulation()`,并注册**所有 `TaskScheduler.Shared.AddTask(...)` / `AddRecurringTask(...)` 定时任务**(见 `OshimaWebAPI.cs`)。
|
||||
- `OnBeforeUnload()` —— 必须按名称移除自己曾添加的每个定时任务,否则热重载会泄露重复任务。
|
||||
|
||||
### 定时任务(在 `OshimaWebAPI.cs` 注册)
|
||||
|
||||
任务名为中文;新增任务时记得在 `OnBeforeUnload` 中按相同名称移除:
|
||||
|
||||
```
|
||||
"重置每日运势" 每日 00:00 — Daily.ClearDaily / 活动缓存 / 公告 / 商店预刷新
|
||||
"上九" / "下三" 每日 09:00 / 15:00 — 物品交易冷却重置 + 地区天气刷新
|
||||
"刷新存档缓存" 每 1 分钟 — RefreshSavedCache、RefreshClubData、RoomsAutoDisband
|
||||
"刷新每日任务" 每日 04:00 — 每日任务、签到、商店、市场、活动缓存、公告
|
||||
"刷新boss" 每 1 小时
|
||||
"刷新活动缓存" 每 4 小时
|
||||
```
|
||||
|
||||
### 认证(WebAPI)
|
||||
|
||||
`OshimaWebAPI` 接入了 FunGame 的 `WebAPIAuthenticator.WebAPICustomBearerTokenAuthenticator`。token 仅与 **`GeneralSettings.TokenList`**(从 `rainbot/config` 的 `PluginConfig` 加载)中的列表做匹配。带 `[Authorize(AuthenticationSchemes = "CustomBearer")]` 的控制器需要鉴权(见 `Controllers/FunGameController.cs`);标记 `[AllowAnonymous]` 的接口为有意公开(`/funGame/test`、`/funGame/last`、`/funGame/stats`)。
|
||||
|
||||
### 两类不同的 "Server" 插件,容易混淆
|
||||
|
||||
- **`OshimaServer : ServerPlugin`** —— 接入宿主服务器的控制台(`.osm` 指令、商店事件)。
|
||||
- **`FastAutoServer` / `AnonymousServer : GameModuleServer`** —— 真正的游戏房间逻辑。`FastAutoServer` 通过 `MixGamingQueue` 跑自动对战循环(见 `FastAutoServer.cs` 的 `StartGame`);`AnonymousServer` 是供外部 bot 使用的、基于 token 的 WebSocket 桥。
|
||||
|
||||
两类插件会同时加载进同一个运行时 —— 互不替代。
|
||||
|
||||
## 值得遵循的约定
|
||||
|
||||
- 新的字符串 ID 一律加入 `OshimaGameModuleConstant`;不要在代码中散布 `"oshima.fungame.xxx"` 这类字面量。
|
||||
- 新 addon 必须**同时**更新实体工厂和对应的 ID 枚举。
|
||||
- 在 `OnWebAPIStarted` 中通过 `TaskScheduler.Shared.AddTask` 注册的任务,必须在 `OnBeforeUnload` 中以同名 `RemoveTask` 注销 —— 热重载会反复执行两边,否则任务会成倍累积。
|
||||
- 大量使用中文标识符是有意为之。`.csproj` 中关闭了 `CS8981`(小写标识符)与 `IDE1006`(命名风格)正是这个原因 —— 请勿重新启用。
|
||||
- WebAPI 开发配置使用 `ASPNETCORE_ENVIRONMENT=Development`,监听 `https://localhost:11108;http://localhost:11109`(见 `OshimaWebAPI/Properties/launchSettings.json`)。
|
||||
Loading…
x
Reference in New Issue
Block a user