Add analytics integration with Horchposten backend

Implements session-based analytics tracking that sends gameplay
stats to the Horchposten API. Adds stats.{c,h} for accumulating
per-session metrics (kills, deaths, shots, dashes, jumps, pickups,
damage, time) and analytics.{c,h} with EM_JS bridge for fetch()
calls to the backend. Client ID is persisted in localStorage.
Session start/end hooks are wired into all game lifecycle events
(level transitions, restart, quit, tab close via sendBeacon).
Analytics URL/key are configured via data attributes on the canvas
container. Non-WASM builds compile with no-op stubs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
root
2026-03-08 17:11:39 +00:00
parent 4407932a2d
commit a23ecaf4c1
8 changed files with 331 additions and 1 deletions

29
src/game/stats.c Normal file
View File

@@ -0,0 +1,29 @@
#include "game/stats.h"
#include <string.h>
static GameStats *s_active = NULL;
void stats_reset(GameStats *s) {
memset(s, 0, sizeof(GameStats));
}
void stats_update_score(GameStats *s) {
int score = s->levels_completed * 100
+ s->enemies_killed * 10
- s->deaths * 25
+ s->pickups_collected * 5;
s->score = score > 0 ? score : 0;
}
void stats_set_active(GameStats *s) { s_active = s; }
GameStats *stats_get_active(void) { return s_active; }
void stats_record_kill(void) { if (s_active) s_active->enemies_killed++; }
void stats_record_death(void) { if (s_active) s_active->deaths++; }
void stats_record_shot_fired(void) { if (s_active) s_active->shots_fired++; }
void stats_record_shot_hit(void) { if (s_active) s_active->shots_hit++; }
void stats_record_dash(void) { if (s_active) s_active->dashes_used++; }
void stats_record_jump(void) { if (s_active) s_active->jumps++; }
void stats_record_pickup(void) { if (s_active) s_active->pickups_collected++; }
void stats_record_damage_taken(int n) { if (s_active) s_active->damage_taken += n; }
void stats_record_damage_dealt(int n) { if (s_active) s_active->damage_dealt += n; }