Files
csgowtf/MISSING_BACKEND_API.md
vikingowl f3d24e0286 docs: Consolidate backend API documentation and feature proposals
- Merge NEW_FEATURES.md into MISSING_BACKEND_API.md as "Future Feature Proposals"
- Remove redundant NEW_FEATURES.md file
- Add CLAUDE.md to .gitignore (local development config)
- Include pending frontend component updates

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-07 21:04:13 +01:00

27 KiB
Raw Blame History

Missing Backend API Data

This document outlines data that the frontend expects but is not currently provided by the backend API. These features would enhance the match analysis experience.


Impact Summary

Field Severity Status Impact
KAST % Critical Missing Players display 0% KAST
ADR Critical Missing Statistics incomplete
Weapon Kills High Missing Weapon stats show 0 kills
Round Winner High Missing No round outcome analysis
Win Reason High Missing Can't show how rounds ended
Headshot % Medium Partial Sometimes missing
Damage Stats Medium Not extracted Data sent but unused
Utility Stats Medium Missing Grenade analysis unavailable
Per-Round Stats Medium Missing No round-by-round performance
Loss Bonus Low Missing Economy analysis incomplete

1. Critical: KAST Percentage

Endpoint: GET /match/{id} (player stats)

Location in Frontend: src/lib/api/players.ts:49-76

Issue: KAST (Kill/Assist/Survive/Trade) is completely unavailable. Frontend returns placeholder 0.

// Current workaround in players.ts
const totalKast = recentMatches.reduce((sum, _m) => {
	// KAST is a percentage, we need to calculate it
	// For now, we'll use a placeholder
	return sum + 0;
}, 0);

Affected Components:

  • /player/[id]/+page.svelte - Player profile stats chart
  • /match/[id]/+page.svelte:28-29 - Team average KAST
  • Match scoreboard KAST% column

Expected Format:

{
	"players": [
		{
			"kast": 72.5
		}
	]
}

Backend Implementation: Calculate per player per match:

KAST% = (Rounds with Kill + Rounds with Assist + Rounds Survived + Rounds Traded) / Total Rounds * 100

2. Critical: Average Damage per Round (ADR)

Endpoint: GET /match/{id} (player stats)

Location in Frontend: src/lib/types/Match.ts:114-115

Issue: ADR not provided. Components use player.adr || 0 fallback.

Affected Components:

  • /match/[id]/+page.svelte:27, 44, 83 - Team and player ADR
  • /match/[id]/damage/+page.svelte - Damage analysis page
  • /player/[id]/+page.svelte:280 - Player profile

Expected Format:

{
	"players": [
		{
			"adr": 85.3
		}
	]
}

Backend Implementation:

ADR = Total Damage to Enemies / Rounds Played

3. High: Weapon Kill Counts

Endpoint: GET /match/{id}/weapons

Location in Frontend: src/lib/api/transformers/weaponsTransformer.ts:85-87

Issue: Backend provides damage/hits but NOT kill counts. All weapons show 0 kills.

// Current workaround
weapon_stats.push({
	// Kill data not available - API only provides hit/damage events
	kills: 0, // HARDCODED ZERO - should be from backend
	damage: stats.damage,
	hits: stats.hits
});

Expected Format:

{
	"weapons": {
		"7": {
			"kills": 12,
			"damage": 1847,
			"hits": 45
		}
	}
}

Backend Implementation: Correlate player_hurt events with player_death events to determine which weapon dealt the killing blow.


4. High: Round Winner & Win Reason

Endpoint: GET /match/{id}/rounds

Location in Frontend: src/lib/api/transformers/roundsTransformer.ts:71-76

Issue: Backend only returns economy data, not round outcomes.

// Current hardcoded placeholders
rounds.push({
	round: roundNum + 1,
	winner: 0, // HARDCODED - should be 2 (T) or 3 (CT)
	win_reason: '', // HARDCODED - should be enum
	players
});

Currently Returns:

{
  "0": { "player_id": [bank, equipment, spent] },
  "1": { "player_id": [bank, equipment, spent] }
}

Expected Format:

{
  "0": {
    "winner": 2,
    "win_reason": "bomb_exploded",
    "players": {
      "player_id": [bank, equipment, spent]
    }
  }
}

Win Reason Values:

Value Description
elimination All enemies killed
bomb_defused CT defused the bomb
bomb_exploded Bomb detonated (T win)
time Round timer expired (CT win)
target_saved Hostage rescued (rare)

