YALootBoxes/CLAUDE_TASK.md
smthspec 354dfe34d5 Phase 1: rename audit complete (LootboxSpawner -> YALootBoxes)
- Renamed code prefix LB_ -> YALB_ across all four script files
- Renamed source files LootboxSpawner_*.c -> YALootBoxes_*.c
- Deleted three empty 0-byte stub files (_BoxTypes/_LootLists/_SpawnLocations)
- Fixed folder case scripts/4_world -> scripts/4_World to match config.cpp
- Verified box_types.json className values match CfgVehicles class names

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 21:27:38 +03:00

144 lines
No EOL
13 KiB
Markdown

# YALootBoxes — Polish, Verify, and Extend Logging
**Project root:** `P:\YALootBoxes`
**Context:** This is a DayZ server mod (Enforce Script). It was originally scaffolded under the name `LootboxSpawner` and has since been renamed to `YALootBoxes`. The mod spawns lockable lootboxes at config-defined locations; players need a specific held item to attempt opening one via a hold-to-open action; success unlocks+fills the box, failure rolls one random negative effect. All settings live in four JSON files under `$profile:YALootBoxes\`.
This is a **source-level review and polish pass**. There is no DayZ Server/Tools setup available yet, so do not attempt to pack a PBO or boot a server — focus on static correctness, consistency, and completeness of the Enforce Script source and JSON schemas.
Work through the phases below **in order**. Do not skip ahead. At the end of each phase, summarize what you found/changed before moving to the next.
---
## Phase 0 — Orientation
1. Recursively list all files under `P:\YALootBoxes`.
2. Read every `.c`, `.cpp`, and `.json` file you find.
3. Build a mental (or written, in scratch notes) map of: mod folder structure vs. the expected layout below, and flag any structural differences immediately.
**Expected layout:**
```
YALootBoxes/
├── config.cpp
├── Prefix.cpp
└── scripts/
└── 4_World/
├── YALootBoxes_Config.c
├── YALootBoxes_Lootbox.c
├── YALootBoxes_ActionOpen.c
└── YALootBoxes_Manager.c
```
(File names above assume the rename also touched filenames — verify and report actual names found, don't assume.)
---
## Phase 1 — Rename Audit (the user says rename "should" be complete — verify, don't trust)
Search the **entire** project for every leftover instance of the old naming scheme. Check ALL of:
- [ ] String `LootboxSpawner` (any casing) — in `.c`, `.cpp`, `.json`, comments, file names, folder names
- [ ] String `LB_` prefix on classes/functions/constants (e.g. `LB_Log`, `LB_MainConfig`, `LB_ConfigLoader`, `LB_BoxTypeDef`, `LB_FailEffect`, `LB_ActionOpenLootbox`, `LB_ApplyRandomFailEffect`, etc.) — decide on and apply a **consistent new prefix** (suggest `YLB_` or `YALB_`) if these were meant to be renamed too
- [ ] `CfgPatches` / `CfgMods` class name (`LootboxSpawner`) in `config.cpp`
- [ ] `CfgVehicles` class names (`LootboxSpawner_Crate_Military`, `_Medical`, `_Industrial`) — these **must** exactly match the `className` fields inside `box_types.json`, so check both sides together
- [ ] `$profile:LootboxSpawner\` path constant — should become `$profile:YALootBoxes\`
- [ ] Any `displayName` strings, log prefixes (`Print("[LootboxSpawner] ...")`), or code comments referencing the old name
- [ ] `Prefix.cpp` content itself
**Action:** Fix every occurrence found. Keep a running checklist in your response of exactly what was renamed, file by file, so the user can review the diff. Do not silently rename things — call out each change.
**Cross-check after renaming:** confirm `box_types.json`'s `className` values still exactly match the `CfgVehicles` class names in `config.cpp` post-rename (this is the #1 way these mods silently fail to spawn anything — a one-character mismatch and the server just won't spawn the object, often without an obvious error).
---
## Phase 2 — Structural / Completeness Review
Go file by file and check for the following. This codebase was written without ever being compiled against the real DayZ SDK headers, so treat it as a first draft that needs adversarial review, not a finished product.
### General Enforce Script correctness
- [ ] Confirm every class that's referenced is actually defined somewhere (no dangling references to types that don't exist, e.g. double check `ContinuousInteractActionInput`, `ActionContinuousBase`, `CCINone`, `CCTObject`, `UAMaxDistances` are real DayZ API symbols available in the modding SDK — if you have access to DayZ SDK docs/headers via web search, verify; otherwise flag as "needs verification against SDK" rather than assuming correctness)
- [ ] Check `RegisterNetSyncVariableBool` usage — confirm sync var registration pattern matches how `ContainerObject`/`ItemBase` subclasses normally do it in DayZ mods
- [ ] Check for null-safety: every place a JSON-loaded reference (`m_TypeDef`, `LB_ConfigLoader.MainConfig`, etc.) is used, confirm there's a null check or a guaranteed-non-null path
- [ ] Check `GetActions()` override signature/pattern is correct for hooking custom actions onto a `ContainerObject`-derived class — this was a best-effort implementation and deserves scrutiny
- [ ] Verify `eAgents` enum members used (`SALMONELLA`, `INFLUENZA`, `CHOLERA`, `BRAIN`, `WOUND_AGENT`) are the real DayZ agent enum names
- [ ] Verify `GetBleedingManagerServer()`, `GetHealthDamageManager()`, `SetFracture()`, `InsertAgent()` are real PlayerBase/HealthDamageManager API calls and used with correct signatures
### Config loading
- [ ] Confirm `JsonFileLoader<T>.JsonLoadFile` / `JsonSaveFile` usage matches real DayZ API (class name and static usage pattern)
- [ ] Confirm the `map<string, ref array<ref LB_LootEntry>>` (or renamed equivalent) is a supported Enforce Script generic — DayZ's Enforce Script has known limitations with nested generic containers in JSON deserialization. **This is a likely problem area** — flag clearly if you believe `JsonFileLoader` cannot deserialize a `map<string, array<...>>` directly. If so, propose a fix: e.g. restructure `loot_lists.json` as an array of `{type, entries}` objects instead of a map, since flat arrays deserialize far more reliably in Enforce Script's JSON layer.
- [ ] Check that `EnsureDirectoryExists` / `MakeDirectory` calls match the real API (case, return type)
- [ ] Confirm default-object construction (e.g. `LB_MainConfig()` constructor) actually runs before `JsonLoadFile` overwrites fields, so a partially-specified JSON file doesn't leave other fields zero/null
### Lifecycle & manager logic
- [ ] Re-derive the despawn timer logic by hand against the user's original spec: locked boxes despawn/respawn after N minutes (config-driven per box type) **even if never opened**; opened boxes despawn N minutes after becoming unlocked. Confirm `HasExpiredUnopened` / `HasExpiredAfterOpening` actually implement this without overlap or gaps.
- [ ] Check for a race/edge case: what happens if a box is mid-open-action (channeling) at the exact moment the lifecycle tick deletes it for expiring? Flag this as a known edge case if not already handled, and propose a minimal guard (e.g. skip despawn-delete if an action is actively targeting it, or just accept and document the rare edge case).
- [ ] Check `CallLater(..., true)` repeating-timer usage is correct DayZ API usage (3rd param = repeat flag, confirm order of args).
- [ ] Verify location pool logic (`m_FreeLocationNames`, `m_LocationInUse`) doesn't have an off-by-one or duplicate-assignment bug when `SpawnOneAtRandomFreeLocation` recurses on failure.
### Action / interaction logic
- [ ] Confirm the "fixed channel time, instant roll, but failure can interrupt early" requirement is actually satisfiable with `ActionContinuousBase` + `OnFinishProgressServer` — i.e. confirm that bailing out early (releasing the button) does NOT call `OnFinishProgressServer` and does NOT roll anything. Flag if the current code doesn't clearly guarantee this.
- [ ] Confirm the proximity message system (manager's `TickProximityMessages`) and the action's "show prompt when holding right item" are not redundant/conflicting — i.e. one always shows "Requires: X", the other only enables the action — and that nothing in the action class duplicates the proximity broadcast.
- [ ] Verify `RPCSingleParam` / `ERPCs.RPC_USER_ACTION_MESSAGE` is a real, appropriate way to send a HUD text message to a single client in DayZ's API. If this is not correct, propose the standard pattern used by DayZ mods for "send toast/notification to one player" (often a custom RPC type registered in `Init.c`/`Missions`, since `RPC_USER_ACTION_MESSAGE` may not exist or may not behave as a generic toast).
### Config/JSON schema consistency
- [ ] Confirm every field referenced in `.c` files has a matching field (same name, same casing) in the example JSON files, and vice versa.
- [ ] Confirm `failEffects[].chance` semantics are documented clearly as "weight" not "independent probability" (since the code does a weighted pick among effects, not N independent rolls) — fix any comment/naming that implies otherwise.
Produce a written list of every issue found in this phase, categorized as:
- 🔴 **Will likely fail to compile or run** (must fix)
- 🟡 **Will likely behave incorrectly at runtime** (should fix)
- 🟢 **Style/maintainability nit** (optional)
Fix all 🔴 and 🟡 items. For 🟢 items, list them but ask before changing anything purely stylistic.
---
## Phase 3 — Add Debug Logging Levels
Extend the logging system to support **NONE / ERROR / WARN / INFO / DEBUG / VERBOSE** levels, replacing the current single `EnableDebugLogging: bool`.
### Requirements:
1. In the main config class, replace `EnableDebugLogging` (bool) with `DebugLogLevel` (string or int — your call, but document which and why; string is more admin-friendly for hand-editing JSON, int is cheaper to compare at runtime — consider storing as string in JSON but parsing to an int enum at load time for fast comparisons).
2. Define the level ordering: `NONE(0) < ERROR(1) < WARN(2) < INFO(3) < DEBUG(4) < VERBOSE(5)`. A message at level X is printed only if `DebugLogLevel >= X`.
3. Replace the single `LB_Log(string msg)` (or renamed equivalent) helper with level-specific variants, e.g.:
- `Log_Error(string msg)`
- `Log_Warn(string msg)`
- `Log_Info(string msg)`
- `Log_Debug(string msg)`
- `Log_Verbose(string msg)`
Each should prefix output appropriately, e.g. `[YALootBoxes][ERROR] ...`, and route to both `Print()` (.log/.rpt via engine default) and, if straightforward, `ErrorEx()` for ERROR-level messages specifically (DayZ's standard pattern for messages that should be prominent in the `.RPT` file) — verify `ErrorEx` is real API before using it; if uncertain, just use `Print()` consistently and note the limitation.
4. Go through **every existing log call in the codebase** and reclassify it to the correct level based on its actual content:
- Config file missing / failed to parse / unknown class referenced → `ERROR` or `WARN` depending on whether it's recoverable
- "Spawned box at location X", "Manager initialized" → `INFO`
- Per-tick lifecycle summaries ("removed N, active now M") → `DEBUG`
- Per-player proximity message sends, per-effect-roll details → `VERBOSE`
5. Update the example `main_config.json` to use the new field with a sensible default (`INFO` recommended for normal server operation).
6. Update the default-constructor fallback value to match.
Add a short section to the project's README (create one at `P:\YALootBoxes\README.md` if it doesn't exist) documenting:
- What each log level is meant to be used for
- The config field name and JSON example
- A reminder that VERBOSE will be noisy and is meant for active debugging sessions only, not production
---
## Phase 4 — Final Consistency Pass
1. Re-read every file once more, top to bottom, now that renaming and logging changes have landed, specifically checking that:
- No file still calls the old single-arg `LB_Log(...)` (or its renamed equivalent) — every call site should now use a leveled function
- No JSON file and `.c` file have drifted out of sync on field names again as a side effect of your edits
- All four JSON example files are valid JSON (mentally parse them, or note if you want to validate via a tool)
2. Produce a final summary report with these sections:
- **Renames applied** (file-by-file list)
- **Bugs fixed** (🔴 and 🟡 items from Phase 2, with before/after description)
- **Known limitations / things that need real DayZ SDK to verify** (be explicit — this matters since nothing has been compiled yet)
- **Logging system** (what changed, default level, example config)
- **Suggested next steps** for the user once they have DayZ Tools available (e.g. "pack PBO, boot test server, spawn near a military crate empty-handed, confirm proximity message text, pick up a crowbar, confirm action prompt appears, hold to open, confirm one of the two outcomes fires correctly")
---
## Ground rules throughout
- **Do not invent DayZ API behavior you're not confident about.** If you can't verify something against real SDK docs/headers, say so explicitly in the summary rather than presenting a guess as fact. This is real game-server code the user intends to run.
- **Do not silently delete functionality.** If you think something should be removed (e.g. a redundant message path), propose it and explain why before removing it, in your phase summary.
- **Keep commit-sized changes traceable** — if this is a git repo, make small logical commits per phase rather than one giant diff; if it's not a git repo, mention that initializing one would make this kind of iterative work much easier to review going forward.
- This is **review + polish + logging**, not a redesign. Don't change the core mechanics (proximity message always shown, fixed-channel hold-to-open, weighted single fail-effect roll, post-open despawn timer) unless you find them to be actually broken as currently spec'd — flag concerns rather than unilaterally redesigning.