Jerry Medina

Roblox games and contract work

I've been building Roblox games since 5th grade. My games have 25M+ combined visits, I've sold some of them, and studios bring me onto games under NDA to build features and fix bugs.

WhenSince 5th grade
RoleLead developer on my own games; contractor on others
StackLuau, object-oriented programming, client-server networking, server-side validation, lag compensation, binary packet serialization, DataStores (persistent storage), MemoryStore (shared cross-server state), distributed locking, data migrations, matchmaking
Highlights
  • 25M+ combined visits
  • Dig and Shoot: 1.7M+ visits in one month, about $3.5K a month
  • Invited to the Roblox Developers Conference at 16

How I got here

I started building on Roblox in 5th grade. I did debugging work on Dress to Impress in its early days, and that led to contract work. Studios bring me onto games under NDA to build one feature, fix a bug, or handle a specific process, and the contract ends when that’s done.

I also build my own. Dig and Shoot, made with YouTube creator RiceGum, reached 1.7M+ visits in one month, peaked at 1,000 players at once, and made about $3.5K a month. I later sold it. Moo Legacy is at about 17M visits. I designed the systems the game runs on and managed two other programmers.

Dig and Shoot artwork of a player holding a gem next to a player with a sniper scope
Dig and Shoot, the game I made with RiceGum.
Dig and Shoot artwork of a player shooting from a dug-out block trench
Players dig through the block map and fight from the tunnels they make.

At 16, Roblox invited me to the Roblox Developers Conference, which is for top creators on the platform. I couldn’t go because of my age.

Why I built a shared framework

I kept making multiplayer shooters: Dig and Shoot, TowerDown (teams shoot down each other’s block towers), and OneShot (one bullet in the chamber). Each one needs weapons, networking, saved player data, and rounds. Rebuilding all of that for every game wastes time and brings back old bugs, so I wrote it once as an object-oriented framework the three games share. Game modes are classes that extend one base mode and override only what’s different, like spawning, loadouts and hit rules.

A multiplayer game is a client-server system with many untrusted clients, bad connections, and many servers sharing one database. The problems below show up in most backend work too.

Engineering problems

Never trust the client

Every player runs the game on their own device, and anything that device sends can be faked. If the server accepts whatever hit a client reports, cheaters win. The client and server both simulate each bullet’s speed and drop. The server replays the bullet’s path from the known starting point and only accepts a hit if it matches what the client reported. It also rejects requests stamped with an impossible time and enforces each weapon’s fire rate itself, so a modified client can’t fire faster than the game allows.

Lag compensation

Because of network delay, every player sees the world a split second in the past. The server records where each character was 30 times a second and keeps the last half second of history, so a hit is checked against where the target was when the shot was fired, not where it is when the message arrives. Shots older than 400 ms are thrown out, which limits how much lag a player can use to their advantage.

Distributed locks on player data

Many game servers share one database. If a player jumps between servers quickly, two servers can write the same player’s data and one can overwrite the other. Each player’s record is locked to one server at a time, and the lock expires on its own after 30 seconds if that server crashes, so a crash never leaves a player locked out. Loads retry up to 5 times, records saved in an older format are migrated to the current one when they load, and every open record is saved when a server shuts down.

Shared state across servers

Some data has to be consistent across every server at once. The daily reward system keeps its cooldowns in a shared in-memory store, and each claim is a single atomic operation, so a player can’t claim the same reward twice by joining two servers. For matchmaking, each server publishes its players’ average skill rating, so new players get routed to servers near their level.

Smaller network packets

In my tower-defense framework, a server may need to track huge numbers of enemies. Sending every enemy’s position on every update would flood the network. Instead, the server and every client share a clock and the map’s path, so each client works out enemy movement on its own. The server only sends when an enemy appears or dies, packed into one compact binary message per update instead of one message per enemy. The simulation runs on a fixed tick with seeded randomness, so every machine computes the same result. Enemy data lives in flat arrays instead of one object per enemy, which keeps each update fast.

Server-side AI

TowerDown’s bots run on a behavior tree, a common way to structure game AI as small reusable decisions: pick a target, aim, shoot, reload, move. OneShot’s bots use pathfinding with custom moves for sliding and opening doors.