Backend Implementation: Extract from RoundEnd game events in demo parser.


5. Medium: Damage Statistics (dmg_enemy, dmg_team)

Endpoint: GET /match/{id} (player stats)

Location in Frontend: src/lib/api/transformers.ts:96

Issue: Backend sends dmg as Record<string, unknown> but fields aren't extracted.

// In transformer - data received but not mapped
dmg?: Record<string, unknown>;  // NOT EXTRACTED to dmg_enemy/dmg_team

Type Definition (src/lib/types/Match.ts:134-135):

dmg_enemy?: number; // Damage dealt to enemies
dmg_team?: number;  // Damage dealt to team (friendly fire)

Expected Format:

{
	"players": [
		{
			"dmg": {
				"enemy": 2847,
				"team": 45
			}
		}
	]
}

Fix: Either:

  1. Backend returns flat dmg_enemy and dmg_team fields, OR
  2. Frontend transformer extracts from dmg.enemy and dmg.team

6. Medium: Utility/Grenade Statistics

Endpoint: GET /match/{id} (player stats)

Location in Frontend: src/lib/types/Match.ts:144-148

Issue: Not provided by backend at all.

Missing Fields:

ud_he?: number;      // HE grenade damage dealt
ud_flames?: number;  // Molotov/Incendiary damage dealt
ud_flash?: number;   // Flash grenades thrown (count)
ud_smoke?: number;   // Smoke grenades thrown (count)
ud_decoy?: number;   // Decoy grenades thrown (count)

Expected Format:

{
	"players": [
		{
			"ud_he": 156,
			"ud_flames": 89,
			"ud_flash": 8,
			"ud_smoke": 12,
			"ud_decoy": 2
		}
	]
}

Backend Implementation: Count grenade events and sum damage from player_hurt events where weapon is HE/molotov/incendiary.


7. Medium: Per-Round Player Statistics

Endpoint: GET /match/{id}/rounds

Issue: No per-round performance data for players.

Missing Fields per Player per Round:

kills_in_round?: number;   // Kills in this specific round
damage_in_round?: number;  // Damage dealt this round
assists_in_round?: number; // Assists this round

Expected Format:

{
	"1": {
		"winner": 2,
		"win_reason": "elimination",
		"players": {
			"76561198012345678": {
				"bank": 4000,
				"equipment": 3750,
				"spent": 2900,
				"kills": 2,
				"damage": 187,
				"assists": 1
			}
		}
	}
}

Backend Implementation: Aggregate player_death and player_hurt events per round, grouped by attacker.


8. Low: Loss Bonus Tracking

Endpoint: GET /match/{id}/rounds

Issue: Not tracked in backend.

Missing Fields per Team per Round:

loss_streak?: number; // Consecutive round losses (0-4)
loss_bonus?: number;  // Current loss bonus amount

CS2 Loss Bonus Scale:

Consecutive Losses Bonus
0 $1,400
1 $1,900
2 $2,400
3 $2,900
4+ $3,400

Backend Implementation: Track RoundEnd events and maintain loss counter per team, resetting on win.


9. Optional Fields (Expected Gaps)

These fields are intentionally optional due to data availability:

Field Reason
replay_url Only available for matches < 4 weeks old (Valve retention)
share_code Not all matches have share codes
tick_rate May not be in older demos
game_mode Legacy CS:GO matches don't have this
avg_ping Not always recorded in demos

Backend Implementation Checklist

Priority 1: Critical

  • Add KAST calculation per player per match
  • Add ADR calculation per player per match
  • Add weapon kill tracking (correlate damage with death events)
  • Add round winner from RoundEnd events
  • Add win_reason enumeration from RoundEnd events

Priority 2: High

  • Extract dmg_enemy and dmg_team in player stats
  • Add utility grenade statistics (ud_he, ud_flames, ud_flash, ud_smoke, ud_decoy)
  • Ensure hs_percent is always calculated

Priority 3: Medium

  • Add per-round player stats (kills, damage, assists per round)
  • Add loss bonus tracking per team per round
  • Ensure tick_rate is always provided when available

Frontend Readiness

The frontend already has:

  • Type definitions for all fields (src/lib/types/)
  • Components ready to display data (using fallbacks currently)
  • Transformers prepared to extract nested data
  • UI for all features (showing placeholders/zeros)

Once backend provides this data, frontend will automatically display it.


API Response Examples

Ideal Match Response

