NEO-109: Add Slice 3 encounter telemetry hook comments.
Document encounter_start, encounter_complete, reward_attribution, and encounter_complete_denied at engine anchors; remove wiring duplicate.pull/148/head
parent
e6debc2968
commit
1a7b5312c5
|
|
@ -8,7 +8,7 @@ namespace NeonSprawl.Server.Game.Combat;
|
|||
public static class CombatOperations
|
||||
{
|
||||
// --- Reserved telemetry hook sites (NEO-84): no emit until future modules ---
|
||||
// encounter_start — future E5.M3 encounter spawn/engage path (not wired in Slice 1).
|
||||
// encounter_start — E5.M3 anchor: EncounterProgressOperations.TryActivateOnFirstEngagement (NEO-109).
|
||||
// player_death — future player HP / death resolution (player HP out of scope in Slice 1).
|
||||
/// <summary>
|
||||
/// Resolves one ability against one prototype combat target using catalog damage and the health store.
|
||||
|
|
|
|||
|
|
@ -88,10 +88,8 @@ public static class EncounterCombatWiring
|
|||
playerId,
|
||||
encounterId,
|
||||
completion.ReasonCode);
|
||||
return;
|
||||
}
|
||||
|
||||
// --- Telemetry hook site (NEO-109): future E9.M1 catalog event `encounter_complete` ---
|
||||
// TODO(E9.M1): catalog emit — once per player+encounter when grants commit (NEO-106 cast path).
|
||||
// encounter_complete / reward_attribution hooks: EncounterCompletionOperations.TryCompleteAndGrant (NEO-109).
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ namespace NeonSprawl.Server.Game.Encounters;
|
|||
/// Internal completion payload returned on successful encounter grant (NEO-105).
|
||||
/// Persisted via <see cref="IEncounterCompleteEventStore"/> on success (NEO-107).
|
||||
/// E7.M2 quest-credit routing consumes this record (hook stub on NEO-107).
|
||||
/// NEO-109 telemetry: <c>encounter_complete</c> / <c>reward_attribution</c> hook sites in
|
||||
/// <see cref="EncounterCompletionOperations.TryCompleteAndGrant"/>.
|
||||
/// </summary>
|
||||
public readonly record struct EncounterCompleteEvent(
|
||||
string PlayerId,
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ namespace NeonSprawl.Server.Game.Encounters;
|
|||
/// <summary>
|
||||
/// Applies encounter reward-table grants and marks completion idempotently (NEO-105).
|
||||
/// Combat defeat wiring: <see cref="AbilityInput.AbilityCastApi"/> (NEO-106).
|
||||
/// NEO-109 telemetry hook sites: <see cref="TryCompleteAndGrant"/> (<c>encounter_complete</c>, <c>reward_attribution</c>),
|
||||
/// <see cref="Deny"/> (<c>encounter_complete_denied</c>).
|
||||
/// </summary>
|
||||
public static class EncounterCompletionOperations
|
||||
{
|
||||
|
|
@ -122,7 +124,16 @@ public static class EncounterCompletionOperations
|
|||
// TODO(E7.M2): reward_delivery — QuestRewardBundle router consumes EncounterCompleteEvent
|
||||
// (playerId, encounterId, idempotencyKey, grantedItemSummary) → idempotent RewardDeliveryEvent.
|
||||
// Prototype quest credit: contract_handoff_token item loot + this event record; full router: E7.M2.
|
||||
// TODO(E9.M1): catalog emit — encounter_complete on successful grant commit (NEO-109).
|
||||
|
||||
// --- Telemetry hook site (NEO-109): future E9.M1 catalog event `encounter_complete` ---
|
||||
// TODO(E9.M1): catalog emit — once per player+encounter on successful grant + completion mark commit.
|
||||
// Planned payload: playerId, encounterId, rewardTableId, completedAt, idempotencyKey, grantedItems summary
|
||||
// (EncounterCompleteEvent). No ingest or ILogger here (comments-only). EncounterCombatWiring delegates here.
|
||||
|
||||
// --- Telemetry hook site (NEO-109): future E9.M1 catalog event `reward_attribution` ---
|
||||
// TODO(E9.M1): catalog emit — once per successful completion (batch attribution, not per TryAddStack).
|
||||
// Planned payload: playerId, encounterId, rewardTableId, grantedItems[] (EncounterGrantApplied batch).
|
||||
// Inventory layer still emits item_created per stack via PlayerInventoryOperations (NEO-56).
|
||||
|
||||
return new EncounterCompletionResult(
|
||||
Success: true,
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ namespace NeonSprawl.Server.Game.Encounters;
|
|||
/// <summary>
|
||||
/// Server-internal encounter completion resolution envelope (NEO-105).
|
||||
/// Combat wiring promotes via NEO-106; HTTP DTOs via NEO-108.
|
||||
/// NEO-109 telemetry hook sites live in <see cref="EncounterCompletionOperations.TryCompleteAndGrant"/>.
|
||||
/// </summary>
|
||||
/// <param name="GrantsApplied">Item grants on success; empty when denied.</param>
|
||||
/// <param name="CompleteEvent">Completion payload on success; null when denied.</param>
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ namespace NeonSprawl.Server.Game.Encounters;
|
|||
/// <summary>
|
||||
/// Encounter activation and defeat-all progress orchestration (NEO-104).
|
||||
/// Combat cast wiring: <see cref="AbilityInput.AbilityCastApi"/> (NEO-106).
|
||||
/// NEO-109 telemetry hook site: <see cref="TryActivateOnFirstEngagement"/> (<c>encounter_start</c>).
|
||||
/// </summary>
|
||||
public static class EncounterProgressOperations
|
||||
{
|
||||
|
|
@ -63,7 +64,10 @@ public static class EncounterProgressOperations
|
|||
}
|
||||
|
||||
// --- Telemetry hook site (NEO-109): future E9.M1 catalog event `encounter_start` ---
|
||||
// TODO(E9.M1): catalog emit — on first activation for player+encounter (NEO-106 wires cast path).
|
||||
// TODO(E9.M1): catalog emit — when TryActivate returns true (first activation for player+encounter).
|
||||
// Planned payload: playerId, encounterId, npcInstanceId (engagement target). No ingest or ILogger here
|
||||
// (comments-only). EncounterCombatWiring calls this on first damaging hit vs a required NPC (NEO-106).
|
||||
|
||||
return progressStore.TryActivate(playerId, encounterId);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -206,13 +206,26 @@ Prototype: defeat all three E5.M2 NPCs via cast → row **`prototype_combat_pock
|
|||
curl -sS -i "http://localhost:5253/game/players/dev-local-1/encounter-progress"
|
||||
```
|
||||
|
||||
## Encounter telemetry hooks (NEO-109)
|
||||
|
||||
Comment-only hook sites for Epic 5 **Slice 3** catalog events ([epic_05 Slice 3](../../docs/decomposition/epics/epic_05_pve_combat.md#epic-5-slice-3)). **`TODO(E9.M1)`** — no production ingest. **`POST …/ability-cast`** and **`EncounterCombatWiring`** delegate to the engines below (no duplicate API-layer hooks).
|
||||
|
||||
| Event | Anchor |
|
||||
|-------|--------|
|
||||
| **`encounter_start`** | **`EncounterProgressOperations.TryActivateOnFirstEngagement`** — emit when **`TryActivate`** returns true (first engagement). Activates NEO-84 reserved **`encounter_start`** pointer in **`CombatOperations`**. |
|
||||
| **`encounter_complete`** | **`EncounterCompletionOperations.TryCompleteAndGrant`** — once per successful grant + completion mark commit. |
|
||||
| **`reward_attribution`** | Same success path — once per completion (batch **`grantedItems`**); per-stack **`item_created`** remains in **`PlayerInventoryOperations`** ([NEO-56](#player-inventory-neo-54-store-neo-55-http)). |
|
||||
| **`encounter_complete_denied`** | **`EncounterCompletionOperations.Deny`** — structured deny + **`EncounterCompletionReasonCodes`**. |
|
||||
|
||||
Plan: [NEO-109 implementation plan](../../docs/plans/NEO-109-implementation-plan.md).
|
||||
|
||||
## Encounter combat wiring (NEO-106)
|
||||
|
||||
On every successful **`POST …/ability-cast`** accept, **`EncounterCombatWiring.TryProcessCastOutcome`** (best-effort; does not change cast JSON):
|
||||
|
||||
| Cast outcome | Encounter effect |
|
||||
|--------------|------------------|
|
||||
| **`damageDealt > 0`** vs a required NPC | **`EncounterProgressOperations.TryActivateOnFirstEngagement`** — starts **`prototype_combat_pocket`** progress (`encounter_start` hook site in NEO-104). |
|
||||
| **`damageDealt > 0`** vs a required NPC | **`EncounterProgressOperations.TryActivateOnFirstEngagement`** — starts **`prototype_combat_pocket`** progress (**`encounter_start`** hook site, [NEO-109](#encounter-telemetry-hooks-neo-109)). |
|
||||
| **`targetDefeated: true`** | **`TryMarkTargetDefeated`**; when all three E5.M2 NPC ids defeated, **`EncounterCompletionOperations.TryCompleteAndGrant`**. |
|
||||
| Inventory full on completion | Defeat progress retained; completion/grants fail closed (retry when bag has space). |
|
||||
|
||||
|
|
@ -363,7 +376,7 @@ Comment-only hook sites in **`CombatOperations.TryResolve`** for future E9.M1 ca
|
|||
|
||||
- **`ability_used`** — on every successful resolve (zero-damage abilities included).
|
||||
- **`enemy_defeat`** — only when lethal damage drives **`after.Defeated`** to **`true`** (re-hit on defeated targets denies at **`target_defeated`** before damage).
|
||||
- **Reserved (comments only):** **`encounter_start`** (E5.M3 encounters).
|
||||
- **Reserved (comments only):** **`encounter_start`** — E5.M3 anchor: [Encounter telemetry hooks (NEO-109)](#encounter-telemetry-hooks-neo-109).
|
||||
- **`player_death`** — only when lethal NPC damage drives player **`currentHp`** to **0** (comment hook in NEO-95; full event deferred).
|
||||
|
||||
E1.M4 cast funnel events **`ability_cast_requested`** / **`ability_cast_denied`** remain in **`AbilityCastApi`** ([NEO-30](#ability-cast-neo-31-neo-82)). E9.M1 ingest should correlate route **`playerId`** with engine payload fields at accept. Plan: [NEO-84 implementation plan](../../docs/plans/NEO-84-implementation-plan.md).
|
||||
|
|
|
|||
Loading…
Reference in New Issue