// ROBLOX PROGRAMMER · NETWORKING & SIMULATION

Combat that feels the same at 150 ping as it does at 0.

I build server-authoritative systems for Roblox from scratch: combat with prediction and reconciliation, lag compensation, anticheat that doesn't trust the client, and simulations big enough to break a normal server. Most of my work is systems that don't exist yet. When something you already have is slow, desyncing or exploitable, I fix that too.

~0 ms
added parry delay at 150 ping, server-authoritative
500+
units per battle at 60+ FPS, resolved headless on the server
100%
server-side logic; the client only renders
<24 h
typical reply on Discord, GMT+3
// CASE STUDIES

Three systems, and how they were built

Each of these is a networking or simulation problem that most Roblox projects either give up on or ship broken. Each one comes with the comparison against the way it's usually done.

"

Good code isn't just code that works. It's code that's modular, exploit-proof and fast. That's the part you're actually paying for.

// HOW I BUILD
COMMISSIONED · SHIPPED

Parry-based combat that survives ping

A full melee kit (parry, block, posture, perfect dodge, hotbar abilities, aerials) built around parry timing, the one mechanic that breaks hardest when players aren't on fibre.

LAG COMPENSATION SERVER REWIND ANTICHEAT

THE PROBLEM

In most Roblox games, parrying above 100 ping is effectively impossible. The input has to travel to the server and back before anything resolves, so a correct read still registers as a miss. Studios usually "fix" this by letting the client decide, which hands exploiters the whole combat system.

THE APPROACH

The client plays the parry instantly, but only as a prediction; it never decides the outcome. The server stores a short history of both players' states, then rewinds them to the exact tick each input was made and judges the exchange there. Mispredictions reconcile back silently.

THE RESULT

A parry at 150 ping is judged identically to one at 0, with no round-trip delay for the player. The server stays fully authoritative, so nothing on the client is worth exploiting.

WHAT SHIPPED WITH IT

Parry. Negates the attack's damage entirely and puts the damage into the attacker's posture instead.
Block. Takes chip damage through the guard and feeds the posture-break bar.
Perfect dodge. Available against most attacks, with iframes on the opening frames of the dodge only.
Limited true stun. You can still parry or block mid-string, so light attacks never become a free combo.
Hotbar. Up to nine items, abilities or weapons, usable whenever the player wants, RPG-style rather than fixed slots.
Aerials. Air variants of both light and heavy attacks, taken from the same input in the air.
// TRY IT Same input, two architectures

Set a ping, then hit parry as the attack crosses the window. The naive lane sends your input to the server and judges it on arrival. The rewind lane judges it at the tick you actually pressed. Both are server-authoritative in the second case; the difference is when the server thinks you pressed.

PING 150 ms
CLIENT SENDS → SERVER JUDGES ON ARRIVAL READY

Your press is judged half a round trip late, so the attack has already moved past the window.

CLIENT PREDICTS → SERVER REWINDS AND JUDGES READY

The server keeps a short state history, rewinds to the tick you pressed, and judges the exchange there.

PRESSED AT -
NAIVE JUDGED AT -
REWIND JUDGED AT -
TIMING ERROR IMPOSED BY PING -

Run it and the player reads the attack perfectly: the input lands dead centre. Everything after that is ping. Against a 120 ms window, the naive lane stops being able to parry above about 120 ping; the rewind lane never does. Drag the slider down to 40 and watch the difference disappear. That's the honest version of this claim.

WHAT THIS DEMO DOES AND DOESN'T SHOW

The parry window here is 120 ms wide, which is roughly a tight-but-fair window in a melee game. Ping is treated as symmetric, so the client-to-server trip is half the number on the slider. Nothing else is simulated: no jitter, no packet loss, no tick quantisation. All three make the naive lane worse, not better.

What it demonstrates is one thing only: with a fixed window, the naive lane's judgement point drifts by ping / 2 while the rewind lane's does not. That is the whole argument, and it is the same argument the shipped system makes.

SOLO · ~300 HOURS

Headless battle engine for an auto-battler

Multiversal War RNG: entire battles resolved as pure deterministic computation on the server, then replayed on the client from an event log.

ECS DETERMINISTIC SIM EVENT-LOG REPLAY

THE PROBLEM

The obvious build spawns every unit as a physical character on the server, runs pathfinding on each one and replicates its state every frame. That dies in the low hundreds, and every unit it does spawn is another object sitting on the client for an exploiter to read or edit.

THE APPROACH

No models on the server at all. The battle is resolved as a deterministic computation on a 2D plane: state lives in small ECS components per unit, and a set of systems ticks through them until a side wins. The server emits a structured event log (spawns, movement, attacks, deaths) and the client replays it, spawning models, interpolating movement and firing effects. AI comes from templates keyed on unit type and rarity, with combat built on reaction time against wind-up time: telegraphed heavies, dodges, parries, feints and counters.