{
	"match_id": "123456",
	"players": [
		{
			"id": "76561198012345678",
			"name": "Player1",
			"kills": 25,
			"deaths": 18,
			"assists": 4,
			"kast": 72.5,
			"adr": 85.3,
			"hs_percent": 45.2,
			"dmg_enemy": 2847,
			"dmg_team": 12,
			"ud_he": 156,
			"ud_flames": 89,
			"ud_flash": 8,
			"ud_smoke": 12
		}
	]
}

Ideal Rounds Response

{
	"1": {
		"winner": 2,
		"win_reason": "bomb_exploded",
		"t_loss_streak": 0,
		"ct_loss_streak": 1,
		"players": {
			"76561198012345678": {
				"bank": 4000,
				"equipment": 3750,
				"spent": 2900,
				"kills": 2,
				"damage": 187
			}
		}
	}
}

Ideal Weapons Response

{
	"weapons": {
		"7": {
			"name": "AK-47",
			"kills": 12,
			"damage": 1847,
			"hits": 45,
			"headshots": 8
		}
	}
}

Future Feature Proposals

The following features require backend changes to implement. They are organized into tiers based on implementation complexity.


Tier 3: API Enhancements (Expose Existing Data)

These features use data that's already stored in the database but not currently exposed through the API.

3.1 Per-Weapon Kill Attribution

Current State:

  • weapon table stores damage per hit with hit_group, weapon_id, and dmg
  • Weapon damage is aggregated in player meta endpoint

Missing:

  • Kill counts per weapon (correlating damage with deaths)
  • Headshot kills vs body shot kills per weapon

Proposed API Change:

// Extend GET /player/:id/meta/:limit response
interface WeaponStats {
	weapon_id: number;
	weapon_name: string;
	kills: number; // NEW: Total kills with this weapon
	headshot_kills: number; // NEW: HS kills with this weapon
	damage: number; // Existing
	shots: number; // Existing
	hits: number; // Existing
}

Implementation Notes:

  • Requires correlating weapon damage events with kill events
  • Could be computed at match import time and stored, or calculated on-demand

3.2 Per-Map Detailed Statistics

Current State:

  • All player stats exist per match with map field
  • No pre-aggregated per-map statistics

Missing:

  • K/D ratio per map
  • ADR per map
  • Headshot % per map
  • Win rate per map

Proposed API Change:

// Extend GET /player/:id/meta/:limit response
interface MapStats {
	map: string;
	matches_played: number;
	wins: number;
	losses: number;
	ties: number;
	avg_kills: number;
	avg_deaths: number;
	avg_adr: number;
	headshot_pct: number;
}

Use Case: Players can see which maps they perform best on, helping with map vetoes and practice focus.


3.3 Hit Group Aggregates

Current State:

  • weapon.hit_group stores where each shot landed (0=head, 1=chest, 2=stomach, 3=left arm, 4=right arm, 5=left leg, 6=right leg)
  • Individual hits are stored but not aggregated

Missing:

  • Aggregated hit distribution across all matches
  • Per-weapon accuracy by body part

Proposed API Change:

// Extend GET /player/:id/meta/:limit response
interface HitGroupStats {
	total_hits: number;
	head: number; // Count of head hits
	chest: number; // Count of chest hits
	stomach: number; // Count of stomach hits
	arms: number; // Combined left+right arm hits
	legs: number; // Combined left+right leg hits
	head_pct: number; // Calculated percentage
	body_pct: number; // chest + stomach percentage
	limb_pct: number; // arms + legs percentage
}

Use Case: Visual body diagram showing where player typically lands shots, identifying spray control issues.


3.4 Round Economy Timeline

Current State:

  • roundstats table contains bank, equipment, spent per round
  • Data exists but not exposed in player endpoint

Missing:

  • Economy trends over match history
  • Buy pattern analysis (eco/force/full buy distribution)
  • Equipment value vs damage dealt correlation

Proposed API Change:

// New endpoint: GET /player/:id/economy
interface EconomyStats {
	avg_equipment_value: number;
	avg_bank_at_round_start: number;
	eco_round_pct: number; // % of rounds with <$2000 equipment
	force_buy_pct: number; // % of rounds with $2000-$4000
	full_buy_pct: number; // % of rounds with >$4000
	value_per_kill: number; // avg damage dealt / avg equipment value
	save_rate: number; // % of rounds where player survived with <$2000
}

Use Case: Understanding economic efficiency - are they getting value for their money?


3.5 Opponent History (Head-to-Head)

Current State:

  • All match participants are stored
  • Can identify when two players were in the same match

