02 · EloStore ecosystem
CS2 servers
Skin changer, match engine and broadcast
Our own game servers running our own code: skins picked in the site dashboard appear in game by SteamID, tournaments load from the admin, the broadcast gets a live killfeed. 3 own C# plugins, 1,755 lines with no third-party plugins and 0 weapon switches for a skin to apply.
Skins from the dashboard
A player picks a finish in the dashboard on the site, joins the server, and it is already in their hands. These are the same renders the player sees in the dashboard.
Renders from the elostore.ru dashboard












Knives and gloves
The knife model and its finish are applied at the moment the item is given, before the first frame: no weapon switching.





A paint engine of our own
There was no ready way to bake a CS2 finish onto a model for the web, so we spent about a month building the skin changer and our own engine from scratch: the model and the paint come from the game files, the paint formulas repeat the CS2 shader, and every result is checked against the Valve icon.
The interface is recreated: the model and pattern come from the game files, the shader from the engine viewer, the terminal numbers are illustrative
0
finishes built by the engine
0
weapon models from the game files
8
paint styles following the shader formulas

The task
EloStore tournaments and skins needed a server of their own, not someone else's plugins with closed behaviour.
The task: connect the site and the game. A player sets everything up on the site, joins the server, and it is all already there: skins, roster, match phases, broadcast.
Slice by layer
- Interfacethe pixel
- Skins dashboard on the site, tournament brackets, match admin, an OBS overlay
- Logicmoney and rules
- Match phases, map veto, Single Elimination and Round Robin brackets, a broadcast event director
- Dataschema and migrations
- Loadouts by SteamID, a catalogue of skins, agents and stickers, match stats in Postgres
- Serverdeploy and operations
- A dedicated CS2 server under systemd with its own user, RCON closed to the outside
- Securitythe kernel
- A token in the GSI config against forged state, a roster whitelist, token-protected server API
EloSkins skin changer

Players choose weapon skins, knives, gloves, agents and stickers in the site dashboard, and they appear in game.
- 01On player authorization the plugin pulls the loadout by SteamID from the site API, with separate skins for T and CT
- 02Paint is applied at entity creation (OnEntitySpawned) and in the GiveNamedItem hook, before the first frame: knife model and paint land without switching
- 03Paint is set through the native CAttributeList_SetOrAddAttributeValueByName via a gamedata signature
- 04Agent models are precached at map start, otherwise SetModel is unsafe
- 05The !ws command refreshes skins after edits on the site without reconnecting
Result
A skin from the dashboard is in your hands from the very first frame.
EloMatch match engine

Our own port of MatchZy onto EloStore infrastructure: a tournament match is driven from the site.
- 01A match loads from the site with css_eloload: roster, maps, series
- 02Phases: warmup → knife → side pick → live → break → next map of the series
- 03A quiet roster whitelist: outsiders move to spectators without chat spam
- 04The break between maps is set in the admin, every match event feeds the admin timeline
EloDM deathmatch

DM in the style of top public servers, entirely on our own code.
- 01A custom spawn system: teleport to a point where enemies are beyond a threshold, against spawn kills
- 02Instant respawn with spawn protection, +HP per frag, ammo refill
- 03A weapon menu with a saved loadout
- 04Skin changer compatible: DM never touches the knife, only EloSkins issues it
OBS broadcast overlay

Tournament streams get a live killfeed, multikill banners and round recaps.
- 01CS2 sends Game State Integration to the site, the server keeps the last snapshot, the overlay reads a stream
- 02A director compares snapshots and detects kills, aces, clutches, the bomb, round end
- 03GSI does not say who killed whom: pairs are rebuilt from the killer's kills delta and the victim's alive → dead transition
- 04Events fade on their own timers even if the game stops sending data
Stories from production
Incident 01 · open
A knife in slow motion
Swapping the skin broke weapon animation speed: draw and reload played in slow motion.
Incident 02 · open
Skins applied only after a switch
Paint was applied after the weapon spawned, so players had to switch weapons to see the skin.
Stack
C# · .NET · CounterStrikeSharp · Source 2 · GSI · RCON · Next.js API · PostgreSQL · SSE · systemd
