Fighting Game · Guides & deep dives

V2 Analytics Self-Service Query Guide

dashboard, notebook, or incident

8sections3 minread1table

On this page

Phase 72.5.2.15 defines the self-service analytics documentation path for approved analysts, researchers, and operators.

The default path is to use governed analytics surfaces first, then @v2/telemetry-data-export-api for scoped raw-event investigation, and finally @v2/telemetry-bi-export-connectors for Grafana, Tableau, and Looker delivery. Direct warehouse queries are allowed only for principals with an approved purpose and must preserve the privacy guardrails below.

Access Model#

  • Roles: researcher, analyst, or admin
  • Required approval: a non-empty approved purpose attached to the query, dashboard, notebook, or incident
  • Governed API: GET /v2/telemetry/export/events
  • BI delivery: Grafana JSON data frames, Tableau Web Data Connector rows, and Looker LookML/rows from @v2/telemetry-bi-export-connectors
  • Audit: every export records principal subject, approved purpose, source table, row count, and topic set

Data Map#

Need Preferred Surface Warehouse Source
Standard event names and payloads telemetry-sdk-event-catalog.md GameEventTaxonomy_V2_Contract.json
Raw event investigation @v2/telemetry-data-export-api warehouse.v2_telemetry.events
Reconstructed sessions @v2/telemetry-session-reconstruction warehouse.v2_telemetry.player_sessions
Realtime player counts @v2/realtime-player-count-dashboard latest aggregate samples
Funnels @v2/session-funnel-analysis session and purchase events
Retention cohorts @v2/retention-cohort-analysis session events by cohort day
Engagement metrics @v2/engagement-metrics-dashboard session length and interval events
Economy analytics @v2/economy-analytics earn, spend, and purchase events
Difficulty analytics @v2/difficulty-analytics encounter attempts and outcomes
Crash analytics @v2/crash-analytics-dashboard sanitized crash aggregates
Performance analytics @v2/performance-analytics client performance samples
A/B experiments @v2/ab-test-analysis-pipeline experiment exposure and conversion events
Churn and segments @v2/churn-prediction-model, @v2/player-segmentation hashed-account behavioral events
Alerting @v2/telemetry-alerting-rules aggregate crash/player/matchmaking samples

Privacy Guardrails#

  • Never select, store, or join raw account IDs, email, IP address, platform tokens, device identifiers, or other forbidden payload fields.
  • Preserve exposesRawAccountIds: false for every self-service query, dashboard, notebook, and BI connector output.
  • Use accountIdHash only when the approved purpose requires account-level grouping.
  • Prefer cohort, segment, session, region, platform, game mode, and build aggregates over player-level extracts.
  • Keep raw-event exports within the approved topic, account hash, and time scopes enforced by queryTelemetryDataExport.
  • Do not bypass @v2/telemetry-privacy-compliance, @v2/telemetry-data-export-api, or retention policy for ad hoc notebooks.
  • Redact payloadJson before sharing screenshots or external BI exports unless every field is already approved for that audience.

Query Workflow#

  1. Start from telemetry-sdk-event-catalog.md and confirm the topic and payload fields are standard V2 telemetry.
  2. Check whether a governed surface already answers the question.
  3. If raw rows are required, request an approved purpose and scope topics, account hashes, and time windows before using GET /v2/telemetry/export/events.
  4. Use cursor pagination for exports larger than one page.
  5. Validate the row count, topics, and source table in the export audit record.
  6. Publish durable dashboards through Grafana, Tableau, or Looker connectors rather than unmanaged CSV extracts.
  7. Attach the query, approval ticket, and verification notes to the dashboard or incident record.

SQL Templates#

The examples below are ClickHouse-flavored and use only approved V2 warehouse columns. Adapt JSON extraction syntax for BigQuery or Redshift without changing the privacy model.

Daily Active Sessions#

sql
SELECT
  toDate(toDateTime(eventUnixSeconds)) AS event_day,
  uniqExact(sessionId) AS sessions