Missing:

  • Head-to-head records vs specific players
  • Performance when playing with/against specific teammates

Proposed API Change:

// New endpoint: GET /player/:id/opponents?limit=10
interface OpponentRecord {
	opponent_id: string;
	opponent_name: string;
	opponent_avatar: string;
	matches_played: number;
	wins: number;
	losses: number;
	avg_kills_vs: number; // Avg kills when playing against this opponent
	avg_deaths_vs: number; // Avg deaths when playing against this opponent
	last_match_date: string;
}

Use Case: "Rival" detection - who do they frequently play against and how do they perform?


3.6 Crosshair History

Current State:

  • crosshair code stored per match
  • color enum stored (0=default, 1=green, 2=yellow, 3=blue, 4=cyan)

Missing:

  • Not exposed in player meta endpoint
  • No history of crosshair changes

Proposed API Change:

// Extend GET /player/:id/meta/:limit response
interface CrosshairInfo {
	current_crosshair: string; // Most recent crosshair code
	current_color: number; // Most recent color
	changes_count: number; // How often they change crosshair
	history: Array<{
		crosshair: string;
		color: number;
		first_seen: string;
		matches_used: number;
	}>;
}

Use Case: Players curious about what crosshair settings others use, track experimentation.


Tier 4: Demo Parser Additions

These features require new data collection from demo files during parsing.

4.1 Kill/Death Event Log

What to Capture:

type KillEvent struct {
    MatchID       string
    RoundNumber   int
    Tick          int
    Timestamp     float64  // Seconds into round
    KillerID      string
    VictimID      string
    AssisterID    string   // nullable
    WeaponID      int
    Headshot      bool
    Wallbang      bool
    Smoke         bool     // Through smoke
    NoScope       bool
    Flashed       bool     // Victim was flashed
    Distance      float32  // Distance between players
    KillerX       float32
    KillerY       float32
    KillerZ       float32
    VictimX       float32
    VictimY       float32
    VictimZ       float32
}

Enables:

  • Opening kill/death statistics (first blood)
  • Trade detection (kill within X seconds of teammate death)
  • Kill distance analysis (long range vs close quarters)
  • Clutch situation detection
  • Kill position heatmaps

Storage Estimate: ~20-30 kills per match × 20 bytes average = ~500 bytes per match


4.2 Round Winner Attribution

What to Capture:

type RoundResult struct {
    MatchID       string
    RoundNumber   int
    WinnerTeamID  int      // 2 or 3
    WinReason     int      // 1=bomb, 2=defuse, 3=elimination, 4=time
    ClutchPlayerID string  // nullable - player who clutched (1vX)
    ClutchSize    int      // 1v1, 1v2, etc.
    MVPPlayerID   string   // Round MVP
}

Enables:

  • Clutch win rate (1v1, 1v2, 1v3, etc.)
  • Bomb plant/defuse success rates
  • Round impact scoring
  • MVP frequency

4.3 Position/Heatmap Data

What to Capture:

type PlayerPosition struct {
    MatchID      string
    RoundNumber  int
    Tick         int      // Sample every ~32 ticks (0.5 seconds)
    PlayerID     string
    X            float32
    Y            float32
    Z            float32
    ViewAngleX   float32  // Where they're looking
    ViewAngleY   float32
    IsAlive      bool
}

Enables:

  • Kill heatmaps (where do they get kills/die)
  • Site preference analysis (A vs B)
  • Positioning patterns
  • 2D round replay (future)

Storage Estimate: High - ~2000 position samples per player per match. Consider:

  • Only sample during key moments (kills, bomb plant, round end)
  • Downsample to 1 sample per second
  • Store as compressed binary blob

4.4 Trade Detection

What to Capture:

  • Already covered by Kill Event Log (4.1)
  • Calculate at query time: If player A dies and teammate B kills A's killer within 5 seconds = trade

Derived Stats:

interface TradeStats {
	trades_given: number; // Times you avenged a teammate
	trades_received: number; // Times a teammate avenged you
	trade_success_rate: number; // trades_given / opportunities
	trading_partner_id: string; // Who they trade with most often
}

4.5 Utility Timing Analysis

What to Capture:

type UtilityEvent struct {
    MatchID       string
    RoundNumber   int
    Tick          int
    PlayerID      string
    UtilityType   int      // flash, smoke, he, molotov
    ThrowX        float32
    ThrowY        float32
    ThrowZ        float32
    LandX         float32  // Where it detonated/landed
    LandY         float32
    LandZ         float32
    PlayersFlashed []FlashedPlayer  // For flashbangs
}

