diff --git a/AGENTS.md b/AGENTS.md index 65ff8f48f..0b302ab43 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,318 +1,138 @@ -# AGENTS.md +# Repository Guidelines + +本文件是 Everglow 的根级 AI 编码指南,适用于整个仓库。进入子目录后,必须先查找更近的 `AGENTS.md`;局部规则优先。本仓库面向 Windows 上的 Terraria tModLoader,使用 C#、.NET 8、FNA,并以 GPL-3.0 发布。 + +## Start Here + +开始任务前,先确认改动范围并阅读对应实现、测试和局部说明;不要凭项目概览猜测 API 或资源路径。 + +| 任务 | 先阅读 | +| --- | --- | +| 构建、打包或 CI | `Documents/源代码编译流程.md`、`Sources/Directory.Build.props`、`.github/workflows/build-and-test.yml` | +| Mission 任务系统 | `Sources/Everglow.Function/Mechanics/Mission/README.md`、`CONTRACTS.md` | +| 触及 `Terraria.Main` 的测试 | `.cursor/rules/unit-testing-terraria-main.mdc` 与临近测试 | +| Food 模块 | `Sources/Modules/Food/FoodModule.md` | +| 新增游戏内容 | `Sources/Modules/Example/` 中相同内容类型的范例 | +| 子世界或 IL 修改 | `Documents/子世界.md`、`Documents/ILDoc/` | +| Yggdrasil | `Sources/Modules/Yggdrasil/AGENTS.md`、其 `README.md` | + +`Documents/`、子系统 README、`CONTRACTS.md` 与局部 `AGENTS.md` 是本文件的补充,不要将其内容复制回根指南。 + +## Repository Map + +```text +Everglow.sln solution: active modules + unit tests +Sources/ + Everglow/ Mod entry and all localization + Everglow.Core/ Terraria-independent base layer + Everglow.Function/ tML-facing shared functionality + Everglow.UnitTests/ MSTest tests + Modules/ content assemblies (14 active modules) +Libraries/SubworldLibrary.dll required external mod dependency; read-only +Tools/ build tasks and utilities +Documents/ design and workflow documentation +``` -> 面向 AI 编码 agent 的项目指南。修改本仓库代码前请完整阅读;当你改动了本文涉及的流程/结构/约定时,请同步更新本文。 -> 约定优先级:本文件 < 各目录下更具体的文档(如 `Sources/Everglow.Function/Mechanics/Mission/CONTRACTS.md`)。 +The project produces one `Everglow.tmod`: the main project assembles the Core, Function, and active content-module assemblies. The active module list is the `Modules` property in `Sources/Directory.Build.props`; the same value drives project references and conditional-compilation symbols. -## 项目概述 +`Modules/IIID`、`Modules/TwilightForest`、`Modules/ZY` 和 `Sources/Everglow.Scripts` 都是已废弃残留,不参与构建;不要在其中新增或恢复内容。 -Everglow(流光无际)是一个 Terraria tModLoader 大型综合内容模组,C# / .NET 8 / FNA,GPL-3.0。 +## Build and Test -- 解决方案:`Everglow.sln`(仓库根),所有 C# 源码在 `Sources/` 下。 -- 采用"单 Mod + 多程序集模块"架构:1 个主项目 + 2 个公共库 + 14 个内容模块,构建时合并产出**单一** `Everglow.tmod`。 -- 使用自研 MSBuild 工具链(NuGet 包 `Solaestas.tModLoader.ModBuilder`)构建,**不能**用 tML 游戏内"生成 Mod"按钮构建。 -- 依赖 tML 模组 `SubworldLibrary`(`Libraries/SubworldLibrary.dll`,`build.txt` 中 `modReferences = SubworldLibrary`)。 -- 主 Mod 入口:`Sources/Everglow/Everglow.cs`(`public class Everglow : Mod`)。 -- 官方构建文档:`Documents/源代码编译流程.md`(改动构建流程前先读它)。 +Prerequisites: .NET SDK 8.0+, a local tModLoader installation, Windows, and a `tModLoader.targets` file in this repository or one of its five ancestors that points at tML's `tMLMod.targets`. Shader compilation also requires the XNA runtime components normally installed with tML. -## 项目结构 +Run commands from the repository root: -``` -Everglow/ 仓库根 -├─ Everglow.sln 解决方案(含激活模块 + UnitTests) -├─ update.bat git fetch + rebase origin/master + dotnet clean + dotnet restore -├─ Sources/ -│ ├─ Directory.Build.props ★ 全局构建属性:net8.0、LangVersion=preview、 -│ │ 激活模块列表、ModBuilder/StyleCop 包、资源 Pack 白名单 -│ ├─ Directory.Build.targets WriteResource/ReadResource:模块资源清单的写入与汇总 -│ ├─ Everglow/ ★ 主 mod 项目(程序集 Everglow,唯一 EnableModBuilder=true) -│ │ ├─ Everglow.cs Mod 入口类(见「架构」) -│ │ ├─ build.txt mod 元数据(version、modReferences) -│ │ ├─ Localization/ ★ 全部本地化:en-US/ zh-Hans/ templates/ 下 Mods.Everglow.*.hjson -│ │ └─ lib/ FontStashSharp 等随 mod 分发的 dll -│ ├─ Everglow.Core/ ★ 基础库:不引用 Terraria/tML,RootNamespace = Everglow.Commons -│ ├─ Everglow.Function/ ★ 功能库:引用 tML,RootNamespace = Everglow.Commons,资源前缀 Commons -│ ├─ Everglow.UnitTests/ MSTest 测试项目 -│ ├─ Everglow.Scripts/ 【残留目录】只剩 bin/obj,源码已移至 Tools/Everglow.Scripts -│ └─ Modules/ ★ 内容模块(每个是独立的 Everglow.<名>.csproj 类库) -│ ├─ Directory.Build.props 模块统一配置:自动引用 Core/Function、PathPrefix=模块名、全局 using -│ ├─ AssetReplace/ CagedDomain/ EternalResolve/ Example/ Food/ MEAC/ -│ ├─ Minortopography/ Myth/ Ocean/ Plant/ PlantAndFarm/ SpellAndSkull/ -│ ├─ SubSpace/ Yggdrasil/ ← 以上 14 个为激活模块 -│ └─ IIID/ TwilightForest/ ZY/ ← 废弃:仅剩 bin/obj,未列入 与 .sln,勿改动 -├─ Libraries/ SubworldLibrary.dll(勿动) -├─ Resources/ 不打包的设计资源(图标、UI 皮肤、旧音乐,勿动) -├─ Tools/ 构建工具:Everglow.Tasks(WriteResource/ReadResource MSBuild 任务源码)、 -│ Everglow.Scripts(模块管理 CLI)、AtlasCutter、ImageRGBAConvert 等 -├─ Localization/ 旧版遗留单体 hjson(非现行体系,勿新增内容) -├─ Documents/ 中文设计/流程文档 -└─ .github/workflows/ 构建 + AI 审查 workflow - ├─ build-and-test.yml .NET 构建与测试 - ├─ holistic-review.lock.yml AI 审查(gh-aw 编译) - └─ agentics-maintenance.yml gh-aw 自动维护 +```powershell +dotnet restore +dotnet build +dotnet build /p:Configuration=Release /p:WarningLevel=0 +dotnet test --verbosity normal /p:WarningLevel=0 +dotnet test --filter "FullyQualifiedName~MissionSystem" +.\update.bat ``` -## 构建 +`dotnet build` packages and deploys `Everglow.tmod` to the local tML Mods directory, then enables it. Do not use tML's in-game “Build Mod” action for this repository. Stale `bin/` and `obj/` outputs are a known cause of build failures; consult the build document before removing caches. -### 环境前置(缺一不可) +When modifying `Sources/Directory.Build.props`, explain the structural impact and obtain user confirmation first. Keep the matching `Directory.Build.props` block in `.github/workflows/build-and-test.yml` synchronized, because CI regenerates the file before restore. -1. **.NET SDK 8.0+**(目标框架 net8.0,无 global.json 约束)。 -2. **本机安装 tModLoader**(Steam 版;当前目标版本 2026.03 / Terraria 1.4.4.9)。 -3. **`tModLoader.targets` 文件**:必须存在于本仓库或其上溯 5 级内的某个父目录,内容指向 tML 安装目录的 `tMLMod.targets`。标准布局(仓库克隆在 `Documents/My Games/Terraria/tModLoader/ModSources/Everglow`)下,`ModSources\tModLoader.targets` 已存在。缺失时构建报错 `Missing tModLoader.targets`。 -4. Windows 环境;编译 `.fx` shader 依赖 XNA 运行库组件(本机装过 tML 一般已具备;CI 会显式安装 XNA Framework Redistributable)。 +## Architecture and Placement -### 常用命令 - -```powershell -dotnet restore # 还原依赖 -dotnet build # Debug 构建全解决方案(含 .tmod 打包部署) -dotnet build /p:Configuration=Release /p:WarningLevel=0 # CI 构建方式 -dotnet test --verbosity normal /p:WarningLevel=0 # 运行全部单元测试(CI 方式) -dotnet test --filter "FullyQualifiedName~MissionSystem" # 按命名空间过滤测试 -.\update.bat # 同步上游:git fetch + rebase + clean + restore +```text +Everglow.Core -> interfaces, infrastructure, utilities; no Terraria/tML reference +Everglow.Function -> tML implementations, templates, hooks, VFX, UI, netcode +Modules -> gameplay/content; reference Core and Function automatically +Everglow -> composition, content discovery, resource merge, .tmod output ``` -### 构建产物与部署 +- Both Core and Function use `Everglow.Commons` as their root namespace. Do not add a Terraria/tML reference to Core; define an interface there and implement/register it in Function through `Ins` instead. +- `Sources/Everglow/Everglow.cs` automatically scans the `Everglow.*` assemblies and registers content. Do not manually call `AddContent` for normal `ModItem`, `ModNPC`, `ModProjectile`, `ModTile`, or `ModSystem` classes. +- A content module needs an `EverglowModule` only for lifecycle work such as hooks, effect preload, skies, or events. Normal content classes require no module entry point. +- Module projects inherit Core, Function, `SubworldLibrary`, `PathPrefix`, and standard global usings from `Sources/Modules/Directory.Build.props`. Do not duplicate those references or usings in module `.csproj` files. +- Add an explicit `ProjectReference` in a module's `.csproj` for every newly introduced cross-module type dependency. Existing dependencies include `Myth → SpellAndSkull`, `Ocean → Myth`, and `Yggdrasil → CagedDomain, Food, SpellAndSkull, SubSpace`. -- 构建主项目后自动执行:编译各项目 dll → 编译 `.fx` 为 `.xnb` → 汇总模块资源清单 → 生成 **`Everglow.tmod` 直接写入 tML Mods 目录**(`Documents\My Games\Terraria\tModLoader\Mods\`)→ 自动写入 `enabled.json` 启用模组。 -- VS 调试:使用 `Terraria` / `TerrariaServer` 启动配置(`Sources/Everglow/Properties/launchSettings.json`),即以 dotnet 启动 tML。 -- 构建异常时先删除各项目 `bin/`、`obj/` 再重建(过期缓存是常见问题)。 +## Resources and Content -### 构建系统关键点(改动前必读) +- Use the source-generated `ModAsset` members for assets in the current project. Use `Commons.ModAsset` for Function assets. Do not add handwritten asset paths unless a generated member cannot express the path. +- Runtime asset paths are `Everglow//`; a module's prefix is its module name and Function uses `Commons`. +- Resource packing is allowlisted. `.hjson`, `.txt`, and `.png` are automatic; other extensions need an appropriate packed `AdditionalFiles` entry. Read the build document before changing packing configuration. +- Never modify existing binary or art assets: `Resources/`, `Libraries/`, any module `.png/.obj/.ttf/.atlas/.xnb`, root `icon*.png`, or `Tools/*.exe|dll`. Do not create placeholder art; tell the user when a new asset is required. +- New content follows `Everglow.[.[.]]`. Keep matching assets beside their `.cs` file. Prefer the templates in `Everglow.Function/Templates` and the Example module over new bespoke base patterns. -- `Sources/Directory.Build.props`:全局属性 + **`` 模块列表**。该列表同时驱动主项目的 ProjectReference 和 `DefineConstants`(模块名即可用于 `#if Myth` 等条件编译),增删模块改这里。 -- ⚠️ **CI 会在 restore 前重新生成 `Sources/Directory.Build.props`**(workflow 内 echo 覆盖,内容与仓库版本一致)。修改该文件必须同步更新 `.github/workflows/build-and-test.yml` 中的对应段落,否则 CI 与本地行为不一致。 -- `Sources/Modules/Directory.Build.props`:每个模块自动获得——对 `Everglow.Core`、`Everglow.Function`、`Libraries/*.dll` 的引用;`PathPrefix = 模块名`(从项目名 `Everglow.<名>` 截取);全局 using(`Terraria`、`Terraria.ModLoader`、`Terraria.ID`、`Microsoft.Xna.Framework(.Graphics)`、`Everglow.Commons`)。**模块 csproj 通常保持空壳**,不要重复添加上述引用与 using。 -- `Sources/Directory.Build.targets` + `Tools/Everglow.Tasks`(WriteResource/ReadResource):各模块构建时把 `Pack=true` 的 `AdditionalFiles` 清单写入主项目 obj 下的 `*.resource`,主项目构建时汇总打包。 -- **资源打包是白名单制**:`.hjson/.txt/.png` 自动打包,`.ogg/.wav/.mp3/.json/.atlas/.obj/.bmp/.mapio/.ttf` 已在 props 中显式声明;新增其它资源类型必须在对应 csproj 中添加 ``。模块资源没生效时先查这里。 -- ModBuilder(NuGet `Solaestas.tModLoader.ModBuilder`):负责 tML 引用注入、程序集 Publicize、`.fx` shader 编译(`CompileEffect=true`,输出 `.xnb` 到 `Assets\`)、`.tmod` 生成、`ModAsset` 路径类源生成(`EnablePathGenerator=true`)。 -- 模组元数据:`Sources/Everglow/build.txt` + `description.txt` + `workshop_description.txt` + `icon*.png`。 +## Code, Gameplay, and Networking -### CI +- Follow `.editorconfig`: tab indentation (width 4), LF and UTF-8 without BOM for text, Allman braces, file-scoped namespaces, and a trailing newline. Keep `.sln` and `.csproj` as CRLF. +- Match local naming, comment language, and existing style. Do not perform unrelated reformatting. Module projects already provide common global usings. +- For `NPC.ai[]` and `Projectile.ai[]`, define a private enum and descriptive wrapper properties instead of scattered numeric indexes. +- Guard client-only graphics, VFX, render targets, and texture work with `!Main.dedServ`. Graphics services are not registered on a dedicated server. +- Use `ModIns.PacketResolver` for custom packets. Synchronize gameplay state with `netUpdate` when needed and use `SendExtraAI`/`ReceiveExtraAI` for additional projectile or NPC state. +- Gate unfinished work with `CompileTimeFeatureFlags` or `EverglowConfig`; do not submit always-enabled experimental behavior. -`.github/workflows/build-and-test.yml`(push/PR 到 master,windows-latest): +## Localization -1. **检查分支不得落后 origin/master**(behind 即失败)——提交 PR 前先 rebase/merge 最新 master(可用 `update.bat`)。 -2. 重新生成 `Directory.Build.props` → `dotnet restore` → 下载 tML 并生成 `tModLoader.targets` → 安装 XNA → `dotnet build /p:Configuration=Release /p:WarningLevel=0` → `dotnet test --verbosity normal /p:WarningLevel=0`。 +- Maintain both `Sources/Everglow/Localization/en-US/` and `zh-Hans/`; `templates/` is not a content target. +- Content classes must override `LocalizationCategory` with `LocalizationUtils.Categories.*`. +- Do not manually create classification HJSON keys. Use the in-game `OutputLocalizationHjsonItem` exporter to add missing keys. Localization keys are additive: never delete them. +- Do not rename a content internal name without searching and updating all references, localization keys, `ItemID/NPCID.Search` uses, and compatibility implications. +- Do not add new content to the legacy root `Localization/en-US_Mods.Everglow.hjson`. -PR 前请在本地跑通同样的 build 与 test 命令。CI 无 lint/format 检查。 +## Tests and Verification -## 单元测试 +- Unit tests use MSTest 3.10.2 in `Sources/Everglow.UnitTests`; prefer pure logic tests. Function changes and tests require `dotnet test` after a successful build. +- Before a test first touches `Terraria.Main`, set `Program.SavePath = string.Empty;` in `[TestInitialize]`. Do not construct `Main`, start graphics/content loading, or run the game loop. Shared `Main` state means affected tests must not run in parallel. +- For `Player.talkNPC`, set the private property with reflection; do not call `SetTalkNPC`. +- Every code change requires `dotnet build`. Clearly state any tML runtime behavior that could not be verified locally. +- After text edits, run this byte-level UTF-8 BOM check against `origin/master`; do not substitute `git diff --check` or a text reader. -- 框架:**MSTest 3.10.2**(不是 xUnit/NUnit),测试项目 `Sources/Everglow.UnitTests`,仅引用 `Everglow.Function`(传递获得 Core 与 tML API)。该测试项目单独启用了 `enable`(主项目未启用)。 -- 运行:解决方案根目录 `dotnet test`。测试项目构建后自动把 `tModLoader.dll / FNA.dll / ReLogic.dll / SubworldLibrary.dll` 复制到输出目录(csproj 中 `CopyTModLoaderFiles` 目标),保证测试可加载 Terraria 类型。 -- 目录组织镜像被测项目:`Core/`(GraphicsUtils、MathUtils)、`Function/Physics/`、`Function/MissionSystem/`、`Function/UI/` 等;新增测试归入对应目录。 -- `TestResults/`(根目录及测试项目下)是 MSTest 部署输出,已 gitignore,不要提交。 -- **写测试的规则**: - - 首次触碰任何 `Terraria.Main` 静态成员前,必须在 `[TestInitialize]` 中执行 `Program.SavePath = string.Empty;`(防止静态构造读取存档配置抛异常,范例见 `UnitTest.cs`)。 - - 不要 `new Main()`,不要启动图形设备/内容加载/真实游戏循环;`Main.player`、`Main.npc` 是静态数组,直接填充槽位即可;`Main.LocalPlayer` 即 `Main.player[Main.myPlayer]`。 - - 共享静态状态意味着相关测试类需避免并行执行。 - - `Player.talkNPC` 是私有 setter,优先反射赋值,**不要**调用 `SetTalkNPC`(会触碰 ShopHelper 导致 NRE)。 - - 详细指引见 `.cursor/rules/unit-testing-terraria-main.mdc`,写涉及 `Main` 的测试前必读。 - - 优先测试纯逻辑(数学、物理、状态机、序列化);UI 绘制、贴图加载类不测。 - -## 架构 - -### 分层 - -``` -Everglow.Core 基础层:不引用 Terraria/tML(csproj 中显式 Remove),免疫 tML 更新 - ↓ 定义接口、DI 容器、模块系统、VFX 基元、工具类 -Everglow.Function 功能层:引用 tML,实现 Core 的接口 - ↓ 模板基类、VFX 管线、Hook、Netcode、Mechanics、UI 等 -Modules(14 个) 内容层:游戏内容(物品/NPC/弹幕/群系/事件…) - ↓ -Everglow(主项目) 装配层:引用全部项目、合并资源、产出 Everglow.tmod +```powershell +$base = git merge-base HEAD origin/master +$files = @((git -c core.quotepath=false diff --name-only --diff-filter=ACMRTUXB $base --) + (git -c core.quotepath=false ls-files --others --exclude-standard)) | Sort-Object -Unique +$bom = @($files | Where-Object { + if (-not (Test-Path -LiteralPath $_ -PathType Leaf)) { return $false } + $b = [IO.File]::ReadAllBytes($_) + $b.Length -ge 3 -and $b[0] -eq 0xEF -and $b[1] -eq 0xBB -and $b[2] -eq 0xBF +}) +if ($bom) { $bom | ForEach-Object { "UTF-8 BOM: $_" }; exit 1 } +"UTF-8 BOM check passed ($($files.Count) files)." ``` -- Core 与 Function 的 RootNamespace **均为 `Everglow.Commons`**。 -- **Core 禁止新增 tML 引用**;需要 tML 能力时,在 Core 定义接口、在 Function 实现,经 `Ins` 服务定位器取用。 - -### 主入口与启动流程 - -`Sources/Everglow/Everglow.cs` 的 `Load()`: - -1. `ModIns.Mod = this`(`Everglow.Function/ModIns.cs`:静态 Mod 引用 + `OnPostSetupContent`/`OnUnload` 事件 + `PacketResolver`)。 -2. `AddServices()`:向 `Ins`(`Everglow.Core/Ins.cs`,基于 `Microsoft.Extensions.DependencyInjection` 的静态服务定位器)注册单例:`Logger`、`IVisualQualityController`、`ModuleManager`、`IHookManager`、`IMainThreadContext`;**仅客户端**再注册 `GraphicsDevice`、`SpriteBatch`、`RenderTargetPool`、`IVFXManager`、`VFXBatch`(服务端 `IVFXManager` 注册为 `FakeManager`)。 -3. `AddContents()`:**跨程序集自动加载内容**——`Ins.ModuleManager.CreateInstances()` 注册配置;`CreateInstances()`(尊重 `[Autoload]`、排除 `ModGore`)把所有 `Everglow.*` 程序集中的 tML 内容类(ModItem/ModNPC/ModProjectile/ModTile/ModSystem…)逐一 `AddContent`。**无需也不应再手动 AddContent**。 -4. `PostSetupContent()`/`Unload()` 转发到 `ModIns`;`HandlePacket` 转发到 `ModIns.PacketResolver`。 - -### 模块系统 +## Agent Boundaries -**编译期**(MSBuild): -- 激活模块列表 = `Sources/Directory.Build.props` 的 `` 属性(分号分隔),同时注入 `DefineConstants`。 -- 每个模块自动引用 Core + Function + SubworldLibrary,`PathPrefix = 模块名`,并获全局 using(见「构建系统关键点」)。 -- **资源运行期路径规则**:`Everglow//<项目内相对路径>`。模块前缀即模块名(如 `Everglow/Myth/Effects/WaterDisortion`),`Everglow.Function` 的前缀是 `Commons`(`Everglow/Commons/...`)。 -- 每个项目源生成自己的 **`ModAsset`** 静态路径常量类:模块内写 `ModAsset.Xxx` 指**本模块**资源;引用公共库资源写 `Commons.ModAsset.Xxx`(即 `Everglow.Commons.ModAsset`)。优先使用 `ModAsset` 而非手写路径字符串。 +### Always -**运行期**(反射扫描): -- `Everglow.Core/Modules/ModuleManager.cs`:扫描 AppDomain 中所有名称以 `Everglow.` 开头的程序集(排除主程序集),实例化所有非抽象、`Condition == true` 的 `IModule` 并 `Load()`;卸载时 `Unload()`。 -- `IModule`(`Everglow.Core/Modules/IModule.cs`):`Code` / `Name` / `Condition` / `Load()` / `Unload()`;推荐继承抽象基类 **`EverglowModule`**(`Everglow.Function/Modules/EverglowModule.cs`,命名空间 `Everglow.Commons.Modules`)。 -- **`IModule` 是可选的**:只加物品/NPC 等内容类时不需要它(`AddContents()` 会自动注册)。需要挂 On_/IL_ 钩子、预加载 Effect、注册天空/事件时才写,参考 `Modules/Myth/MythModule.cs`、`Modules/Yggdrasil/YggdrasilModule.cs`。 -- `[ModuleHideType]`:标注的类不出现在 `ModuleManager.Types` 中(即不被 `CreateInstances()` 扫描到)。 -- `DependencyGraph`(同目录):类型级依赖拓扑排序工具。 +- Make the smallest focused patch, preserving unrelated user changes in a dirty worktree. +- Read the relevant implementation, nearby tests, and task-specific documentation before editing. +- Search the codebase for callers, implementations, and related patterns before editing. +- Verify changes in proportion to risk and report exact unverified behavior. -### 模块目录约定 +### Ask First -以 `Modules/Myth` 为范式:**先按主题/区域分子目录,再按 tML 内容类型分**: +- Any structural change to `Sources/Directory.Build.props`, a project file, the solution, module activation, or resource-packing configuration. +- Adding a dependency, renaming/deleting files or public content names, creating new art assets, or changing build/CI behavior. +- Any Git state change: branch creation, staging, commit, push, rebase, merge, or reset. -``` -Modules/Myth/ -├─ MythModule.cs IModule 入口(可选) -├─ TheFirefly/ 区域(群系):Items/ NPCs/ Projectiles/ Tiles/ Walls/ Buffs/ Dusts/ -│ Gores/ VFXs/ Backgrounds/ WorldGeneration/ Pylon/ … -├─ TheTusk/ LanternMoon/ Acytaea/ Misc/ 其他区域 -├─ Common/ 模块内共享代码(特效、管线) -├─ Effects/ .fx shader(自动编译) -├─ Sounds/ Music/ UIImages/ 纯资源目录 -└─ Everglow.Myth.csproj 通常为空壳 -``` - -- 命名空间:`Everglow.<模块名>[.<区域>[.<类型>]]`,如 `Everglow.Myth.TheFirefly.Items`。 -- 贴图/音效等资源与 .cs **同名同目录**。 -- `Modules/Example` 是官方示范模块,开发新内容前先参考它(示范 Items/Projectiles/Tiles/Pylon/Elevator/Skeleton/VFX/.fx 写法,大量继承 `Everglow.Commons.Templates` 模板类)。 - -### 新建模块步骤 - -1. 创建 `Sources/Modules//Everglow..csproj`(空壳即可,引用由 `Modules/Directory.Build.props` 自动注入)。 -2. 把 `` 加入 `Sources/Directory.Build.props` 的 `` 属性(并同步 CI workflow 中的覆盖段落)。 -3. 加入 `Everglow.sln`(可选但推荐)。 -4. 命名空间用 `Everglow.`;如需钩子/预加载则新建 `Module : EverglowModule`。 -5. 本地化键写入 `Sources/Everglow/Localization/{en-US,zh-Hans}/`(见「本地化」)。 - -### 模块依赖 - -- 所有模块 → `Everglow.Core` + `Everglow.Function` + `SubworldLibrary`(自动)。 -- 显式模块间依赖:`Myth → SpellAndSkull`;`Ocean → Myth`;`Yggdrasil → CagedDomain, Food, SpellAndSkull, SubSpace`。 -- 新增跨模块类型引用时必须在模块 csproj 中补 `ProjectReference`(不要依赖主项目传递引用"碰巧编译过")。 - -### 公共层速览 - -**Everglow.Core**(`Everglow.Commons.*`): - -| 目录/文件 | 内容 | -|---|---| -| `Ins.cs` | 服务定位器:`Ins.Batch`、`SpriteBatch`、`Device`、`HookManager`、`Logger`、`MainThread`、`ModuleManager`、`RenderTargetPool`、`VFXManager`、`VisualQuality`;`Ins.Add()`/`Get()` | -| `Modules/` | `IModule`、`ModuleManager`、`DependencyGraph`、`ModuleHideTypeAttribute` | -| `Interfaces/` | `IVisual`、`IVFXManager`、`IHookManager`/`IHookHandler`、`IMainThreadContext`、`IVisualQualityController` | -| `VFX/VFXBatch.cs` | 顶点批次绘制器(配合 `Vertex/` 的 Vertex2D/3D) | -| `ObjectPool/` | `RenderTargetPool`(RenderTarget2D 池) | -| `Coroutines/` | 协程(`CoroutineManager`、`WaitForFrames`…),常用于弹幕/VFX 时序 | -| `Utilities/` | `MathUtils` 系列、`GraphicsUtils`、`MathNetUtils` | - -**Everglow.Function**(`Everglow.Commons.*`,资源前缀 `Commons`): - -| 目录 | 内容 | -|---|---| -| `Templates/` | ★ 内容模板基类:`Clubs`、`StabbingSwords`、`Whips`、`Yoyos`、`Slingshots`、`TrailingProjectile`;`Furniture/` 全套家具 + 电梯;`Pylon`;`Enemies/`。**新武器/家具优先继承这些模板** | -| `VFX/` | `VFXManager`、`Pipeline`/`PostPipeline`、`Pipelines/`(Bloom/Warp/HeatMap…)、`Visuals/`(Particle、VisualNPC/Projectile…)、`Effects/`(.fx) | -| `Hooks/` | `HookManager`(经 `Ins.HookManager` 注册 On/IL hook) | -| `Netcode/` | `PacketResolver`、`IPacket`/`IPacketHandler`、内置 Packets | -| `Mechanics/` | `Mission/` 任务系统(含 README 与 CONTRACTS.md)、`Cooldown/`、`ElementalDebuff/`、`Events/` | -| `UI/`、`Menu/` | `EverglowUISystem`、Sidebar、`StringDrawer` 富文本;`EverglowModMenu` 主菜单 | -| `TileHelper/`、`CustomTiles/`、`Physics/` | TileAccessor、CableTile、MapIO;自研碰撞;MassSpring 质弹系统 | -| `Skeleton2D/`、`IIID/`、`MEAC/` | Spine 骨骼动画;Obj 模型渲染;MEAC 特效框架(注意:与废弃模块目录无关) | -| `FeatureFlags/` | `CompileTimeFeatureFlags`(编译期开关)、`EverglowConfig`(运行期) | -| `Localization/` | `ExportHjson` 等本地化导出工具(见「本地化」) | -| `DeveloperContent/` | 开发调试用物品 | - -### 关键 API 速查 - -```csharp -Ins.VFXManager.Add(myVisual); // 提交一个 IVisual 特效对象 -Ins.Batch.Begin(...)/Draw(...)/End(); // VFXBatch 顶点绘制 -Ins.HookManager / Ins.MainThread / Ins.Logger // 钩子 / 主线程调度 / 日志 -ModIns.Mod // 当前 Mod 实例 -public override string Texture => ModAsset.Xxx_Mod; // 本模块贴图(源生成常量) -Texture2D t = Commons.ModAsset.Trail_8.Value; // 公共库资源 -ModContent.Request("Everglow/<模块名>/Effects/Xxx"); // 手写路径时的前缀规则 -``` +### Never -## 代码规范 - -规则以根目录 `.editorconfig`(`root = true`)为准,全项目启用 `StyleCop.Analyzers.Unstable`(多数文档/排序类规则已关闭)。要点: - -- **Tab 缩进(宽度 4)、UTF-8(无 BOM)、文件末尾加新行**。文本文件默认使用 LF;为适配 Windows 上的 Visual Studio,`.sln` 与 `.csproj` 文件使用 CRLF。禁止把缩进改成空格。 -- **大括号 Allman 风格**(开括号独占一行);控制语句必须带大括号。 -- 命名:类型/方法/属性/事件/枚举 PascalCase;接口 `I` 前缀;私有字段 camelCase(跟随所在文件,不加 `_`/`m_` 前缀);常量 PascalCase。 -- namespace 用**文件作用域**形式(`namespace Everglow.Food.Items;`),新文件一律如此。 -- using:`System.*` 排最前、放 namespace 外;`var` 仅在类型从右值显而易见时使用。 -- `ImplicitUsings` + `LangVersion=preview` + 允许 unsafe;不要求 `this.`;未使用参数会产生 warning。 -- **模块项目已注入全局 using**(见「构建系统关键点」),在 `Sources/Modules/**` 下不要重复添加这些 using。 -- 主项目未启用 Nullable(仅 UnitTests 启用),不要在主项目新代码中大规模引入 `?` 注解风格。 -- 注释**跟随所在文件既有语言**(本仓库中英混用是现状);`Documents/` 与 Core 的 XML 注释多为中文。 -- 部分旧文件为非 UTF-8 编码(如 `.gitignore` 头部注释为 GBK),编辑时注意保留原编码,不要"修复"导致 diff 爆炸。 - -## tModLoader 开发约定 - -- **贴图路径**:不要手写路径字符串,用源生成的 `ModAsset.*` 常量(见「模块系统」)。**重名资源文件会导致 ModAsset 生成冲突**,资源文件名须(在生成范围内)唯一。 -- **本地化分类**:所有 `ModItem`/`ModNPC`/`ModProjectile`/`ModBuff`/`ModBiome` 应覆写 `LocalizationCategory`,取值用 `LocalizationUtils.Categories.*` 常量(如 `Categories.MeleeWeapons`),这是本地化导出工具正确归档的前提。 -- **ai 数组封装**:`NPC.ai[]`/`Projectile.ai[]` 不要散落魔数下标,用私有枚举 + 属性包装(范例:Myth 模块的 NPC 写法)。 -- **多人/网络**:自定义包走 `ModIns.PacketResolver`(`Everglow.Commons.Netcode`,实现 `IPacket`/`IPacketHandler`);状态变更记得 `netUpdate = true`;客户端专属逻辑(绘制、VFX、RenderTarget)必须 `!Main.dedServ` 守卫。 -- **基类优先**:新武器/家具优先继承 `Everglow.Commons.Templates` 的模板类(参考 Example 模块),不要从零实现已有模式。 -- **FeatureFlags**:实验性功能用 `CompileTimeFeatureFlags`(编译期)或 `EverglowConfig`(运行期)控制,不要直接提交常开的半成品功能。 -- 大文件用 `partial` 拆分;变体命名习惯用下划线后缀(如 `Stove_Item`、`TsunamiShark_missile`),跟随同模块惯例。 - -## 本地化 - -- 全部集中在 `Sources/Everglow/Localization/`:`en-US/`、`zh-Hans/`(正式语言,**两份都要维护**)与 `templates/`(模板,勿直接填内容)。 -- 文件按类别拆分:`Mods.Everglow.Items.Weapons.Melee.hjson`、`Mods.Everglow.NPCs.hjson`……内容类通过 `LocalizationCategory` 归入对应文件。 -- **不要手编分类 hjson 文件新增键**:用游戏内开发者物品 `OutputLocalizationHjsonItem`(源码在 `Sources/Everglow.Function/Localization/ExportHjson.cs`)运行导出,它会增量补齐缺失键(只加不删)。 -- **本地化键只增不删**;重命名内容类(internal name)会连锁破坏 hjson 键、`ItemID/NPCID.Search` 与存档兼容,必须全局搜索引用后再改。 -- 代码中取文本:`Language.GetTextValue("Mods.Everglow.Common.*")`;瓷砖地图名用 `this.GetLocalization("MapEntry" + option)`。 -- 仓库根的 `Localization/en-US_Mods.Everglow.hjson` 是旧格式残留,新内容不要往里加。 - -## 常见陷阱 - -- **CI 覆盖 `Sources/Directory.Build.props`**:改它必须同步 workflow(见「CI」)。 -- **CI 要求分支不落后 origin/master**:PR 前先同步 master。 -- `Sources/Everglow.Function/Test/*.*` 被 .gitignore 忽略——放在这里的内容不会入库,别误用。 -- 服务端没有图形服务(`SpriteBatch`/`Device`/`RenderTargetPool`/`VFXBatch` 等仅客户端注册),跨端代码注意 `Main.dedServ`。 -- `Modules/IIID`、`TwilightForest`、`ZY` 与 `Sources/Everglow.Scripts` 是废弃残留目录,不参与编译,**不要**在其中新增代码或"复活"它们(注意 `Everglow.Function` 内的 `IIID/`、`MEAC/` 命名空间目录是正常共享代码,与废弃模块无关)。 -- 模块资源没生效:先检查资源类型是否在 Pack 白名单内(见「构建系统关键点」)。 -- 构建报错 `Missing tModLoader.targets`:仓库上溯 5 级内缺少指向 tML 的 targets 文件(见「环境前置」)。 -- tML 升级后优先检查 `Everglow.Function` 的编译错误(Core 被隔离正是为此)。 - -## 提交与 PR 规范 - -- master 受保护:走分支 + PR,需其他开发者审查后合并。 -- 分支命名:`<模块名>/<简述>`(如 `Myth/newRope`、`common/npc_mission`、`hotfix/Localization`)。 -- 提交信息:简短英文祈使句;可用 Conventional Commits 前缀(`fix(Myth): …`、`chore(ci): …`)。 -- PR 前自查:`dotnet build` 与 `dotnet test` 本地通过;分支已同步最新 master;无二进制/生成物误入暂存区。 - -## Agent 行为准则 - -1. **最小改动**:修 bug 就修 bug,不顺手重构;不做与任务无关的批量格式化(历史文件风格混杂,批量格式化会造成巨大 diff,禁止)。 -2. **二进制/美术资源只读**:`Resources/`、`Libraries/`、各模块的 `.png/.obj/.ttf/.atlas/.xnb`、`Sources/Everglow/icon*.png`、`Tools/*.exe|dll` 一律不修改;需要新贴图时告知用户,不要生成图片占位。 -3. **结构性修改先确认**:`Sources/Directory.Build.props`、各 csproj、`Everglow.sln` 的结构性改动先向用户说明并确认。 -4. **不擅自 git 操作**:除非用户明确要求,不执行 commit/push/rebase 等任何 git 变更。 -5. **本地化键只增不删**;改 internal name 必须连带更新 hjson 与所有引用(见「本地化」)。 -6. **优先阅读再动手**:改动某模块/系统前,先看其目录下的 README/CONTRACTS/TODO(如 `Mechanics/Mission/`、`Modules/Food/FoodModule.md`)与 `Documents/` 下的中文文档。 -7. **验证**:改完必须 `dotnet build`;涉及 Function/UnitTests 逻辑时加 `dotnet test`。完成文本文件修改(尤其是批量重写)后,必须在仓库根目录运行以下 PowerShell,对相对 `origin/master` 的全部分支变更及未跟踪文件进行原始字节检查;成功时只输出汇总,失败时列出含 UTF-8 BOM(`EF BB BF`)的文件。不得以文本读取、`git diff --check` 或构建成功代替此检查,因为这些方式可能吞掉或忽略 BOM。 - - ```powershell - $base = git merge-base HEAD origin/master - $files = @((git -c core.quotepath=false diff --name-only --diff-filter=ACMRTUXB $base --) + (git -c core.quotepath=false ls-files --others --exclude-standard)) | Sort-Object -Unique - $bom = @($files | Where-Object { - if (-not (Test-Path -LiteralPath $_ -PathType Leaf)) { return $false } - $b = [IO.File]::ReadAllBytes($_) - $b.Length -ge 3 -and $b[0] -eq 0xEF -and $b[1] -eq 0xBB -and $b[2] -eq 0xBF - }) - if ($bom) { $bom | ForEach-Object { "UTF-8 BOM: $_" }; exit 1 } - "UTF-8 BOM check passed ($($files.Count) files)." - ``` - - 无法本地验证的 tML 运行时行为,在总结中明确说明未验证项。 -8. **不新建文档文件**(md 等),除非用户要求;代码自解释优先。 -9. 遇到构建/测试问题先查 `Documents/源代码编译流程.md` 与 `.cursor/rules/*.mdc`,再向用户提问。 - -## 参考文档索引 - -| 文档 | 内容 | -|---|---| -| `Documents/源代码编译流程.md` | 自定义构建管线详解 | -| `Documents/子世界.md`、`Documents/ILDoc/` | 子世界与 IL 修改文档 | -| `.cursor/rules/unit-testing-terraria-main.mdc` | 单元测试实施指南(写测试前必读) | -| `Sources/Everglow.Function/Mechanics/Mission/{README,CONTRACTS}.md` | Mission 任务系统契约 | -| `Sources/Everglow.Core/Utilities/Utils.md`、`Sources/Everglow.Function/VFX/VFX.md`、`Sources/Modules/Food/FoodModule.md` | 子系统文档 | -| `Sources/Modules/Example/` | 官方示范模块(新内容写法参考) | -| tModLoader 官方文档与 ExampleMod | tML API 用法的最终参考 | +- Modify binary/art assets, legacy/dead modules, generated output, or third-party libraries unless the user explicitly asks. +- Delete localization keys, broadly reformat files, introduce tML into Core, or use a manual `AddContent` registration for ordinary content. +- Use destructive Git commands or discard user changes without explicit instruction. diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..2db7abb83 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,39 @@ +# Code of Conduct + +## Our Commitment + +We want Everglow to be a welcoming, collaborative, and harassment-free community. Everyone who participates in our repository, issue tracker, pull requests, Discord server, and other official project spaces is expected to help create a respectful environment. + +## Expected Behavior + +- Treat people with empathy, respect, and good faith. +- Discuss ideas, code, and gameplay decisions constructively. +- Give and accept feedback with a focus on improving the project. +- Respect differing backgrounds, experience levels, identities, and viewpoints. +- Take responsibility for mistakes and help resolve their impact. + +## Unacceptable Behavior + +The following is not acceptable in project spaces: + +- Harassment, intimidation, threats, stalking, or unwanted sexual attention. +- Insults, slurs, discriminatory remarks, or personal and political attacks. +- Trolling, deliberately disruptive behavior, or sustained bad-faith discussion. +- Publishing another person's private information without explicit permission. +- Any conduct that a reasonable person would find hostile, unsafe, or unprofessional. + +## Scope + +This Code of Conduct applies in all official Everglow spaces, including GitHub and the Everglow Discord server. It also applies when someone publicly represents the project, such as through an official project account or a designated community role. + +## Reporting and Enforcement + +Report abusive, harassing, or otherwise unacceptable behavior by privately messaging the management team on the [Everglow Discord server](https://discord.gg/pdXvp89Dbp). Do not post sensitive reports or personal information in public channels. + +The management team will review reports promptly and fairly, share information only as needed to investigate and resolve the report, and aim to protect the reporter's privacy and safety. They may remove or reject comments, issues, pull requests, commits, or other contributions that violate this Code of Conduct. + +Depending on severity and prior conduct, enforcement may include a private correction, a warning with participation limits, a temporary ban, or a permanent ban from project spaces. Maintainers may communicate moderation decisions when appropriate, while respecting the privacy of the people involved. + +## Attribution + +This policy is informed by the [Contributor Covenant, version 2.1](https://www.contributor-covenant.org/version/2/1/code_of_conduct/), and its community-impact enforcement model. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..9632d472f --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,70 @@ +# Contributing to Everglow + +Thank you for helping improve Everglow. The project is a GPL-3.0 Terraria tModLoader mod built with C# and .NET 8. Contributions may include code, tests, documentation, localization, bug reports, and design discussion. + +## Before You Start + +- Search [existing issues](https://github.com/CycloneClub/Everglow/issues) before opening a new one. +- Open an issue or discuss the change with maintainers before investing in a large feature, a new module, a public content rename, a build-system change, or new art/audio assets. +- Keep one pull request focused on one problem. Avoid drive-by formatting changes or unrelated refactors. +- Read [AGENTS.md](AGENTS.md) for the repository map, architectural boundaries, resource rules, and task-specific documentation links. It is written for coding agents but documents project constraints that apply to every contribution. + +## Development Setup + +Everglow is developed on Windows. Before building, install: + +1. [.NET SDK 8.0 or later](https://dotnet.microsoft.com/download/dotnet/8.0). +2. A local [tModLoader](https://store.steampowered.com/app/1281930/tModLoader) installation. +3. The XNA runtime components used by tModLoader for Effect compilation. + +Clone the repository under tModLoader's `ModSources` directory. A `tModLoader.targets` file must exist in this repository or within one of its five parent directories and point to tML's `tMLMod.targets`. In the normal Windows layout, `ModSources/tModLoader.targets` supplies this link. + +Run commands from the repository root: + +```powershell +dotnet restore +dotnet build +dotnet test --verbosity normal /p:WarningLevel=0 +``` + +The CI-equivalent build is: + +```powershell +dotnet build /p:Configuration=Release /p:WarningLevel=0 +``` + +Do not use tModLoader's in-game **Build Mod** action for this repository. The MSBuild pipeline compiles the module assemblies, processes resources and Effects, and writes the combined `Everglow.tmod` to the local tModLoader Mods directory. + +## Making Changes + +- Place gameplay content in the appropriate active module below `Sources/Modules/`; do not add code to the retired `IIID`, `TwilightForest`, or `ZY` module directories. +- Preserve the layer boundary: `Everglow.Core` must not reference Terraria or tModLoader. Add tML-facing implementations in `Everglow.Function` instead. +- Follow `.editorconfig`: tab indentation, Allman braces, file-scoped namespaces, LF text files, UTF-8 without BOM, and a trailing newline. Keep `.sln` and `.csproj` files as CRLF. +- Prefer the existing templates in `Everglow.Function/Templates` and the examples in `Sources/Modules/Example/` when adding common tModLoader content types. +- Use generated `ModAsset` members for assets. Do not edit existing binary or art assets, including module textures, audio, atlases, fonts, compiled assets, `Resources/`, `Libraries/`, or tool binaries, unless a maintainer specifically requests it. +- Maintain both `Sources/Everglow/Localization/en-US/` and `zh-Hans/` for player-facing content. Do not delete localization keys. +- Treat changes to `Sources/Directory.Build.props`, project files, the solution, resource-packing rules, active modules, and CI as architectural changes; discuss them first. + +## Tests and Verification + +Run `dotnet build` for every code change. Run the full test command above when changing `Everglow.Function`, unit tests, or shared logic. For a focused test run: + +```powershell +dotnet test --filter "FullyQualifiedName~MissionSystem" +``` + +Tests use MSTest and live in `Sources/Everglow.UnitTests`. Terraria static state makes graphics-dependent tests unsuitable; favor pure logic tests. Before a test first accesses `Terraria.Main`, set `Program.SavePath = string.Empty;` in `[TestInitialize]`. See `.cursor/rules/unit-testing-terraria-main.mdc` before writing those tests. + +Before submitting text-file changes, ensure they contain no UTF-8 BOM. `AGENTS.md` contains the repository's required byte-level verification command. + +## Pull Requests + +- Branch from an up-to-date `master`; CI rejects branches that are behind `origin/master`. +- Use a concise English imperative commit message. Conventional Commit prefixes are welcome, for example `fix(Myth): correct projectile sync`. +- In the pull request, explain the problem, the chosen solution, and the verification you ran. Call out any client-only, server-only, multiplayer, or tML runtime behavior that you could not test locally. +- Do not commit generated `bin/`, `obj/`, `TestResults/`, unrelated binary files, credentials, or secrets. +- Be ready to respond to review feedback with small follow-up commits rather than rebasing away the discussion. + +## Getting Help and Discussing Ideas + +Use GitHub Issues for reproducible bugs and well-scoped feature proposals. Join the [Everglow Discord server](https://discord.gg/pdXvp89Dbp) for community discussion, early design feedback, or general tModLoader help. Please follow the [Code of Conduct](CODE_OF_CONDUCT.md) in all project spaces. diff --git a/README.md b/README.md index a15b3cc69..b9f36df92 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@
-Everglow +Everglow # Everglow @@ -10,7 +10,7 @@ Development in progress ✿✿ヽ(°▽°)ノ✿
- languages-top + languages-top
- license - commit + license + commit
- stars + stars
-## 📖 Documentation +## 🚀 Get Started -~~Work in progress.~~ 😭 +- [Installation guide](https://everglow.cloudea.work/docs/getting-started/installation) +- [Everglow Docs](https://everglow.cloudea.work/docs/getting-started/introduction) -## ⚙️ How do I build this? +## 🧩 Compatibility -If you wish to build the server yourself, follow these steps: +- Terraria 1.4.4.9 via tModLoader. +- Requires the tModLoader mod dependency [SubworldLibrary](https://github.com/jjohnsnaill/SubworldLibrary). -### Step 1 +## 🤝 Contributing -Get TModLoader from [Steam](https://store.steampowered.com/app/1281930/tModLoader) or [GitHub](https://github.com/tModLoader/tModLoader/releases). - -### Step 2 - -Install the [.NET 8.0 (or higher) SDK](https://dotnet.microsoft.com/download/dotnet/8.0) and [Visual Studio](https://visualstudio.microsoft.com/). -Make sure your SDK version is higher or equal to the required version. - -### Step 3 - -Clone the mod into `%userprofile%/Documents/My games/Terraria/tModLoader/ModSources`. - -Either use `git clone https://github.com/Solaestas/Everglow` on the command line to clone the repository or use Code --> Download zip button to get the files. - -### Step 4 - -To build Everglow, open a command prompt inside the project directory. -You can quickly access it on Windows by holding shift in File Explorer, then right clicking and selecting `Open command window here`. -Then type the following command: `dotnet build` build the built files will be found in the newly created build directory. +Please read [CONTRIBUTING.md](CONTRIBUTING.md) before submitting code, documentation, localization, or design changes. All community spaces follow the [Code of Conduct](CODE_OF_CONDUCT.md). ## 🎯 Support us -Feel free to dive in! [Open an issue](https://github.com/Solaestas/Everglow/issues/new) or submit PRs. +Feel free to dive in! [Open an issue](https://github.com/CycloneClub/Everglow/issues/new) or submit PRs. ## 📫 Get in touch If you would like to contact us or TML users, it's best to join our [Discord server](https://discord.gg/pdXvp89Dbp). To use Discord you will need to register a new account on [their website](https://discordapp.com/). ## 📑 License -All code of this repository is provided under the [GPL-3.0](https://github.com/Solaestas/Everglow/blob/master/LICENSE) license. -~~All of the art, audio, and other non-code assets belong to their respective owners and are used non-commercially either with a permission, a royalty-free license, or with various modifications & trust in the holiness of videogame modding. -No copyright infringements intended.~~ +All code of this repository is provided under the [GPL-3.0](https://github.com/CycloneClub/Everglow/blob/master/LICENSE) license. + +All of the art, audio, and other non-code assets belong to their respective owners and are used non-commercially either with a permission, a royalty-free license, or with various modifications & trust in the holiness of videogame modding. + +No copyright infringements intended. ## ❤️ Contributors + Thank you to the following contributors for helping improve the mod for everyone! - - + + diff --git a/Sources/Modules/Yggdrasil/AGENTS.md b/Sources/Modules/Yggdrasil/AGENTS.md new file mode 100644 index 000000000..934349206 --- /dev/null +++ b/Sources/Modules/Yggdrasil/AGENTS.md @@ -0,0 +1,54 @@ +# Yggdrasil Module Guidelines + +本文件适用于 `Sources/Modules/Yggdrasil/` 及其全部子目录,并补充根 `AGENTS.md`。Yggdrasil 是启用的内容模块,命名空间为 `Everglow.Yggdrasil`,资源前缀为 `Everglow/Yggdrasil`。 + +## Read Before Editing + +- `README.md`:天穹树关卡顺序与当前开发重点;目前重点是 Kelp Curtain(苍苔帘幕)。 +- `Everglow.Yggdrasil.csproj`:显式依赖 CagedDomain、Food、SpellAndSkull 和 SubSpace;新增跨模块类型引用必须在此加入对应 `ProjectReference`,并先获得用户确认。 +- `YggdrasilWorld.cs`、`YggdrasilModule.cs`:子世界入口、世界尺寸、全局钩子和渲染流程。 +- `Common/YggdrasilPlayer.cs` 与 `Netcode/`:玩家持久状态与同步模式。 +- 修改世界生成、后处理或贴图资源前,先阅读对应区域的现有实现和根指南中的资源约束。 + +## Module Map + +| 位置 | 责任 | +| --- | --- | +| `YggdrasilWorld.cs` | `Subworld` 定义、进入状态和世界尺寸/生成入口 | +| `YggdrasilModule.cs` | 客户端 Hook、地图着色、遮挡与后处理渲染 | +| `Common/` | 跨区域玩家、全局 NPC、内容和墙体逻辑 | +| `Netcode/` | 模块数据包与处理器 | +| `WorldGeneration/` | 天穹树世界、城镇与 Kelp Curtain 生成,以及 `.mapio`/噪声输入 | +| `YggdrasilTown/` | 城镇内容:生物群系、背景、家具、NPC、物品、投射物和 VFX | +| `KelpCurtain/` | 苍苔帘幕内容:群系、Tiles、NPC、物品、Buff、投射物和 VFX | +| `CorruptWormHive/`、`HurricaneMaze/`、`GreenCore/`、`CityOfMagicFlute/` | 其他已落地关卡区域 | +| `Effects/`、`Music/` | 模块 Effect 源文件与音乐资源 | + +将新内容放入所属关卡/区域及对应内容类型目录;不要把区域专属实现塞入 `Common/`。关卡名、资源和内部类型名是内容及存档兼容性的一部分,重命名之前必须全局搜索并征求确认。 + +## Subworld and Generation + +- 使用 `YggdrasilWorld.InYggdrasil` 或 `SubworldSystem.IsActive()` 判断天穹树上下文;不要以地图尺寸、坐标或场景效果替代该判断。 +- `YggdrasilWorld` 当前是 2000 × 21000、`ShouldSave => false` 的临时子世界。修改尺寸、保存策略、世界边界、进入/退出行为或 `Tasks` 属于结构性游戏行为,先获得用户确认。 +- 世界生成改动放在 `WorldGeneration/`,并保持 `YggdrasilWorldGeneration.YggdrasilWorldGenPass` 的既有入口。涉及 `.mapio`、`.bmp` 噪声或 JSON 的改动先确认资源打包和运行时加载路径。 +- 子世界专属 NPC 生成、背景、音乐、瓷砖和交互必须在正确的 `YggdrasilWorld`/`RoomWorld` 上下文中启用;新增逻辑不得意外影响主世界。 + +## Rendering and Effects + +- `YggdrasilModule.Load()` 中的 `FilterManager`、`On_`、`IL_` Hook 和 `RenderTarget2D` 工作仅可在 `!Main.dedServ` 条件内注册或使用。服务端不能访问图形服务。 +- `YggdrasilModule` 的 IL 注入依赖 tML 当前局部变量布局。改动匹配模式、注入点或升级 tML 后,必须保留明确的失败信息,并在客户端实际打开地图验证。 +- 需要经过该模块遮挡/特效流程的投射物实现 `IOcclusionProjectile`,并实现 `DrawOcclusion(VFXBatch)` 和 `DrawEffect(VFXBatch)`;绘制必须只依赖客户端可用状态。 +- 新 `.fx` 文件位于 `Effects/` 或所属区域的 `VFXs/`。全局构建属性会编译 Effect;修改 shader 后至少运行构建,并在客户端验证实际渲染。不要手改生成的 `.xnb`。 +- 继续使用模块的 `ModAsset` 路径成员;不要把同一资源以不同硬编码路径重复请求。 + +## Multiplayer and Persistent State + +- 自定义同步通过 `ModIns.PacketResolver`,使用 `IPacket`/`IPacketHandler` 和 `[HandlePacket]`。数据包读写顺序必须严格一致。 +- 玩家永久增益状态归 `Common/YggdrasilPlayer.cs` 与 `Netcode/PermanentBoostPacket.cs` 管理。新增持久字段须同时审查 `SaveData`、`LoadData`、`SyncPlayer`、`CopyClientState`、`SendClientChanges` 和数据包的 `Send`/`Receive`/handler。 +- NPC 或 Projectile 的权威状态变化应设置适当的 `netUpdate`,额外状态使用 `SendExtraAI`/`ReceiveExtraAI`。不要仅靠客户端视觉代码改变游戏状态。 + +## Resources and Verification + +- `.png`、`.ogg`/`.mp3`、`.fx`、`.mapio` 和 `.bmp` 均是只读美术/设计输入;除非用户明确要求,不修改它们,也不创建占位资源。 +- 此模块的 `.json` 通过项目文件中的 `Solaestas-ResourceFile` 包含;不要删除或扩展其范围而未确认结构性影响。 +- 修改本模块 C# 或 Effect 后,从仓库根运行 `dotnet build`。涉及网络、子世界、世界生成或渲染的行为不能由单元测试充分覆盖;在最终说明中分别列出已验证与未验证的客户端、服务端和多人行为。