From 8c53747c3c43ad9bfba29f91baadf310531bf336 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=88=AA=E5=91=B3=E9=BA=BB=E9=85=B1?= <93972760+TaranDahl@users.noreply.github.com> Date: Fri, 8 May 2026 17:09:12 +0800 Subject: [PATCH 1/2] Update copilot-instructions.md --- .../SKILL.md" | 130 ++++++++++++++++++ .../SKILL.md" | 124 +++++++++++++++++ 2 files changed, 254 insertions(+) create mode 100644 ".trae/skills/\346\222\260\345\206\231\346\226\207\346\241\243-write-documentation/SKILL.md" create mode 100644 ".trae/skills/\347\224\237\346\210\220ini\346\240\207\347\255\276-generate-ini-tag/SKILL.md" diff --git "a/.trae/skills/\346\222\260\345\206\231\346\226\207\346\241\243-write-documentation/SKILL.md" "b/.trae/skills/\346\222\260\345\206\231\346\226\207\346\241\243-write-documentation/SKILL.md" new file mode 100644 index 0000000000..984e79c4c6 --- /dev/null +++ "b/.trae/skills/\346\222\260\345\206\231\346\226\207\346\241\243-write-documentation/SKILL.md" @@ -0,0 +1,130 @@ +--- +name: 撰写文档 Write Documentation +description: "### Write Documentation\n\nThis command is invoked when the code changes for a feature or bugfix are complete on a branch (branched from `develop`) and documentation is the only remaining task. The AI should discover what changed, categorize it, and write the appropriate documentation entries." +--- + +#### Workflow + +**Step 0: Determine the author** + +Use `git log develop...HEAD --format="%an <%ae>"` to list commits on the current branch that are not in `develop`. If the branch has extra commits, use the author name(s) from those commits as the user's identity for `CREDITS.md` and `Whats-New.md`. If there are no extra commits or the author cannot be determined from commit information, ask the user directly for their identity before proceeding. + +**Step 1: Discover what changed** + +Run `git diff develop...HEAD --stat` to see which files were modified. Then inspect the diffs in detail using `git diff develop...HEAD` (or `git diff develop...HEAD -- `) to understand the nature of each change. Key things to identify: +- New/changed INI keys (tags) — look for `.Read(exINI, ...)` calls in `LoadFromINIFile` / `LoadBeforeTypeData` etc. +- New/changed hooks — look for `DEFINE_HOOK`, `DEFINE_JUMP`, `DEFINE_PATCH` macros. +- New types/classes — look for new files in `src/New/` or new `ExtData` classes. +- Whether the change is a new feature, an enhancement of existing behavior, a bugfix, a UI change, an AI/scripting change, or something miscellaneous. + +**Step 2: Categorize the change** + +Determine which doc pages need updating: + +| Change type | Where to document | +|-------------|------------------| +| New feature (brand new functionality) | New `### ` section in the appropriate primary doc page, inserted in **dictionary (alphabetical) order** among existing sibling `### ` headings | +| Enhancement of existing game behavior that adds new INI tags | New `### ` section in the appropriate primary doc page, likewise in alphabetical order | +| Enhancement/bugfix of existing game behavior with **no new INI tags** | A bullet point under `## Bugfixes and miscellaneous` in `docs/Fixed-or-Improved-Logics.md` | +| User interface change (new hotkey, display, sidebar, tooltip) | `docs/User-Interface.md` | +| AI, scripting, trigger, or mapping change | `docs/AI-Scripting-and-Mapping.md` | +| Uncategorized change | `docs/Miscellanous.md` | +| New user setting in RA2MD.INI | `docs/Whats-New.md` (under "New user settings") | + +Primary doc page mapping: +- Most game logic features → `docs/New-or-Enhanced-Logics.md` + - Within this file, `## ` headings are categories (e.g., `## Buildings`, `## Projectiles`, `## Warheads`). Place new `### ` sections under the appropriate category, sorted alphabetically. + +Additionally, every non-trivial change requires: +- **`docs/Whats-New.md`** — changelog entry. +- **`CREDITS.md`** — credit the author. + +**Step 3: Draft the documentation text — user review required before writing** + +Before writing any documentation, draft the descriptive text and present it to the user for review. Use the following format for the draft: + +``` +### + +- + - (tab-indented) controls/determines/is used for . +``` + +Two styles for the first bullet point: +- **New feature** (brand new functionality): + ``` + - Now you can . (新功能) + ``` +- **Enhancement of existing behavior** (patches/improves vanilla logic): + ``` + - In vanilla, . Now you can . + ``` + +Wait for the user to approve the drafted text before proceeding to write it into the actual doc files. + +**Step 4: Write the main documentation** + +After user approval, write the approved text into the appropriate doc file. For sections in `docs/New-or-Enhanced-Logics.md` or similar, insert the new `### ` section in alphabetical order among existing sibling headings under the correct `## ` category. Look at existing sibling `### ` headings to determine the correct insertion point. + +Continue with the INI code block following existing conventions: + +```markdown +In `rulesmd.ini`: +```ini +[SECTION] ; ObjectType +KeyName=default ; accepted type +KeyName.WithDots=default ; accepted type with optional explanation +``` +``` + +Key rules for INI documentation: +- Use ` ```ini ` fenced code blocks. +- Section header comment format: `[SOMENAME]` followed by spaces then `; ObjectType` (e.g., `; BuildingType`, `; TechnoType`, `; WarheadType`, `; SuperWeaponType`). +- For global sections use the literal section name: `[General]`, `[AudioVisual]`, `[CombatDamage]`, `[Radiation]`, `[AI]`, etc. +- Key name, equals sign, default value (or blank if empty), spaces, semicolon, type description. +- Boolean types are documented as `; boolean`. +- Integer types as `; integer`. +- Floating point types as `; double` or `; float`. +- Pointer types as `; AnimType` (just the game class name, not full C++ type). +- List types as `; list of TechnoType` etc. +- If the INI key name contains dots, it maps naturally (e.g. `KeyName.SubKey` stays as-is in docs). + +When there are many related keys, group them logically within the same section and INI block. Put them in the order they appear in the INI section. + +**Step 5: Chinese translation** + +After the English documentation has been written and confirmed, produce a Chinese translation of the new section(s). Present the Chinese text to the user for review and confirmation. Update the corresponding `.po` files in `docs/locale/zh_CN/LC_MESSAGES/` after the user approves the translation. + +**Step 6: Write `docs/Whats-New.md` entry** + +Whats-New entries go under the `### Version TBD (develop branch nightly builds)` section. Use the author identity determined in Step 0. The entry should be a bullet point briefly describing the change and how it might affect existing mods: + +```markdown +- (by ) +``` + +If new INI keys are user-facing settings in `RA2MD.INI`, also add them under the `### New user settings in RA2MD.INI` section: +```ini +[Phobos] +NewKeyName=true ; boolean +``` + +If INI keys were renamed, add entries under `### Changed tags` using the format seen in existing entries: +```markdown +- `[Section] -> OldName` -> `[Section] -> NewName` +``` + +**Step 7: Write `CREDITS.md` entry** + +Use the author identity determined in Step 0. Find the author's section in `CREDITS.md`. If the author doesn't have a section yet, create one. Add a bullet describing the contribution: + +```markdown +- **AuthorName (GitHubUsername)**: + - Feature description matching the phrasing used in other entries +``` + +Do not skip the CREDITS entry unless the user explicitly says to skip it. + +**Step 8: Review and confirm** + +After writing all entries, present a summary to the user showing which files were modified and what was added. diff --git "a/.trae/skills/\347\224\237\346\210\220ini\346\240\207\347\255\276-generate-ini-tag/SKILL.md" "b/.trae/skills/\347\224\237\346\210\220ini\346\240\207\347\255\276-generate-ini-tag/SKILL.md" new file mode 100644 index 0000000000..bf0ba6e469 --- /dev/null +++ "b/.trae/skills/\347\224\237\346\210\220ini\346\240\207\347\255\276-generate-ini-tag/SKILL.md" @@ -0,0 +1,124 @@ +--- +name: 生成INI标签 Generate INI tag +description: "A \"tag\" is an INI key that generally corresponds to a C++ property. Defining a tag requires modifications in four places within the target `ExtData` class: **declaration**, **initialization**, **serialization**, and **INI loading**. If the user does not provide all information explicitly, the AI should infer the missing pieces, present them to the user for confirmation, and only proceed after approval." +--- + +#### 1. Determine the Class + +Game entities have **instance classes** (e.g., `BuildingClass`) and **static type classes** (e.g., `BuildingTypeClass`). Tags are almost always defined in the static type class's `ExtData` — when the user says "add a tag for buildings", they mean `BuildingTypeExt::ExtData`. Same pattern applies: + +| User says | Corresponding ExtData | +|-----------|----------------------| +| Building / BuildingType | `BuildingTypeExt::ExtData` | +| Vehicle / Unit / UnitType | `UnitTypeExt::ExtData` (or `TechnoTypeExt::ExtData`) | +| Infantry / InfantryType | `InfantryTypeClass` → `TechnoTypeExt::ExtData` | +| Aircraft / AircraftType | `AircraftTypeClass` → `TechnoTypeExt::ExtData` | +| Warhead | `WarheadTypeExt::ExtData` | +| Weapon | `WeaponTypeExt::ExtData` | +| Bullet / Projectile | `BulletTypeExt::ExtData` | +| SuperWeapon / SW | `SWTypeExt::ExtData` | +| Animation / Anim | `AnimTypeExt::ExtData` | +| Particle | `ParticleTypeExt::ExtData` | +| Terrain / TerrainType | `TerrainTypeExt::ExtData` | +| Overlay / OverlayType | `OverlayTypeExt::ExtData` | +| Global / Rules | `RulesExt::ExtData` | + +Note: `TechnoTypeExt::ExtData` is the **common base class** extension for `BuildingType`, `UnitType`, `InfantryType`, and `AircraftType`. If a tag applies to all Techno types, place it in `TechnoTypeExt`; if it applies only to a specific subtype, place it in the corresponding subclass Ext (e.g., buildings only → `BuildingTypeExt`). + +#### 2. Determine the Section + +- **Non-global tags**: Read from `pSection` (the INI section matching the instance ID/name) inside `LoadFromINIFile`. Determine whether to use `pSection` or `pArtSection`: + - `pSection` = `pThis->ID` — reads from the identically-named section in `rulesmd.ini`. The vast majority of tags go here. + - `pArtSection` = `pThis->ImageFile` — reads from the identically-named section in `artmd.ini`, using `INI_Art` / `exArtINI`. Generally used for visual, graphical, or animation-related tags. Check whether the class's `LoadFromINIFile` defines a `pArtSection` variable and `exArtINI` to see if this is supported. +- **Global tags**: For `RulesExt::ExtData`, read from fixed global sections such as `GameStrings::General` (`[General]`), `GameStrings::CombatDamage` (`[CombatDamage]`), `GameStrings::Radiation` (`[Radiation]`), `GameStrings::AudioVisual` (`[AudioVisual]`), `GameStrings::AI` (`[AI]`), etc. Infer the appropriate section based on the key name's semantics. + +#### 3. Determine the Key Name + +The INI key name specified by the user. **Critical conversion rule: dots `.` in the key name become underscores `_` in the C++ property name.** + +For example: `"Factory.IsSuper"` → C++ property name `Factory_IsSuper` + +#### 4. Determine the Type + +Infer the C++ type based on semantics. Common types and their wrappers: + +| Semantics | C++ Type | Wrapper | +|-----------|---------|---------| +| Boolean on/off switch | `bool` | `Valueable` | +| Integer (count, frames, int percentage) | `int` | `Valueable` | +| Floating point (ratio, multiplier, speed) | `double` | `Valueable` | +| In-game distance (Lepton) | `Leptons` | `Valueable` | +| Coordinate | `CoordStruct` / `Point2D` | `Valueable` | +| Color | `ColorStruct` | `Valueable` | +| Nullable (omitting means use default logic) | any | `Nullable` | +| List (comma-separated values) | `std::vector` | `ValueableVector` | +| Pointer to another game type | `WeaponTypeClass*` etc. | `Valueable` | +| Index lookup (sounds etc.) | see `ValueableIdx` | `ValueableIdx` | +| Enum | game enum | `Valueable` etc. | + +**Inference rules:** +- Key name contains `Is`/`Can`/`Allow`/`Use`/`Has`/`Enable`/`Disable` → likely `Valueable` +- Key name contains `Amount`/`Count`/`Max`/`Min`/`Delay`/`Rate`/`Frame` (integer) → likely `Valueable` +- Key name contains `Factor`/`Mult`/`Percent`/`Speed`/`Ratio`/`Chance` → likely `Valueable` +- Key name contains `Type` (singular pointer) → `Valueable` +- Key name contains `Types` (plural) → `ValueableVector` +- When unsure about optionality, default to `Valueable` (required); use `Nullable` if omitting is semantically valid. + +#### 5. Implementation Steps + +Modify the `Body.h` and `Body.cpp` of the target ExtData. Follow these four steps: + +**A. Declare the property (Body.h → ExtData public section)** + +Follow existing declaration style, e.g.: +```cpp +Valueable Factory_IsSuper; +``` + +**B. Initialize the property (Body.h → ExtData constructor initializer list)** + +Add a default value in the constructor, matching the existing format (comma-first, aligned): +```cpp +, Factory_IsSuper { false } +``` + +**C. Register in serialization (Body.cpp → Serialize function)** + +Insert into the `Stm` chain in `Serialize(T& Stm)`, ordered alphabetically or logically: +```cpp +.Process(this->Factory_IsSuper) +``` + +**D. INI loading (Body.cpp → LoadFromINIFile function)** + +Based on the section determined in step 2, choose `exINI` or `exArtINI`, and `pSection` or `pArtSection`: +```cpp +// From rulesmd.ini (most common) +this->Factory_IsSuper.Read(exINI, pSection, "Factory.IsSuper"); + +// From artmd.ini (visual/graphical) +this->Factory_IsSuper.Read(exArtINI, pArtSection, "Factory.IsSuper"); + +// Global tag example (RulesExt) +this->Factory_IsSuper.Read(exINI, GameStrings::General, "Factory.IsSuper"); +``` + +If the property is a pointer to another game type (e.g., `Valueable`), use `.Read` to enable auto-creation: +```cpp +this->SomeWeapon.Read(exINI, pSection, "SomeWeapon"); +``` + +#### 6. Full Example + +User says: "add a tag called `Factory.IsSuper` for buildings" + +Inference process: +- Class: `BuildingTypeExt::ExtData` ("buildings" → building type static data) +- Section: `pSection` (not visual-related) +- Key: `Factory.IsSuper` → property name `Factory_IsSuper` +- Type: `Valueable` (contains `Is`, boolean semantics) +- Default: `false` (conservative default) + +After confirmation, modify: +- [Body.h](file:///f:/RA2%20Engine%20Extension/MJobos/src/Ext/BuildingType/Body.h): declaration + initialization +- [Body.cpp](file:///f:/RA2%20Engine%20Extension/MJobos/src/Ext/BuildingType/Body.cpp): Serialize + LoadFromINIFile \ No newline at end of file From 0a584c878c294d240c2142b0f679ee13da6f0cb9 Mon Sep 17 00:00:00 2001 From: Noble Fish <89088785+DeathFishAtEase@users.noreply.github.com> Date: Fri, 8 May 2026 22:09:39 +0800 Subject: [PATCH 2/2] fix format --- .../SKILL.md" | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git "a/.trae/skills/\346\222\260\345\206\231\346\226\207\346\241\243-write-documentation/SKILL.md" "b/.trae/skills/\346\222\260\345\206\231\346\226\207\346\241\243-write-documentation/SKILL.md" index 984e79c4c6..6f99eead76 100644 --- "a/.trae/skills/\346\222\260\345\206\231\346\226\207\346\241\243-write-documentation/SKILL.md" +++ "b/.trae/skills/\346\222\260\345\206\231\346\226\207\346\241\243-write-documentation/SKILL.md" @@ -68,14 +68,14 @@ After user approval, write the approved text into the appropriate doc file. For Continue with the INI code block following existing conventions: -```markdown +````markdown In `rulesmd.ini`: ```ini [SECTION] ; ObjectType KeyName=default ; accepted type KeyName.WithDots=default ; accepted type with optional explanation ``` -``` +```` Key rules for INI documentation: - Use ` ```ini ` fenced code blocks.