type FlashedPlayer struct {
    PlayerID      string
    Duration      float32  // Flash duration in seconds
    IsTeammate    bool
}

Enables:

  • Flash effectiveness (avg flash duration)
  • Team flash rate (already have dmg_team but duration is more precise)
  • Smoke lineup success
  • Molotov damage tracking

4.6 First Blood Statistics

What to Capture:

  • Mark is_first_blood flag in Kill Event (4.1)
  • First kill of each round

Derived Stats:

interface FirstBloodStats {
	first_blood_attempts: number; // Rounds where they got first kill OR first death
	first_bloods: number; // Times they got first kill
	first_deaths: number; // Times they died first
	first_blood_rate: number; // first_bloods / first_blood_attempts
	opening_duel_win_rate: number; // first_bloods / (first_bloods + first_deaths)
}

4.7 HLTV Rating 2.0

Formula Components:

Rating 2.0 = 0.0073*KAST + 0.3591*KPR - 0.5329*DPR + 0.2372*Impact + 0.0032*ADR + 0.1587

Where:
- KAST = % of rounds with Kill, Assist, Survived, or Traded
- KPR = Kills per round
- DPR = Deaths per round
- Impact = (2.13*KPR + 0.42*Assist per Round - 0.41)
- ADR = Average damage per round

What's Needed:

  • KAST requires knowing if player survived or was traded (needs trade detection)
  • All other components are calculable from existing data

Proposed Implementation:

  • Add kast_rounds counter to match stats
  • Calculate Rating 2.0 server-side for consistency

Tier 5: New Systems

These features require significant new infrastructure.

5.1 Player Comparison Tool

Description: Side-by-side comparison of any two players' statistics.

Requirements:

  • New UI page: /compare/:player1/:player2
  • API endpoint: GET /players/compare?ids=player1,player2
  • Returns normalized stats for fair comparison

Comparison Metrics:

interface PlayerComparison {
	players: [PlayerMeta, PlayerMeta];
	stats_comparison: {
		metric: string;
		player1_value: number;
		player2_value: number;
		player1_percentile: number; // How they rank globally
		player2_percentile: number;
	}[];
	head_to_head?: {
		matches_played: number;
		player1_wins: number;
		player2_wins: number;
	};
	common_maps: string[];
	common_teammates: PlayerMeta[];
}

5.2 Achievement System

Description: Badges and milestones for player accomplishments.

Schema:

CREATE TABLE achievements (
    id SERIAL PRIMARY KEY,
    name VARCHAR(100),
    description TEXT,
    icon VARCHAR(50),
    category VARCHAR(50),  -- 'kills', 'utility', 'milestones', 'special'
    threshold INT,
    stat_key VARCHAR(50)   -- Which stat to check
);

CREATE TABLE player_achievements (
    player_id VARCHAR(20),
    achievement_id INT,
    unlocked_at TIMESTAMP,
    progress INT,          -- For progressive achievements
    PRIMARY KEY (player_id, achievement_id)
);

Example Achievements:

Name Description Threshold
Centurion 100 aces 100
Headhunter 1000 headshot kills 1000
Support Main 500 flash assists 500
Clutch Master 50 1v3+ clutches 50
Map Scholar Play 100 matches on each map 700 total
Friendly Fire Deal 1000 team damage (shame badge) 1000

Implementation:

  • Background job checks achievement progress after each match import
  • Push notification system for newly unlocked achievements
  • Achievement showcase on player profile

5.3 Global Leaderboards

Description: Rankings by various statistics.

Schema:

CREATE TABLE leaderboards (
    stat_key VARCHAR(50),
    time_period VARCHAR(20),  -- 'all_time', 'monthly', 'weekly'
    player_id VARCHAR(20),
    value DECIMAL(10,2),
    rank INT,
    updated_at TIMESTAMP,
    PRIMARY KEY (stat_key, time_period, player_id)
);

Leaderboard Categories:

  • Highest K/D ratio (min 50 matches)
  • Most headshot kills
  • Highest ADR
  • Most flash assists
  • Most matches played
  • Highest win rate (min 100 matches)
  • Most aces
  • Longest win streak

Implementation:

  • Materialized view or dedicated table refreshed hourly/daily
  • Pagination support for full leaderboard browsing
  • Filter by region/rank bracket (future)

5.4 Improvement Tips Engine

Description: AI-generated suggestions based on weak stats.

