Files
ik-codex/docs/superpowers/specs/2026-04-30-pz-analysers-pvp-admin-design.md
indifferentketchup b99d8f3061 docs: backfill Phase B.2 spec and plan
Retroactive design + plan documentation for Phase B.2 (PvP combat
detection plus six admin verb-dispatch insight classes), reconstructed
from chat history and git log. Mirrors the shape of the existing
Phase B.1 docs. Plan is as-built with checkboxes pre-checked and
commit SHAs referenced inline; Deviations section captures the
90c85a0 brace-fix interlude.
2026-05-01 12:51:26 +00:00

6.7 KiB

ProjectZomboid analyser design (Phase B.2)

Retroactive: written 2026-05-01.

Summary

Add Project Zomboid PvP combat detection (filtering zombie hits and zero-damage events) and admin verb-dispatch coverage of six action types, by registering seven new Information insight classes onto the existing PatternAnalyser. No custom Analyser subclasses are introduced in this phase — all dispatch fits within PatternAnalyser's per-entry pattern matching.

This document covers Phase B.2. Phase B.1 is in 2026-04-30-pz-analysers-design.md. Phase B.3 (cross-entry / threshold analysers requiring custom Analyser subclasses) is in 2026-04-30-pz-analysers-deferred-design.md.

Scope

  • In scope: PvpDamageInformation + PvpPattern::COMBAT_REAL regex; six Admin<Verb>Information classes + six AdminPattern::<VERB>_ENTRY regex constants; wiring ProjectZomboidPvpLog::getDefaultAnalyser() and ProjectZomboidAdminLog::getDefaultAnalyser(); end-to-end tests for both logs.
  • Out of scope (B.2): any cross-entry / threshold / pairing logic (deferred to B.3); the eight other PZ logs whose getDefaultAnalyser() continues returning an empty PatternAnalyser stub; the codex-side Redactor utility (deferred — see 2026-04-30-redactor-design.md).

Architectural decision: vanilla PatternAnalyser

Phase B.1 established that PatternAnalyser plus Insight::isEqual() coalescing covers single-entry pattern matching cleanly. Phase B.2's analysers (PvP damage rows, admin verb lines) all fit that mould — each interesting line is independent of the others, dispatch is per-entry, and counter-coalescing handles repeats. No Analyser subclassing required. (Phase B.3 will deviate from this when cross-entry logic enters the picture.)

Components

All under src/Analysis/ProjectZomboid/:

Class Type Pattern Coalescing
PvpDamageInformation Information PvpPattern::COMBAT_REAL Default Information::isEqual (label + value) — same attacker/victim/weapon coalesces
AdminAddedItemInformation Information AdminPattern::ADDED_ITEM_ENTRY Default — same admin/item/target coalesces
AdminAddedXpInformation Information AdminPattern::ADDED_XP_ENTRY Default — same admin/amount/skill/target coalesces
AdminGrantedAccessInformation Information AdminPattern::GRANTED_ACCESS_ENTRY Default — same admin/level/target coalesces
AdminChangedOptionInformation Information AdminPattern::CHANGED_OPTION_ENTRY Default — same admin/option/value coalesces
AdminReloadedOptionsInformation Information AdminPattern::RELOADED_OPTIONS_ENTRY Default — same admin coalesces
AdminTeleportedInformation Information AdminPattern::TELEPORTED_ENTRY Default — same admin/target/coords coalesces

Patterns

Seven new constants total.

PvpPattern::COMBAT_REAL — combat regex with the noise filter baked in. The negative lookahead (?!zombie") rejects zombie weapon rows; the damage clause uses alternation to match only positive non-zero floats:

'/Combat: "(?<attacker>[^"]+)" \([^)]+\) hit "(?<victim>[^"]+)" \([^)]+\) weapon="(?<weapon>(?!zombie")[^"]+)" damage=(?<damage>0\.0*[1-9][0-9]*|[1-9][0-9]*\.[0-9]+)/'

The damage alternation explicitly rejects 0.000000 and any leading-minus value because both branches require either 0.<non-zero> or <non-zero>.<digits>.

AdminPattern::<VERB>_ENTRY — six entry-anchored variants of the existing body-only verb constants. Necessary because PatternAnalyser calls preg_match_all against the full Entry text (including the [time] prefix), so the Phase A verb constants anchored at ^<admin> would never match. The Phase A constants stay intact for direct-message use; new ones live alongside them on the same AdminPattern class.

Wiring

Two getDefaultAnalyser() overrides (was return new PatternAnalyser(); for both):

// ProjectZomboidPvpLog
return (new PatternAnalyser())
    ->addPossibleInsightClass(PvpDamageInformation::class);
// ProjectZomboidAdminLog
return (new PatternAnalyser())
    ->addPossibleInsightClass(AdminAddedItemInformation::class)
    ->addPossibleInsightClass(AdminAddedXpInformation::class)
    ->addPossibleInsightClass(AdminGrantedAccessInformation::class)
    ->addPossibleInsightClass(AdminChangedOptionInformation::class)
    ->addPossibleInsightClass(AdminReloadedOptionsInformation::class)
    ->addPossibleInsightClass(AdminTeleportedInformation::class);

Test plan

Unit tests under test/tests/Games/ProjectZomboid/Analysis/, one per Insight class — exercises getPatterns() shape, setMatches() extraction, and at least one filter-rejection case for PvpDamageInformation (zombie weapon and zero-damage rejection).

End-to-end tests under test/tests/Games/ProjectZomboid/Analyser/:

  • PvpLogAnalysisTest against pvp-minimal.txt: asserts exactly three PvpDamageInformation insights (Bare Hands, Tire Iron (Worn), Hunting Knife). Zombie and vehicle rows must be filtered out by the regex.
  • AdminLogAnalysisTest against admin-minimal.txt: asserts 2 + 2 + 2 + 2 + 1 + 2 = 11 insights across the six admin classes, with the duplicate ShotgunShells row coalescing into a single insight at counter == 2.

Fixture changes

None. The Phase A synthetic fixtures pvp-minimal.txt and admin-minimal.txt already cover every code path Phase B.2 exercises.

Commits (as-built, in order)

  1. df62da1pre-phase-B.2 checkpoint (--allow-empty)
  2. 55f769cAdd PvpDamageInformation insight
  3. 90c85a0Add AdminAddedItemInformation insight ⚠️ broken — see 2026-04-30-pz-analysers-pvp-admin.md §Deviations
  4. 0d85a05Fix missing closing brace in AdminPattern (forward-fix for #3)
  5. a2faa55Add AdminAddedXpInformation insight
  6. caed04dAdd AdminGrantedAccessInformation insight
  7. b7b89efAdd AdminChangedOptionInformation insight
  8. 64641faAdd AdminReloadedOptionsInformation insight
  9. d15fc81Add AdminTeleportedInformation insight
  10. 51eb2deWire ProjectZomboidPvpLog default analyser
  11. c57d646Wire ProjectZomboidAdminLog default analyser

11 commits total, vs 10 originally planned. The brace-fix commit accounts for the discrepancy.

Open issues

None blocking. Phase A Q4 (admin verb scope) was settled before B.2 began. Phase B Q2 confirmed PvP fixtures contain real combat events worth analysing.

Pointers

  • Phase B.1 (foundation): 2026-04-30-pz-analysers-design.md and 2026-04-30-pz-analysers.md.
  • Phase B.3 (deferred analysers requiring custom Analyser subclasses): 2026-04-30-pz-analysers-deferred-design.md.
  • Workflow conventions: CLAUDE.md § Workflow conventions and § Pitfalls.