FROM warehouse.v2_telemetry.events
WHERE topic = 'v2.player.session.started'
  AND eventUnixSeconds >= {from_unix_seconds:UInt32}
  AND eventUnixSeconds < {to_unix_seconds:UInt32}
GROUP BY event_day
ORDER BY event_day;

New Player Funnel#

sql
WITH funnel_events AS (
  SELECT
    sessionId,
    topic,
    min(eventUnixSeconds) AS first_seen
  FROM warehouse.v2_telemetry.events
  WHERE topic IN (
    'v2.player.session.started',
    'v2.tutorial.completed',
    'v2.match.completed',
    'v2.cosmetic.purchased'
  )
    AND eventUnixSeconds >= {from_unix_seconds:UInt32}
    AND eventUnixSeconds < {to_unix_seconds:UInt32}
  GROUP BY sessionId, topic
)
SELECT
  topic,
  uniqExact(sessionId) AS sessions
FROM funnel_events
GROUP BY topic
ORDER BY sessions DESC;

Retention Cohort Sketch#

sql
SELECT
  cohort_day,
  active_day,
  uniqExact(accountIdHash) AS retained_accounts
FROM warehouse.v2_telemetry.player_sessions
WHERE accountIdHash IS NOT NULL
  AND cohort_day >= {cohort_start:Date}
  AND cohort_day <= {cohort_end:Date}
GROUP BY cohort_day, active_day
ORDER BY cohort_day, active_day;

Crash Rate By Version#

sql
SELECT
  JSON_VALUE(payloadJson, '$.build_version') AS build_version,
  countIf(topic = 'v2.player.error.reported') AS crashes,
  uniqExact(sessionId) AS sessions,
  crashes / greatest(sessions, 1) AS crash_rate
FROM warehouse.v2_telemetry.events
WHERE topic IN ('v2.player.error.reported', 'v2.player.session.started')
  AND eventUnixSeconds >= {from_unix_seconds:UInt32}
  AND eventUnixSeconds < {to_unix_seconds:UInt32}
GROUP BY build_version
ORDER BY crash_rate DESC;

Matchmaking Wait P95#

sql
SELECT
  JSON_VALUE(payloadJson, '$.region') AS region,
  JSON_VALUE(payloadJson, '$.game_mode') AS game_mode,
  quantileExact(0.95)(
    toFloat64(JSON_VALUE(payloadJson, '$.wait_seconds'))
  ) AS p95_wait_seconds
FROM warehouse.v2_telemetry.events
WHERE topic = 'v2.matchmaking.wait_sampled'
  AND eventUnixSeconds >= {from_unix_seconds:UInt32}
  AND eventUnixSeconds < {to_unix_seconds:UInt32}
GROUP BY region, game_mode
HAVING p95_wait_seconds >= 180
ORDER BY p95_wait_seconds DESC;

BI Connector Recipes#

Grafana#

Use @v2/telemetry-bi-export-connectors with connector grafana. The output is a grafana-json-dataframe payload with time, topic, event ID, session ID, sequence, critical flag, account hash, and payload JSON fields.

Tableau#

Use connector tableau. The output is a tableau-web-data-connector payload with stable columns, rows, and eventUnixSeconds as the incremental key.

Looker#

Use connector looker. The output includes the oshun_v2_telemetry model name, the v2_telemetry_events explore, and a LookML view with topic, session_id, account_id_hash, and event_count definitions.

Review Checklist#

  • The question maps to a documented surface or approved event topics.
  • The query includes an approved purpose and bounded time window.
  • Topic and account hash scopes are explicit when raw rows are exported.
  • Row counts and topic lists match the export audit.
  • Results avoid raw identifiers and comply with retention.
  • Dashboards include owner, refresh cadence, source table, and incident or research ticket.
  • BI connector outputs are regenerated from governed exports, not manually edited extracts.

Verification#

bash
python V2/ue/Tools/check-v2-analytics-self-service-query-guide.py
python -m json.tool V2/ue/Build/Telemetry/v2-analytics-self-service-query-guide.json