# V2 Message Of The Day

This runbook covers `TODOS.phase-72.72.12.1.14`: a message-of-the-day system
that can push announcements to the game client for events, downtime, and patch
notes without a client patch.

The service package is `@v2/message-of-the-day-service` at
`apps/v2/message-of-the-day-service/`. Its contract is
`V2/ue/Content/V2/LiveOps/MessageOfTheDay_V2_Contract.json` and the validation
gate is `V2/ue/Tools/check-v2-message-of-the-day.py`.

## Announcement Model

Supported announcement types:

- `event`
- `downtime`
- `patch-notes`

Each message carries `messageId`, `type`, `priority`, localized title/body copy,
active `startsAt` and `endsAt` windows, `localizationKey`, author metadata,
optional call-to-action data, targeting criteria, dismissal behavior, and
`clientPatchRequired: false`.

Category-specific requirements:

- Events require `eventId`.
- Downtime messages require `downtimeWindowId` and `statusPageUrl`.
- Patch notes require `patchNotesUrl` for patch notes.

## Client Delivery

Endpoints:

- `GET /v2/live-ops/motd/{environment}`
- `POST /v2/live-ops/motd/{environment}/messages`
- `POST /v2/live-ops/motd/{environment}/messages/{messageId}/publish`

`buildV2MessageOfTheDayServiceSurface` validates and publishes the MOTD surface.
The client payload includes `pushAnnouncements: true`, an ETag,
`announcementCount`, the active announcement list, per-account dismissal
support, and `requiresClientPatch: false`.

`resolveV2MessageOfTheDayForClient` applies targeting by region, platform, build
version, and account level. Dismissible announcements that the account has
already dismissed are omitted. Non-dismissible downtime announcements remain in
the payload and can set `requiresAcknowledgement: true` so players see critical
server update notices.

## Operator Flow

1. Author the event, downtime, or patch-note message with localized title/body
   keys and category metadata.
2. Publish to staging first, then production with a new MOTD version ID.
3. The client refreshes `GET /v2/live-ops/motd/{environment}` on startup and
   periodic refresh, applies targeting, and displays active announcements.
4. The client persists per-account dismissal for dismissible messages.
5. Operators expire a message by advancing `endsAt` or publishing a replacement
   version.

## Release Gates

Required gates:

- `message-of-the-day-package`
- `message-of-the-day-announcement-types`
- `message-of-the-day-client-payload`
- `message-of-the-day-targeting`
- `message-of-the-day-dismissal`
- `message-of-the-day-validation`
- `message-of-the-day-ci-wired`

## Verification

```bash
pnpm --filter @v2/message-of-the-day-service test
pnpm --filter @v2/message-of-the-day-service typecheck
pnpm --filter @v2/message-of-the-day-service lint
pnpm --filter @v2/message-of-the-day-service build
python3 V2/ue/Tools/check-v2-message-of-the-day.py
python3 V2/ue/Tools/check-v2-ci-workflow.py
python3 V2/tools/validate-v2-docs.py
```
