# V2 Achievement Trophy Platform Routing

Phase 72.21.1.7 routes the platform-agnostic achievements from
[AchievementTrophies_V2_Contract.json](../../ue/Content/V2/Persistence/Profile/AchievementTrophies_V2_Contract.json)
through the V2 platform SDK abstraction. The routing policy is
`FV2AchievementTrophyPlatformRoutingPolicy`; it consumes committed completion
events and emits an `FV2AchievementTrophyPlatformUnlockPlan` for the native
provider API.

## Source Achievements

The router does not define a second achievement catalog. It uses the
`AchievementTrophy.PlatformPlan.V2` ids already owned by `V2Persistence`:

| Achievement id                             | Purpose                                      |
| ------------------------------------------ | -------------------------------------------- |
| `Achievement.Basic.StoryComplete`          | Required basic completion achievement        |
| `Achievement.Skill.ThrowTechs`             | Skill milestone achievement                  |
| `Achievement.Hidden.BrutalityCondition`    | Hidden discovery achievement                 |
| `Achievement.Hidden.AshaEasterEgg`         | Character-specific Easter egg achievement    |
| `Achievement.Completionist.RankedMarathon` | Optional long-tail completionist achievement |

## Provider Routes

Each achievement id has one auto-unlock route per launch provider. The route
keeps gameplay code on the unified `UnlockAchievement` request type while the
provider bridge selects the correct native command.

| Provider             | Platform account | Native bridge                | Unlock command                        |
| -------------------- | ---------------- | ---------------------------- | ------------------------------------- |
| Steamworks           | Steam            | `V2SteamworksSdkBridge`      | `ISteamUserStats::SetAchievement`     |
| Epic Online Services | Epic Games       | `V2EosSdkBridge`             | `EOS_Achievements_UnlockAchievements` |
| GOG Galaxy           | GOG              | `V2GogGalaxySdkBridge`       | `galaxy::api::IStats::SetAchievement` |
| PlayStation SDK      | PSN              | `V2PlayStationSdkStubBridge` | `Trophies.Unlock`                     |
| Xbox GDK             | Xbox Live        | `V2XboxGdkSdkStubBridge`     | `Achievements.Unlock`                 |

PlayStation and Xbox routes stay public-stub-only in `V2OnlineServices`.
Proprietary console headers and symbols remain in
`Restricted/NotForLicensees/Online/PlatformSDK/PlayStation` and
`Restricted/NotForLicensees/Online/PlatformSDK/XboxGDK`.

## Unlock Rules

`PlanAchievementTrophyPlatformUnlock` queues a provider call only when the
achievement progress has been committed by persistence, the current value meets
the target value, the platform account is linked, and the policy has a matching
route. Duplicate platform unlocks are suppressed. Platform API failures fail
closed so a local profile record cannot imply a provider-side unlock unless the
provider call is ready to run through the platform SDK abstraction.

## Verification

Run:

```bash
python3 V2/ue/Tools/check-v2-achievement-trophy-platform-routing.py
```

The checker validates the C++ API, contract, automation spec, CI workflow, Horde
gate, documentation, and the TODO completion evidence for Section 72.21.1.7.
