Back

Internship Project

Team Size: 7 ⏱️ 2 Month Internship 🎭 Steam Integration 🎭 Analytics

I've done a 2-months internship for Tiny Toad working with Unity 6.0.
My task were:

  1. Custom Analytics System: Built a system in C# and JavaScript, that track gameplay data and send them to 2 Google Sheets, and a few data to the Discord Server using Webhooks.
  2. Steam API Integration: Implemented an Achievement system managing 66 achievements,  7 Leaderboards, Steam statistics and Cloud Save.
  1. Duration: Started in May 2025 - Jun 2025

Game Overview

██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████

Images & general information's (genre, gameplay, …) will be revealed once the game will be publicly announced.

Tool I used:

UE iconUE iconUE icon

I. Custom Analytics System

Needs: Analytic Tracking System to evaluate player gameplay data and iterate on the game design and balancing.

Solution: Using webhook to send the runtime data into a google spreadsheet that will store and automatically process the data (Using JavaScript and Sheet Formulas).

Benefits:

  • Fully customizable system
  • Fast report from player's game sessions
  • Describe a player's game session/progression
  • Data Distribution helps to understand gameplay trends
  • Identify fast game's sessions with particularities (Best Time, Best Stat, etc.)

The General Spreadsheet

During a game session, two type of data are sent to the spreadsheet:

  • Game Data ► Sent at the end of each games (when the player dies)
  • Session Data ► When the player quit the game

Those data are sent in CSV format and spread into dedicated "data" sheet used for Session, General Game Data, Played Level data's.

Main Page: Proceeded view of the Sessions & Game Data

Session's Player Data

Session's General Stats

Session's Game's Played
(Chains of played levels)

When we change the game version, or just want a total wipe of the data, I've set up a button that clear the whole spreadsheet's data's sheet. (To keep the previous data we just copied the whole spreadsheet into an inactive copy, they are around 0.3 - 1 Mb depending of the data's collected)


First Level Data

For first player experience analysis, I created 2 sheets that process the first level data's.
In order to separate New players from Experienced one, I split the two data based on the amount of Unlocked Item; this value can be changed from the Main Page in the Option's Panel.

A value of 20 means that the player have run at least 20 times the first level, and or spent more than 160 minutes playing the game.

New Player Data in Level A

Experienced Player Data in Level A


Segment Data

A level can be split in multiple segments; I've applied the same technique of data collection from the level to each segments, to have a detailed tracking of player data.
As being an "heavy" CSV file, it cannot be exported to the sheet as the level data per player, so I decided to export it to Discord as a text file.

Then the content of this file is exported (with a simple copy & paste) to a special location in the Spreadsheet that will populate the segment data and automatically process them.

SegmentMain: The data's are pasted inside the "Yellow Box" at the top and after few seconds, graph will be drawn representing selected Data per Segments.

SegmentReader: Once pasted in the "Yellow Box", this data sheet is automatically populated and is used for the graph analysis in "Segment Main".


Player Data

I set up a PlayerViewer sheet to be able to see every game/session made by a player and Item Ranking, to be able to have an analysis per player.
The sheet user can pick a player from a list that is automatically generated based on the game played.

Discord

On the Discord server used for development, I've setup 2 webhook and channels to store a few Runtime data and the location to store segment data's.
The Session ID allow us to retrieve the player data's in those channels.

Runtime Channel: Summarize a few data of the played session.

Segment Channel: Used to get the Segments CSV file of a played game.


Additional Elements

  • When a player start a session, a "Session ID" of 8 random character is assigned, in order to retrieve each sessions/games played.
  • Discord notification are automatically flagged as "silent" to not spam notifications.
  • The Discord Messenger has it's own analytics report system using Scriptable Game Object, to allow which stats to send.
  • Automatic Session ID Link have been set up inside the spreadsheet to reach line of specific proceeded data.
  • When a player leave the game during a level (alt+f4), its associated data line will be in red.
  • I track each Object obtained by the player and do an Elo-Like ranking to sort the most chosen object by the player in function of the situation.
  • Stage_1 sheets has many distribution graph based on the collected data in order to determine player trends.

In this example of Player DPS Distribution, we can see the "Victory Threshold" that is the hard limit if the player has enough damage per seconds to kill the level boss or not.


II. Steam Integration

  • Stats & Achievement manager in C#.
  • Setup of 4 Leaderboards + 3 for the Demo versions.
  • A few task on the Web API: Beta & Internal test builds upload; Stats, Achievements & Leaderboards setup.
  • Generated a Google sheet to manage Beta Test key delivered to testers.
  • Simple Cloud Save setup.

Stats & Achievement Manager

In one script I was able to manage the stats and the achievement check and update.
With 66 achievements, one place to manage them all was the best solution to not have them spread everywhere inside the project.

I created an "Achievement Class" array that contains the achievement data loaded at the game initialization from Steam, and it loop every seconds through a list to check if one ore more condition are met (Completed ones are ignored).

For the demo I added 2 Achievements:
Using the same script, I added a list for the demo achievements to check.


Leaderboards

I've setup 4 leaderboards, that load only when the player needs them.
It also load the "score" leaderboards data at the end of a game in order to display the player ranking at the right of its score.

For the demo I setup 3 leaderboards based on the "normal" ones:
My setup was to use the same Leaderboards ID between each project versions in order to not have additional code to re-write and re-use the current one.


III. Bonus Tasks

  • Created a Tabard mesh & used Unity Cloth simulation, to add simulated cloth pieces on the player character.
  • Made the Leaderboards UI by re-using the same structure made for the other interface elements (Code & Prefab).