Optimize CLAUDE.md from 240 to 63 lines
Remove detailed reflection patterns (belong in code comments), project status tracking, completed features list, and implementation approach docs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
d3d3b998c3
commit
44fd044541
251
CLAUDE.md
251
CLAUDE.md
@ -1,239 +1,62 @@
|
||||
# CLAUDE.md
|
||||
# EfD Trading Card Mod
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
Unity mod for Escape from Duckov adding a customizable trading card system with storage.
|
||||
|
||||
## Project Overview
|
||||
|
||||
A Unity mod for Escape from Duckov that adds a customizable trading card system with storage solutions. The framework supports user-generated content through simple pipe-separated text files, allowing non-programmers to add their own card sets.
|
||||
|
||||
## Build Commands
|
||||
## Commands
|
||||
|
||||
```bash
|
||||
# Build the mod
|
||||
dotnet build TradingCardMod.csproj
|
||||
|
||||
# Build release version
|
||||
dotnet build TradingCardMod.csproj -c Release
|
||||
|
||||
# Output location: bin/Debug/netstandard2.1/TradingCardMod.dll
|
||||
dotnet build TradingCardMod.csproj # Build (debug)
|
||||
dotnet build TradingCardMod.csproj -c Release # Build (release)
|
||||
dotnet test TradingCardMod.Tests.csproj # Run tests
|
||||
./deploy.sh # Build + deploy to game
|
||||
./deploy.sh --release # Deploy release build
|
||||
./remove.sh # Remove mod from game
|
||||
```
|
||||
|
||||
**Important**: Before building, update `DuckovPath` in `TradingCardMod.csproj` (line 10) to your actual game installation path.
|
||||
|
||||
## Deployment
|
||||
|
||||
```bash
|
||||
# Deploy to game (builds and copies all files)
|
||||
./deploy.sh
|
||||
|
||||
# Deploy release build
|
||||
./deploy.sh --release
|
||||
|
||||
# Remove mod from game
|
||||
./remove.sh
|
||||
|
||||
# Remove with backup
|
||||
./remove.sh --backup
|
||||
```
|
||||
**Before building**: Update `DuckovPath` in `TradingCardMod.csproj` (line 10) to your game path.
|
||||
|
||||
## Project Skills
|
||||
|
||||
Two workflow skills are available in this project:
|
||||
|
||||
- `/build` - Build and deploy locally for testing (runs `dotnet build` + `./deploy.sh`)
|
||||
- `/deploy` - Build Release and stage for Steam Workshop upload (uses `workshop-upload.sh`)
|
||||
|
||||
Skills are defined in `.claude/skills/`.
|
||||
|
||||
## Testing
|
||||
|
||||
```bash
|
||||
# Run all unit tests
|
||||
dotnet test TradingCardMod.Tests.csproj
|
||||
|
||||
# Run tests with verbose output
|
||||
dotnet test TradingCardMod.Tests.csproj --verbosity normal
|
||||
|
||||
# Run specific test class
|
||||
dotnet test TradingCardMod.Tests.csproj --filter "FullyQualifiedName~CardParserTests"
|
||||
|
||||
# Run single test
|
||||
dotnet test TradingCardMod.Tests.csproj --filter "ParseLine_ValidLineWithoutDescription_ReturnsCard"
|
||||
```
|
||||
|
||||
**Test Coverage:** Parsing logic, validation, rarity mapping, TypeID generation, and description auto-generation are all tested. Unity-dependent code (item creation, tags) cannot be unit tested.
|
||||
- `/build` — Build and deploy locally for testing
|
||||
- `/deploy` — Build Release and stage for Steam Workshop upload
|
||||
|
||||
## Architecture
|
||||
|
||||
### Mod Loading System
|
||||
|
||||
The game loads mods from `Duckov_Data/Mods/`. Each mod requires:
|
||||
- A DLL with namespace matching `info.ini`'s `name` field
|
||||
- A `ModBehaviour` class inheriting from `Duckov.Modding.ModBehaviour`
|
||||
- The `info.ini` and `preview.png` files
|
||||
- **Clone + Reflection**: Clone game items as templates (base ID 135), set private fields via reflection
|
||||
- **Custom tags**: Clone existing ScriptableObject tags. Parent tag pattern for slot filtering (Unity requireTags uses AND logic)
|
||||
- **TypeIDs**: 100000+ range to avoid game/mod conflicts
|
||||
- **Cost struct reflection**: Cost is a value type — must box before reflection, then unbox (see `DisassemblyHelper.cs`)
|
||||
|
||||
### Key Classes
|
||||
|
||||
- **`ModBehaviour`** (`src/ModBehaviour.cs`): Main entry point. Inherits from `Duckov.Modding.ModBehaviour` (which extends `MonoBehaviour`). Handles card set loading in `Start()` and cleanup in `OnDestroy()`.
|
||||
|
||||
- **`Patches`** (`src/Patches.cs`): Harmony patch definitions. Uses `HarmonyLib` for runtime method patching. Patches are applied in `Start()` and removed in `OnDestroy()`.
|
||||
|
||||
- **`TradingCard`** (`src/TradingCard.cs`): Data class representing card properties. Contains `GenerateTypeID()` for creating unique item IDs (100000+ range to avoid game conflicts).
|
||||
|
||||
- **`CardParser`** (`src/CardParser.cs`): Parses card definition files. Pure C# with no Unity dependencies, fully unit tested.
|
||||
|
||||
- **`ItemExtensions`** (`src/ItemExtensions.cs`): Reflection helpers for setting private fields on game objects.
|
||||
|
||||
- **`TagHelper`** (`src/TagHelper.cs`): Utilities for working with game tags, including creating custom tags.
|
||||
|
||||
- **`PackUsageBehavior`** (`src/PackUsageBehavior.cs`): Handles card pack opening mechanics. Implements gacha-style random card distribution based on rarity weights.
|
||||
|
||||
- **`ModConfigApi`** (`src/ModConfigApi.cs`): Optional integration with ModConfig mod. Adds card set information (set name, card number, rarity) to item descriptions in inventory. Also displays mod statistics including disabled card sets count.
|
||||
|
||||
- **`StorageHelper`** (`src/StorageHelper.cs`): Helper class for creating storage items with multi-tag slot filtering, enabling hierarchical storage systems.
|
||||
|
||||
- **`DisassemblyHelper`** (`src/DisassemblyHelper.cs`): Helper class for adding disassembly (deconstruction) formulas to custom items at runtime.
|
||||
|
||||
### Disassembly System Pattern
|
||||
|
||||
The game's disassembly system uses `DecomposeDatabase` (singleton in `Duckov.Economy` namespace) to store formulas. Key implementation details:
|
||||
|
||||
**Types:**
|
||||
- `DecomposeFormula`: Contains `item` (TypeID), `valid` (bool), and `result` (Cost)
|
||||
- `Cost`: A **struct** with `money` (long) and `items` (ItemEntry[])
|
||||
- `Cost+ItemEntry`: **Nested struct** inside Cost with `id` (int) and `amount` (long)
|
||||
|
||||
**Critical Reflection Pattern (Cost is a struct):**
|
||||
```csharp
|
||||
// Cost is a VALUE TYPE - must box before reflection, then unbox
|
||||
Cost result = new Cost { money = 0L };
|
||||
object boxedResult = result; // Box the struct
|
||||
itemsField.SetValue(boxedResult, itemEntries); // Modify boxed copy
|
||||
result = (Cost)boxedResult; // Unbox back
|
||||
formula.result = result;
|
||||
```
|
||||
|
||||
**Adding a Formula:**
|
||||
1. Get `DecomposeDatabase.Instance`
|
||||
2. Access private `entries` field via reflection
|
||||
3. Create `DecomposeFormula` with item TypeID and `valid = true`
|
||||
4. Create `Cost` with money and/or items array
|
||||
5. For items: Create `Cost+ItemEntry[]` via reflection (type found from `Cost.items` field type)
|
||||
6. Add formula to list, write back via reflection
|
||||
7. Call private `RebuildDictionary()` method
|
||||
|
||||
**Known Material TypeIDs:**
|
||||
- Polyethylene Sheet: `764`
|
||||
|
||||
**Cleanup:** Track added item IDs and remove formulas in `OnDestroy()`.
|
||||
|
||||
See `DisassemblyHelper.cs` for complete implementation.
|
||||
| Class | Role |
|
||||
|-------|------|
|
||||
| `ModBehaviour` | Entry point, card set loading/cleanup |
|
||||
| `Patches` | Harmony runtime method patches |
|
||||
| `CardParser` | Pipe-separated card file parser (pure C#, fully tested) |
|
||||
| `PackUsageBehavior` | Card pack opening with gacha-style rarity weights |
|
||||
| `StorageHelper` | Multi-tag slot filtering for hierarchical storage |
|
||||
| `DisassemblyHelper` | Runtime disassembly formulas via reflection |
|
||||
|
||||
### Dependencies
|
||||
- **HarmonyLoadMod** (Workshop 3589088839): Required — provides Harmony 2.4.1
|
||||
- **ModConfig** (Workshop 3592433938): Optional — enhances card descriptions in inventory
|
||||
|
||||
- **HarmonyLoadMod** (Workshop ID: 3589088839): Required mod dependency providing Harmony 2.4.1. Referenced at build time but not bundled to avoid version conflicts.
|
||||
## Card Sets
|
||||
|
||||
- **ModConfig** (Workshop ID: 3592433938): Optional mod dependency. When installed, enhances card descriptions with set information in the inventory UI.
|
||||
|
||||
### Card Definition Format
|
||||
|
||||
Cards are defined in `CardSets/{SetName}/cards.txt` using pipe-separated values:
|
||||
Cards defined in `CardSets/{SetName}/cards.txt`:
|
||||
```
|
||||
CardName | SetName | SetNumber | ImageFile | Rarity | Weight | Value | Description (optional)
|
||||
```
|
||||
Images in `CardSets/{SetName}/images/`. Prefix folder with `_` to disable loading.
|
||||
|
||||
The Description field is optional. If provided, it will be displayed in the item's in-game description/tooltip.
|
||||
## Storage System
|
||||
|
||||
Images go in `CardSets/{SetName}/images/`.
|
||||
- **Binder Sheet** (9 slots): Holds trading cards only
|
||||
- **Card Binder** (12 slots): Holds cards OR binder sheets (nested storage)
|
||||
|
||||
**Disabling Card Sets:** Prefix a card set folder name with `_` (underscore) to exclude it from loading. For example, `_TestSet/` will be skipped. This is useful for work-in-progress sets or seasonal content. The count of disabled sets is displayed in ModConfig.
|
||||
## Dev Notes
|
||||
|
||||
## Game API Reference
|
||||
|
||||
Key namespaces and APIs from the game:
|
||||
- `ItemStatsSystem.ItemAssetsCollection.AddDynamicEntry(Item prefab)` - Register custom items
|
||||
- `ItemStatsSystem.ItemAssetsCollection.RemoveDynamicEntry(Item prefab)` - Remove on unload
|
||||
- `SodaCraft.Localizations.LocalizationManager.SetOverrideText(string key, string value)` - Localization
|
||||
- `ItemStatsSystem.ItemUtilities.SendToPlayer(Item item)` - Give items to player
|
||||
|
||||
## Development Notes
|
||||
|
||||
- Target framework: .NET Standard 2.1
|
||||
- C# language version: 8.0
|
||||
- All logging uses `Debug.Log()` with `[TradingCardMod]` prefix
|
||||
- Custom items need unique TypeIDs to avoid conflicts with base game and other mods
|
||||
|
||||
## Testing
|
||||
|
||||
1. Copy build output to `{GamePath}/Duckov_Data/Mods/TradingCardMod/`
|
||||
2. Include: `TradingCardMod.dll`, `info.ini`, `preview.png`, `CardSets/` folder
|
||||
3. Launch game and enable mod in Mods menu
|
||||
4. Check game logs for `[TradingCardMod]` messages
|
||||
|
||||
## Current Project Status
|
||||
|
||||
**Phase:** 3 - Storage System ✅
|
||||
**Status:** Ready for first release
|
||||
**Project Plan:** `.claude/scratchpad/PROJECT_PLAN.md`
|
||||
**Technical Analysis:** `.claude/scratchpad/item-system-analysis.md`
|
||||
|
||||
### Completed Features
|
||||
|
||||
- Cards load from `CardSets/*/cards.txt` files with optional descriptions
|
||||
- Custom PNG images display as item icons
|
||||
- Cards register as game items with proper TypeIDs
|
||||
- Custom tags for slot filtering:
|
||||
- "TradingCard": Identifies trading cards
|
||||
- "BinderSheet": Identifies binder sheet items
|
||||
- "CardBinderContent": Parent tag for both cards and binder sheets (enables hierarchical storage)
|
||||
- Hierarchical storage system:
|
||||
- **Binder Sheet** (9 slots, weight 0.1): Holds trading cards only
|
||||
- **Card Binder** (12 slots, weight 1.5): Holds trading cards OR binder sheets
|
||||
- Nested storage: Cards → Binder Sheets → Card Binders
|
||||
- Card set exclusion: Prefix folders with `_` to disable loading
|
||||
- ModConfig integration:
|
||||
- Enhanced card info display (set name, number, rarity)
|
||||
- Mod statistics display (total cards, disabled sets)
|
||||
- Debug spawn window with F10 key (for testing):
|
||||
- Spawn storage items (Card Binder, Binder Sheet)
|
||||
- Spawn random cards by rarity
|
||||
- Draggable OnGUI window interface
|
||||
- Disassembly support for storage items:
|
||||
- Binder Sheet → 2x Polyethylene Sheet
|
||||
- Card Binder → 4x Polyethylene Sheet
|
||||
- Cards intentionally have no disassembly (collectibles)
|
||||
- Deploy/remove scripts for quick iteration
|
||||
- Unit tests for parsing logic
|
||||
|
||||
### Implementation Approach: Clone + Reflection
|
||||
|
||||
Based on analysis of the AdditionalCollectibles mod:
|
||||
|
||||
1. **Clone existing game items** as templates (base item ID 135)
|
||||
2. **Use reflection** to set private fields (typeID, weight, value, etc.)
|
||||
3. **Create custom tags** by cloning existing ScriptableObject tags
|
||||
4. **Parent tag pattern** for slot filtering (Unity's requireTags uses AND logic, so parent tags enable OR-like behavior)
|
||||
5. **Load sprites** from user files in `CardSets/*/images/`
|
||||
6. **Attach custom behaviors** for pack opening mechanics
|
||||
|
||||
### Upcoming Features
|
||||
|
||||
- **Card packs** with gacha-style mechanics (weighted random distribution) - disabled pending fix
|
||||
- Additional storage variants or customization options (e.g., larger binders, themed storage boxes)
|
||||
|
||||
### Future Considerations
|
||||
|
||||
- Investigate new ItemBuilder API (added in recent game update) as potential replacement for reflection-based approach
|
||||
|
||||
### Log File Location
|
||||
|
||||
Unity logs (for debugging):
|
||||
```
|
||||
/mnt/NV2/SteamLibrary/steamapps/compatdata/3167020/pfx/drive_c/users/steamuser/AppData/LocalLow/TeamSoda/Duckov/Player.log
|
||||
```
|
||||
|
||||
## Research References
|
||||
|
||||
- **Decompiled game code:** `.claude/scratchpad/decompiled/`
|
||||
- **Item system analysis:** `.claude/scratchpad/item-system-analysis.md`
|
||||
- **AdditionalCollectibles mod:** Workshop ID 3591453758 (reference implementation)
|
||||
- Target: .NET Standard 2.1, C# 8.0
|
||||
- Logging: `Debug.Log()` with `[TradingCardMod]` prefix
|
||||
- Log file: `/mnt/NV2/SteamLibrary/steamapps/compatdata/3167020/pfx/drive_c/users/steamuser/AppData/LocalLow/TeamSoda/Duckov/Player.log`
|
||||
- Research: `.claude/scratchpad/decompiled/`, `.claude/scratchpad/item-system-analysis.md`
|
||||
|
||||
Loading…
Reference in New Issue
Block a user