THE RESULT

500+ unit battles run at 60+ FPS in a live server. The client never holds authority; it's replaying a log the server already finished, so there is no game state worth editing. The engine emits signals independently of the UI, which is how rolling, upgrades and the economy hang off it without touching combat.

// HOW MANY UNITS FIT 130 units the usual way. 6,300 with this system. MATH MODEL · NOT A LIVE BENCHMARK

Same server, same 60 frames a second. The usual approach gives every soldier its own model, its own pathfinding and its own replicated state, and runs out of frame at about 130 of them. Headless ECS state runs out at about 6,300.

48×
more units per server before the frame budget runs out: 130 the usual way, 6,300 here. The shipped game runs 500+ unit battles at 60+ FPS; the numbers below are calculated from per-unit costs.
PER-INSTANCE (THE USUAL WAY) HEADLESS ECS + EVENT REPLAY (THIS SYSTEM)
ARMY SIZE 500
THE USUAL WAY
-
THIS SYSTEM
-
HOW THESE NUMBERS ARE CALCULATED

Per-instance. Each unit is a rigged model on the server with its own animator, humanoid-style movement, its own target search and its own replicated state, about 0.12 ms of server step time each once movement, animation state and replication bookkeeping are counted, plus an term for target searching without a spatial partition. Against a 16.6 ms frame that ceiling lands at ~130 units.

Headless ECS. No instances on the server at all: flat component arrays stepped by a handful of systems, target search through a grid, and state sent to clients as an event log rather than n property updates per frame. About 0.0025 ms per unit plus a fixed 0.8 ms per tick that doesn't grow with the army, so ~6,300 units in the same frame.

Bandwidth, which the chart doesn't show. A per-instance CFrame plus state costs 40–50 bytes per unit per replication tick, which passes a normal player's downstream budget somewhere between 50 and 100 units, usually before the CPU does. Delta-encoded batched state at 6–8 bytes per unit, with distant units aggregated, keeps thousands inside the same budget.

Where the numbers come from. These are calculated from known per-unit costs rather than recorded from a live test place, which is what the model tag means. The ratio is the claim: one approach has a ceiling in the low hundreds, the other doesn't hit one at the scales this game runs at.

SOLO · ~100 HOURS

An 8-bit computer, inside Roblox

A logic-gate sandbox containing a working SAP-2 CPU that runs real assembly, and plays Bad Apple.

LOW-LEVEL LOGIC PERFORMANCE TOOLING

THE PROBLEM

Evaluating thousands of interconnected logic gates every tick is exactly the kind of workload that tanks a Roblox server if it's written the obvious way, with every gate polling its neighbours.

THE APPROACH

Gates are compiled into an event-driven graph so only the parts of the circuit that actually changed are re-evaluated, with propagation ordered to avoid redundant passes. On top of that sits a full SAP-2 instruction set and assembler.

THE RESULT

Players build circuits complex enough to execute assembly programs and stream video, in real time, without the simulation becoming the bottleneck.

// WHAT THE COST SCALES WITH A running 8,000-gate CPU, once per tick MATH MODEL · NOT A LIVE BENCHMARK

Polling costs the same whether the circuit is idle or busy, because every gate is visited every tick. Event-driven costs only what actually changed: on a running CPU, well under one percent of the board.

165×
cheaper per tick on the same circuit: 20 ms polling everything, 0.12 ms re-evaluating what changed. One of those fits in a frame. Calculated from per-gate cost.
POLL EVERY GATE, EVERY TICK · COST GROWS WITH BOARD SIZE RE-EVALUATE WHAT CHANGED · COST GROWS WITH ACTIVITY
HOW THESE NUMBERS ARE CALCULATED

Per-gate cost. Roughly 0.0025 ms to read a gate's inputs, evaluate it and write its output in Luau: a table lookup, a couple of comparisons and a store. Polling pays that for every gate on the board, 60 times a second, no matter what the circuit is doing: 15% of the frame at 1,000 gates, 60% at 4,000, past the whole frame at 8,000.

Changed fraction. On a clocked SAP-2 running a program, the gates whose inputs actually change on a given tick are the ones on the active path: a bus write, a register latch, a handful of decode lines. That's the ~0.6% figure used here. Idle circuits go to nearly zero; a deliberately pathological board with a clock wired into everything converges back toward the polling line, and that's the honest limit of the claim.

Frame budget. 16.6 ms per step at 60 Hz, and the chart shows tick cost as a share of it. Polling's share is set by how big your circuit is; event-driven's share is set by how much of it is doing anything. These are calculated from per-gate cost rather than recorded from a live test place, which is what the model tag means.

// OPEN SOURCE

Mirage

