The problem I needed to solve
After economy and visuals, I wanted to observe actual player behavior. In Bunny Circus Analytics, event delivery should be separate from gameplay, and network loss should not change match outcomes.
Implementation in this snapshot
GameAnalytics.TrackEvent writes events to a persistent outbox. A temporary file is moved after writing, and SendLoop posts the oldest file through UnityWebRequest; a success acknowledgement permits deletion.
The design decision and its cost
Temporary failures use increasing retry delays. Authorization errors and redirects pause sending, while permanently rejected payloads move into rejected storage; failures are not treated identically.
Current boundaries
The supplied PHP source implements daily JSON storage, file locks, duplicate checks and reporting. This supports an architectural account; deployment health and successful live traffic still need separate evidence.
Review scenarios and contract meaning
With the PHP source available, the other side of the contract is visible. The API accepts POST with JSON, checks whether the collection key authorizes the game and passes validated data to storage. store_event locks the game’s daily file, while a shared lock serializes the overall event-budget check. Atomic writing uses a temporary file and rename instead of writing over the original directly. Reusing an identifier with identical content does not append again; conflicting reuse raises an error. This check scans the target daily file and should not be described as an unlimited uniqueness index across every day.
An important scenario is losing the response after a successful write: the client does not know the request arrived and sends it again. Keeping event_id and payload unchanged allows same-day duplicate recognition. A full daily file or total budget yields 503 and stops collection temporarily; this version does not automatically erase history. JSON storage is a simple choice for small hosting, but historical reporting loads it into PHP memory and becomes limited as data grows. I explain Bunny Circus Analytics through reviewable contracts without claiming user counts, delivery rates or completed load testing.
Daily placement follows event time, while the server adds received_at separately. Late arrival is not occurrence time, especially when a queue drains after connectivity returns. Both concepts matter for delays and date-range interpretation. A stored record alone does not precisely establish when a player was online.
What this stage taught me
For me, event recording needs honest terminology: queued differs from delivered. The client seeks durability, but end-to-end correctness for Bunny Circus Analytics also requires server verification.




