# Hathor LLM NPC Integration

## Scope

V2 delegates live NPC dialogue and behavior for these open-world and
semi-open-world surfaces to `@hathor/llm-npc` through `@v2/hathor-npc-adapter`:

- World Tour
- Tekken Force
- Devil Within
- DJ street
- MyCAREER backstage
- SC Chronicles overworld

Fighting-match dialogue that can appear in rollback replays uses prebaked
`@hathor/lore-compiler` banks. Live LLM NPC output is not allowed to influence
deterministic simulation state.

## Runtime Contract

The V2 bridge accepts these hooks:

| Hook                   | V2 input                                             | Hathor output                                                 |
| ---------------------- | ---------------------------------------------------- | ------------------------------------------------------------- |
| `npc.encounter.start`  | NPC id, location, faction, player history hash       | Greeting, behavior intent vector, tone, emotional-state delta |
| `npc.dialogue.request` | Player utterance, scene context, party history hash  | NPC line, tone tag, emotion, suggested actions, memory ids    |
| `npc.behavior.tick`    | World-state delta on a low-frequency open-world tick | Behavior tree node, targeted action, decision reason          |
| `npc.combat.barks`     | HP delta, near-KO, KO, last move, arena hazard       | Short bark line, style hint, emotional-state delta            |

Every request must carry:

- `rollbackPolicy: "off-rollback-only"`
- `deterministicGameplay: false`
- `seed`
- `contextHash`
- `playerHistoryHash`

The bridge returns every response on `v2.npc.off_rollback` with
`rollbackResultPolicy: "ignored_by_rollback"` and includes the Hathor package
identifier `@hathor/llm-npc` in the output metadata.

Before a dialogue response is returned or cached, the bridge validates the
Hathor persona identity, declared intent and emotion, bounded suggested actions,
validated memory attribution, response/abstention state, and calibrated
confidence evidence. Triggered memories must exactly match attributed retrieved
memories, `confidenceScore` must match the calibrated score, and answered output
must clear its threshold. Abstentions cannot carry actions or triggered
memories.

## Dialogue Cache

Dialogue-like outputs from `npc.encounter.start`, `npc.dialogue.request`, and
`npc.combat.barks` are cached by seed plus context hash under
`V2/ue/Content/Generated/NPCDialogue/`. The file-backed adapter path is:

`<mode>/<hook>/<seed-context-hash-prefix>/<seed-context-hash>.json`

where `seed-context-hash` is `sha256(seed + "\n" + contextHash)`. Cache entries
carry the original `seed`, `contextHash`, mode, hook, NPC id, player id, output,
and rationale tags:

- `cross_platform_consistency`
- `cost_containment`
- `qa_repeatability`

The cache is not a replay-determinism feature. Open-world modes are not rollback
replay-recorded; the cache exists so identical seed/context pairs produce
identical reviewed NPC replies across platforms. In plain terms, the cache
exists for cross-platform consistency, cost containment, and repeatable
QA/localization review.

## Failure Behavior

Invalid mode ids, unsupported hooks, missing required identity fields, or any
attempt to mark a request as deterministic fail before calling Hathor. Upstream
provider failures are wrapped as `V2HathorNpcBridgeError` with
`code: "runtime_failure"` so client-server open-world systems can retry, degrade
dialogue, or surface outage telemetry without touching rollback state. Missing,
foreign, malformed, or contradictory dialogue evidence fails closed with
`code: "invalid_runtime_output"`.

`npc.behavior.tick` requires a Hathor behavior selector. Encounter starts and
combat barks can fall back through Hathor dialogue generation until the richer
combat-bark runtime is available in Hathor.

## Unreal Registration

`V2Services` registers two Hathor adapters:

- `hathor` for `@hathor/lore-compiler` compiled narrative exports
- `hathor-llm-npc` for `@hathor/llm-npc` live open-world NPC calls

Both descriptors set `bMayInfluenceRollback = false`; the automation spec
asserts the LLM NPC descriptor is registered, client-server available, and
off-rollback only.