The prediction layer from my commissioned work, packaged, documented and released free for anyone to use.

Mirage
wally = "aslyumm/mirage@0.1.0"

Client-side prediction and reconciliation for any custom state you stream from the server. Your game keeps a single source of truth on the server, and players stop feeling their ping. Documented, published on Wally, and released on the DevForum.

// ALSO BUILT

Other systems

Command-based ballistics

Projectile system driven by a command layer, built as an interview project. Deterministic firing solutions with server validation.

WATCH ↗

Grid building + surface UI

Snap-based placement with live surface interfaces, built to test a placement pipeline for a base-building game.

WATCH ↗

Electromagnetism simulation

Field lines, charges and forces solved per-frame at real scale, running inside Roblox physics.

PLAY ↗
// COMMISSION PRICING

Pick the shape of the job. Get a scope.

Start with what you want built: a system that doesn't exist yet, a whole backend, a fix, or a pentest. If something is already misbehaving, add the symptoms and the panel works out what's likely causing it, what I'd build, and roughly what that costs.

// SHAPE OF THE JOB · START HERE

Most of this is building. Repairs and pentests live in the same list.

// ANYTHING MISBEHAVING? · OPTIONAL

Only if something already exists and isn't working. Things a player or playtester would notice.

// OPTIONAL EXTRAS

Genuinely optional. Everything above already includes the engineering.

These are starting points, not fixed quotes; the real number comes after I've looked at the place file, and it can go down as easily as up. The 30% is for the next three commissions I take, and it's already in the number above. If it still doesn't fit your budget, tell me the budget and I'll tell you honestly what fits inside it.

// HOW IT GOES

Working with me

01 / SCOPE

We write it down

What the system does, what it doesn't, and what "done" means. Nothing starts before this is agreed in text, so neither of us is guessing later.

02 / SCHEDULE

Hours and deadline

We agree how many hours a day go to your project. If I'm unavailable, you hear it in advance and you hear why.

03 / BUILD

Visible progress

Work lands in milestones with a video or a test place you can open each time. If a milestone isn't right, we fix it before the next one starts.

04 / HANDOFF

Yours to maintain

Commented, modular code plus a walkthrough of how it fits together, so your team can extend it without me.

// BEFORE YOU ASK

Common questions

How does payment work, and what protects me?

Half up front, half on delivery, so neither side is carrying the whole risk. What protects you specifically: the scope is written down before anything starts, work arrives in milestones with a test place you can open, and if the first milestone isn't what we agreed you can stop there: you've spent half, and you keep what was delivered. On larger jobs I'll split it into more milestones so the amount exposed at any one moment is smaller.

Robux and currency are both fine. Robux is usually simpler for both of us: a bank transfer into Turkey means both sides handing ID and account details to a processor and to each other, and for a first commission neither of us needs to be holding the other's documents. If you'd rather pay in currency, say so and we agree the method before anything starts.

Robux is always converted at the DevEx rate (the rate I actually receive), not the purchase rate.

Can you take payment from group funds?

Yes, for the second half. Group payouts can be pulled back by the group owner after the work is delivered, which is the one route where I'd be carrying all of the risk, so the up-front half comes through a route that can't be reversed. Everything after the first delivered milestone can come through the group.

If you'd rather not send anything directly to someone you haven't worked with, the fairer version is a small first milestone: a few hours of work, paid and delivered, so you see how I work before committing to the rest. I'd rather do that than have you take a leap.

What if the result isn't what I wanted?

Revisions against the agreed spec are included: if it doesn't do what we wrote down, it isn't finished, and I'm not asking for the second half. If you want something outside the spec, that's a new small scope and I'll price it before touching it rather than after.

If we get to the first milestone and you'd rather not continue, that's a clean stop. You keep the code from that milestone and owe nothing further.

Do you do revenue share?

No, paid work only. I'm happy to price in milestones so a larger project can be paid down in stages instead of all at once.

Do you use AI?

Never for systems, logic, networking or anything I'm hired to engineer. That's the work, and it's written by hand. I don't do UI design and don't count it as a skill of mine, so if a project needs interfaces, bring your own designer or assets and I'll wire them to the systems.

What's your availability?

Based in Turkey, GMT+3, generally free through the day. I'm in a long-term position at the moment but I do take on additional work; whether that fits depends on the hours involved, which we agree on before anything starts.

Who owns the code?

You do, once it's paid for. Reusable pieces that aren't specific to your game may end up generalised into an open-source package later (Mirage started that way), but your systems, assets and design stay yours.

// LET'S BUILD

Tell me what you want built

Send the game, what you want it to do, and a budget range. You'll usually hear back the same day.

Add me on Discord with the handle above, or message me on the DevForum if you'd rather keep it in one place. If you used the estimator, paste the brief it gave you; that's usually enough for me to reply with a real number.