From d195bdd14e7f4605a0fc1b8effa03ba490d3fba6 Mon Sep 17 00:00:00 2001 From: wuwenbo Date: Thu, 11 Jun 2026 11:45:52 +0800 Subject: [PATCH] Add TH1 base engineering skill --- .codex/skills/th1-base/SKILL.md | 175 ++++++++++++++++++++++++++++++++ AGENTS.md | 2 + 2 files changed, 177 insertions(+) create mode 100644 .codex/skills/th1-base/SKILL.md diff --git a/.codex/skills/th1-base/SKILL.md b/.codex/skills/th1-base/SKILL.md new file mode 100644 index 000000000..a6c10b3ba --- /dev/null +++ b/.codex/skills/th1-base/SKILL.md @@ -0,0 +1,175 @@ +--- +name: th1-base +description: TH1 project baseline engineering guide for Unity client changes: assembly boundaries, HybridCLR hotfix rules, YooAsset/AssetBundle resource rules, MemoryPack/AOT serialization safety, build packaging flow, and routing to domain skills. Use before broad TH1 Unity code/resource/build changes, especially when touching Scripts, asmdefs, HybridCLR, hotfix DLLs, StreamingAssets, BundleResources, Resources.Load replacement, YooAsset, MemoryPack, generated config, build panels, or package verification. +--- + +# TH1 Base Engineering + +## Core Rule + +Treat TH1 as a hot-update Unity project with a small AOT shell, a large `TH1.Hotfix` gameplay layer, and YooAsset-managed resources. + +Most feature work may live in hotfix code, but platform bootstrap, HybridCLR/YooAsset initialization, AOT metadata loading, and build packaging must remain stable and boring. Do not solve a hotfix/AOT/resource issue with one-off special cases when a shared entrypoint or generator fix is possible. + +## Skill Routing + +Start here for baseline constraints, then add the domain skill that owns the behavior: + +- `th1-ios-migration`: iOS/IL2CPP, HybridCLR, YooAsset, Steam platform isolation, touch/mobile, packaging. +- `th1-action-logic`: gameplay actions, AI action flow, turn state, replay, deterministic skill side effects. +- `th1-network-sync`: Steam lobby/P2P, GameStart/ForceUpdate, `MapData` network payloads, multiplayer resume. +- `th1-game-archive`: local save/load, `GameRecord`, archive files, resume, bug report archive payloads. +- `th1-multilingual`: localization export/import, `Multilingual.asset`, Workshop language mods. +- `th1-server-backend`: OSS/STS/function compute/upload/auth backend work. +- `th1-online-debug`: production logs, CrashSight/UnityLogError, obfuscated stack decode. +- `th1-crashsight-daily`: daily CrashSight triage and reports. +- `.agents/skills/th1-config-guide`: Excel config generation, `GenerateCS`/`ExcelPartial`, MemoryPack config rules. +- `.agents/skills/th1-ui-patterns`: View/Controller UI work. +- `.agents/skills/th1-ai-nodes`: NodeCanvas AI behavior tree nodes. +- `.agents/skills/th1-anim-scope`: attack animation scope-aware renderer updates. + +If multiple skills apply, use this skill first, then the narrow domain skill. + +## First Moves + +- Run `git status --short`; preserve unrelated user/Unity changes. +- Identify whether the change touches AOT shell, hotfix code, resources/AB, serialization, build pipeline, platform services, or gameplay behavior. +- For Unity code changes, inspect nearby asmdefs and namespace ownership before moving files. +- For generated files, find and update the generator/template instead of hand-editing output, unless the user explicitly asks for a one-off generated output patch. +- Do not modify MemoryPack compatibility, obfuscation behavior, or generated config formats without explicit confirmation. + +## Assembly Boundaries + +Current target shape: + +- AOT shell: minimal startup scene and bootstrap code. It loads AOT metadata, loads `TH1.Hotfix.dll.bytes`, initializes YooAsset, loads the game scene, then invokes hotfix entrypoints. +- `TH1.Hotfix`: gameplay logic, UI logic, renderer logic, config consumers, AI nodes, save/game/archive logic where possible. +- `TH1_Resource`: resource facade and compatibility wrappers. Gameplay code should load through these wrappers, not direct YooAsset calls scattered everywhere. +- Editor assemblies: build panels, HybridCLR/YooAsset tools, config/export windows. They must not leak into runtime/hotfix assemblies. + +Rules: + +- The Build Settings scene should be the empty/init AOT shell scene. The real game scene is loaded through YooAsset after hotfix and metadata are ready. +- Do not put hotfix `MonoBehaviour` references directly in the shell scene. +- If a prefab/scene contains hotfix scripts, it must be loaded only after the hotfix assembly is loaded. +- Keep startup contracts stable and explicit. Prefer direct typed calls for required runtime packages over reflection that silently skips failures. +- Hotfix code must not directly reference editor-only assemblies or platform-specific SDKs that are unavailable on the target platform. + +## HybridCLR Rules + +- After hotfix code, AOT dependency, or generic-heavy serialization changes, rerun the HybridCLR prepare flow before packaging. +- Required artifacts are platform-specific: hotfix DLL bytes and AOT metadata under `StreamingAssets/HybridCLR`. +- Load supplemental metadata before starting hotfix gameplay: + - `mscorlib.dll.bytes` + - `System.dll.bytes` + - `System.Core.dll.bytes` + - `MemoryPack.dll.bytes` + - `System.Runtime.CompilerServices.Unsafe.dll.bytes` +- Use `HybridCLR.RuntimeApi.LoadMetadataForAOTAssembly(..., HomologousImageMode.SuperSet)` for the required load path; do not hide missing RuntimeApi as a non-fatal reflection miss in player builds. +- Do not manually copy stale hotfix DLLs. Use the project build panel/command so generated DLL, AOT metadata, and build status stay consistent. +- If NodeCanvas/ParadoxNotion serialized task types are moved into hotfix, refresh/regenerate the relevant type metadata before packaging. + +## MemoryPack And AOT Serialization + +MemoryPack format compatibility is high risk. Preserve layout unless explicitly changing format. + +Runtime/hotfix code should avoid direct generic MemoryPack entrypoints when the serialized type may live in hotfix: + +```csharp +// Prefer project wrapper or Type API. +TH1Serialization.Serialize(value); +TH1Serialization.Deserialize(bytes); + +MemoryPackSerializer.Serialize(typeof(T), value); +MemoryPackSerializer.Deserialize(typeof(T), bytes); +``` + +Avoid adding new runtime code like: + +```csharp +MemoryPackSerializer.Serialize(value); +MemoryPackSerializer.Deserialize(bytes); +``` + +Rules: + +- Use `TH1_Logic.Tools.TH1Serialization` for gameplay/save/network/runtime data. +- For generators that cannot reference Unity runtime code, generate MemoryPack `Type` API calls. +- Do not reorder or remove existing `[MemoryPackInclude]` members in persisted/networked types. Append new fields. +- For old fields no longer used, keep compatibility placeholders when later fields would shift. +- Treat `MapData`, `NetData`, `GameRecord`, `GameRecordData`, config bytes, and network messages as compatibility-sensitive. +- If generated config code needs a change, update `ExcelExport/ExportTemplate_*.txt` and regenerate/sync output. + +## YooAsset And AB Rules + +Resources are moving to AB-first loading: + +- Use `Assets/BundleResources` as the packaged resource root. +- Prefer stable logical addresses. Do not make gameplay code depend on platform-specific bundle paths. +- Replace `Resources.Load` through `TH1Resource.ResourceLoader`/resource cache wrappers, not scattered direct YooAsset calls. +- Editor may run simulate mode; PC/iOS packages should run actual built-in AB package logic. +- Rebuild YooAsset bundles after moving, adding, deleting, or renaming packaged assets. +- Keep Standalone and iOS bundles separate. Do not reuse PC bundle assumptions for iOS compression or platform output. +- Do not put invalid source files in AB roots: backups (`*.BAK`), raw local-only config, editor-only files, or unknown icon/temp files should live outside `BundleResources`. +- If an address is missing, fix the collector/address/generator path rather than adding local `Resources` fallbacks. + +## Build And Packaging Flow + +For migration-era PC IL2CPP smoke builds, use the project one-click flow where possible: + +1. Configure target platform/build settings. +2. Configure HybridCLR. +3. Run HybridCLR `GenerateAll`. +4. Build hotfix DLL and copy hotfix/AOT metadata to `StreamingAssets`. +5. Build YooAsset built-in `DefaultPackage`. +6. Build Windows IL2CPP player. +7. Launch player and scan the log for startup red errors. + +Manual Unity packaging gotchas: + +- After scene list changes, use full `Build`/`Clean Build`; do not use `Build Scripts Only`. +- If you only need a runnable PC package, keep `Create Visual Studio Solution` off unless explicitly debugging the generated solution. +- Avoid `Script Debugging` for automated smoke player runs; it can wait for a managed debugger. +- If Unity exports a Visual Studio solution for IL2CPP, MSBuild may need current Windows SDK/toolset retargeting. +- Generated build artifacts such as `HybridCLRGenerate/AOTGenericReferences.cs` may change after HybridCLR GenerateAll; commit them only when intentionally refreshed. +- Obfuscator logs and local build output should not be committed unless explicitly part of the requested change. + +Startup smoke success markers: + +- AOT metadata logs show `OK`. +- `TH1.Hotfix` loads. +- YooAsset `DefaultPackage` initializes. +- Game scene loads from YooAsset. +- Hotfix `Main` starts. +- No `MissingMethodException`, `Type Request Error`, `NullReferenceException`, or `LogError` during startup. + +## Verification + +For ordinary Unity runtime C#: + +```powershell +dotnet build Unity/Assembly-CSharp.csproj --no-restore +``` + +For editor/build/config tooling: + +```powershell +dotnet build Unity/Assembly-CSharp-Editor.csproj --no-restore +``` + +Known caveat: this repo can hit Unity package compile errors outside changed code when building the full editor csproj from dotnet. If that happens, report it clearly and verify the narrower runtime/tool project or Unity Editor compile path instead. + +For config generator changes: + +```powershell +dotnet run --project ExcelExport/ExcelExport.csproj -- 1 +dotnet build ExcelExport/ExcelExport.csproj --no-restore +``` + +Before finishing migration/build work, inspect: + +```powershell +rg -n "Resources\\.Load|MemoryPackSerializer\\.Serialize<|MemoryPackSerializer\\.Deserialize<|using Steamworks|BuildScriptsOnly" Unity/Assets/Scripts +``` + +Only treat matches as problems after checking context; editor-only tools and intentionally platform-bound Steam implementations may be valid. diff --git a/AGENTS.md b/AGENTS.md index e32c5fbbb..02fe07943 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -7,6 +7,7 @@ This repository is a Unity 2022.3 LTS / ET Framework turn-based strategy game. T - For architecture questions, read the `MD/GameMDFramework/00-*` overview document and the relevant subsystem document before editing. - For code navigation, read `Unity/graphify-out/GRAPH_REPORT.md` for Unity code and `graphify-out/GRAPH_REPORT.md` for whole-repository context. - If a task touches action execution, networking, localization, online errors, backend upload, or CrashSight reports, use the matching `.codex/skills/th1-*` skill first. +- For broad TH1 Unity/code/resource/build changes, use `.codex/skills/th1-base` first, then layer the narrower business skill on top. - Claude-era context remains in `.claude/` and `Unity/Assets/Scripts/CLAUDE.md`; treat it as historical source material, not the active entrypoint. ## Project Shape @@ -36,6 +37,7 @@ This repository is a Unity 2022.3 LTS / ET Framework turn-based strategy game. T ## Codex Skills And Agents - Prefer `.codex/skills` for current project-specific workflows: + - `th1-base`: baseline Unity engineering rules for assembly boundaries, HybridCLR hotfix, YooAsset/AB, MemoryPack/AOT serialization, generated config, and build/package verification. - `th1-action-logic`: action execution, AI action flow, turn actions, and action-triggered skills. - `th1-network-sync`: Steam lobby, P2P, multiplayer save/recovery, action sync, and deterministic network behavior. - `th1-multilingual`: localization import/export, active text scanning, duplicate IDs, and translation diagnostics.