Rules Engine Approach:

interface ImprovementRule {
	condition: (stats: PlayerStats) => boolean;
	tip: string;
	priority: number;
	category: 'aim' | 'utility' | 'economy' | 'teamplay' | 'consistency';
}

const rules: ImprovementRule[] = [
	{
		condition: (s) => s.headshot_pct < 30,
		tip: 'Your headshot percentage is below average. Focus on crosshair placement at head level.',
		priority: 1,
		category: 'aim'
	},
	{
		condition: (s) => s.flash_assists < 1,
		tip: "You're not getting many flash assists. Practice pop flashes for your teammates.",
		priority: 2,
		category: 'utility'
	},
	{
		condition: (s) => s.team_damage_ratio > 3,
		tip: 'Your team damage is high. Be more careful with utility and spray control.',
		priority: 1,
		category: 'teamplay'
	}
	// ... more rules
];

Alternative - ML Approach:

  • Cluster players by playstyle
  • Compare to higher-ranked players with similar style
  • Identify key stat differences
  • Generate personalized recommendations

5.5 Match Replay Integration (2D)

Description: Simple 2D overhead view of rounds.

Requirements:

  • Position data from Tier 4.3
  • Map radar images (already have some)
  • WebGL or Canvas-based renderer
  • Playback controls (play/pause/speed)

Data Format:

interface ReplayFrame {
	tick: number;
	timestamp: number; // Seconds into round
	players: {
		id: string;
		team: number;
		x: number;
		y: number;
		angle: number;
		health: number;
		alive: boolean;
		weapon: string;
	}[];
	events: {
		type: 'kill' | 'plant' | 'defuse' | 'flash' | 'smoke';
		tick: number;
		data: any;
	}[];
}

Compression:

  • Delta encoding (only send changes)
  • Binary format instead of JSON
  • Stream in chunks for long rounds

5.6 Social Features

Description: Follow players, activity feed, sharing.

Schema:

CREATE TABLE follows (
    follower_id VARCHAR(20),
    following_id VARCHAR(20),
    created_at TIMESTAMP,
    PRIMARY KEY (follower_id, following_id)
);

CREATE TABLE activity_feed (
    id SERIAL PRIMARY KEY,
    player_id VARCHAR(20),
    event_type VARCHAR(50),  -- 'match_completed', 'achievement_unlocked', 'rank_changed'
    event_data JSONB,
    created_at TIMESTAMP
);

Features:

  • Follow/unfollow players
  • Activity feed showing followed players' recent matches
  • Share profile/match links
  • Privacy settings (public/private profiles)

Data Schema Reference

Current Tables Used

Table Key Fields Notes
players id, name, avatar, tracked Core player data
matches matchid, map, date, score* Match metadata
matchplayers All per-player stats Already comprehensive
weapon hit_group, weapon_id, dmg Hit registration
roundstats bank, equipment, spent Economy data
spray spray (gob-encoded) Spray patterns

Existing Fields Available but Not Exposed

Field Location Potential Use
crosshair matchplayers Crosshair display
color matchplayers Crosshair color
avg_ping matchplayers Network quality
hit_group weapon Body part accuracy
spray spray Spray visualization

Priority Recommendations

High Priority (High Value, Low Effort)

  1. 3.1 Per-Weapon Kill Attribution - Players want to know their best weapons
  2. 3.2 Per-Map Detailed Statistics - Essential for competitive players
  3. 3.3 Hit Group Aggregates - Visual appeal, easy to understand

Medium Priority (High Value, Medium Effort)

  1. 4.1 Kill/Death Event Log - Unlocks many derived features
  2. 4.6 First Blood Statistics - Key competitive metric
  3. 3.5 Opponent History - Engaging "rivalry" feature

Lower Priority (High Effort or Niche Appeal)

  1. 5.3 Global Leaderboards - Community engagement
  2. 5.1 Player Comparison - Nice-to-have
  3. 5.2 Achievement System - Gamification
  4. 5.5 Match Replay - High effort, impressive feature

Questions for Discussion

  1. Storage constraints: Position data (4.3) could be large. What's our storage budget?
  2. Processing time: Kill event parsing (4.1) adds to import time. Acceptable?
  3. Caching strategy: Meta stats are cached 30 days. Should new aggregates follow same pattern?
  4. API versioning: Should we version the API or extend existing endpoints?
  5. Privacy considerations: Should opponent history require consent?

Document consolidated from separate feature proposals Last updated: December 2024