DEX®
0%
Full Stack
Engineering
Full Stack Engineer Available 12+ hrs/day

I build the systems games run on.

I design and ship across the stack: 3D and product visuals in Blender, fast interactive web, and game systems that hold up under load. Architecture, motion and craft, verified end to end.

Scroll
OOP ArchitectureServer AuthorityAnti-ExploitNetcodeECSSpatial HashingBlender / CyclesPBR ShadingWebGLReactive UIProcedural GenVFX OOP ArchitectureServer AuthorityAnti-ExploitNetcodeECSSpatial HashingBlender / CyclesPBR ShadingWebGLReactive UIProcedural GenVFX
Working philosophy

Most people ship features. I build interfaces, 3D, and systems that are crafted, performant, and tested until they cannot break.

01 Capability

Production-grade engineering, the way real studios ship it.

Not isolated scripts. Cohesive systems with clean boundaries, deterministic tests, and zero trust in the client.

9
Shipped systems
71+
Automated checks pass
100%
Server-authoritative
0
Known bugs
Engagements

Hired and shipping at two studios.

Active scripting roles on live Roblox games with real players and deadlines, not just personal builds. Server-authoritative systems, shipped on a team.

Hired
Nitrux Studios
Scripter · Jet Simulator

Gameplay scripter on Jet Simulator, a pets and progression simulator. Building server-authoritative systems on a Knit + ProfileStore stack: the nametag system, startup resilience and error handling, and anti-exploit hardening across the codebase.

KnitProfileStoreServer-authoritativeLive game
Hired
Playverse
Programmer · Team C

Programmer on Team C inside Playverse, a large multi-game Roblox group. Building and maintaining gameplay systems across the team's live titles, including Guess My Brainrot, Guess My Anime and Hack a Hive.

Gameplay systemsMulti-game groupLive game
02 Selected Systems

Selected systems.
Each proven against itself.

Server authority, determinism, persistence and tooling. Built the way a studio ships, not the way a tutorial teaches.

Drag / Scroll →
/ 01
Flagship

Tower Defense Engine

Procedurally generated, fully self-playing. Simulation core decoupled from rendering, so the same logic drives a headless test or a live 3D view.

  • Procedural serpentine map generation
  • OOP enemies: armor, slow-resist, boss minions
  • Polymorphic towers: splash, slow, burn, execute
  • Scaling waves, economy, AI commander
25 / 25 runs won, zero errors
/ 02
Combat

Combat System

Server-authoritative combat. The client may only request; the server validates everything and stays exploit-proof.

  • Weapon hierarchy with damage falloff
  • Server-tracked cooldown, ammo, range, sight
  • Dependency-injected clock for deterministic tests
16 / 16 tests passing
/ 03
Data

Inventory System

OOP inventory framework with a full item hierarchy, stacking and weight rules, and clean serialization.

  • Item → Weapon / Consumable inheritance
  • Stack limits, slot and weight caps
  • DataStore-ready serialize / deserialize
13 / 13 tests passing
/ 04
Backend

DataManager

Production persistence with session locking, so two servers can never corrupt the same save.

  • Atomic UpdateAsync with session locks
  • Stale-lock stealing for crash recovery
  • Backoff retry and live schema migration
10 / 10 tests passing
/ 05
UI / UX

Reactive UI Framework

A component library built for responsiveness and disciplined cleanup, scaling to any screen.

  • Maid pattern: connections auto-disconnected
  • Reactive buttons, animated bars, toasts
  • Scale units + text constraints for all devices
All component checks passing
/ 06
VFX

VFX Library

A self-cleaning effects library on TweenService: the feedback layer a game needs.

  • Damage numbers, hit flashes, shockwaves
  • Projectile trails, decaying camera shake
  • Animation-event markers for timing
7 / 7 tests passing
02 Case Study

Tower Defense Engine: a self-playing simulation.

A tower-defense engine built from scratch where the simulation core is fully decoupled from rendering, so the exact same logic drives a headless CI test and a live 3D match. The goal was to prove a Roblox game can be engineered like real software: deterministic, tested and observable.

Role
Solo engineer: design, gameplay, tooling
Stack
Luau, Roblox, Rojo, headless test harness
Scope
~6k lines, 25 automated match runs
Principles
Determinism, OOP, server authority

Problem

Roblox gameplay code usually tangles simulation with rendering, so it cannot be unit tested and balance regressions ship silently. I wanted a game I could prove correct, not play once and hope.

Approach

The core is pure Luau with no Instance or rendering access: grid, enemies, towers, economy and waves are plain data and classes. Maps generate from a seed, towers are polymorphic (splash, slow, burn, execute), enemies carry armor and resistances, and an AI commander plays the whole match headlessly.

Outcome

The same core runs in a headless harness and behind the live 3D view. 25 of 25 self-play matches finish with zero runtime errors, so a balance change is re-validated before it reaches a player. Determinism made the bugs reproducible and the design tunable.

Web Product

PulseWatch: a full SaaS, shipped end to end.

An open-source uptime and status monitoring platform, built solo in Next.js and TypeScript. Scheduled health checks, automatic incident tracking, response-time charts, and shareable public status pages, live and deployed with green CI.

PulseWatch uptime and status monitoring, live product
PulseWatch · Next.js, Prisma, Postgres · live on Vercel
Live
PulseWatch
Full-stack SaaS · Solo build

Monitors websites and APIs on a schedule, records status code and response time on every check, opens and resolves incidents automatically, and serves shareable public status pages. Secure session auth, a Postgres data layer via Prisma, and a cron-driven check engine. Open source under AGPL, with CI on every push.

Next.js 16TypeScriptPrismaPostgreSQLTailwindVercelOpen source
06 Under the hood

Real code. Server-first. Commented.

Game logic is Luau; the web stack is TypeScript end to end. A few representative slices: client/server reconciliation, a typed and validated API boundary, and an optimistic React data hook.

Netcode.luau
-- Client predicts locally, then reconciles to the server snapshot,
-- replaying un-acked inputs so a correction never feels like a snap.
local RING = 128                                -- input history ring buffer
local function reconcile(serverSnap, pending)
    local state = clone(serverSnap)            -- authoritative truth
    local drift = distance(state.pos, render.pos)
    if drift > HARD_SNAP then render = clone(state) end -- teleport / respawn
    for _, cmd in ipairs(pending) do     -- inputs not yet acked
        if cmd.seq > serverSnap.lastSeq then
            state = step(state, cmd, FIXED_DT)  -- deterministic re-sim
        end
    end
    local a = math.min(1, dt / FIXED_DT)
    render = lerp(render, state, a)          -- smooth, no rubber-banding
    return render
end
-- Pack a world delta into BITS, not bytes. A position + id costs ~5B.
function BitBuffer:writeUInt(value, bits)
    for _ = 1, bits do
        self.acc = bit32.bor(self.acc, bit32.lshift(value % 2, self.n))
        value, self.n = value // 2, self.n + 1
        if self.n == 8 then self.bytes[#self.bytes+1], self.acc, self.n = self.acc, 0, 0 end
    end
end
function BitBuffer:writeVarInt(v)              -- 7 bits + continue flag
    repeat local b = v % 128; v = v // 128; self:writeUInt(v > 0 and b+128 or b, 8) until v == 0
end
-- Archetype ECS: entities grouped by component signature for
-- cache-friendly iteration. A query is a bitmask test, not a lookup.
local mask = Component.Position | Component.Velocity
for _, arch in ipairs(world.archetypes) do
    if bit32.band(arch.signature, mask) == mask then
        local pos, vel = arch.cols.Position, arch.cols.Velocity
        for i = 1, arch.count do
            pos[i] = pos[i] + vel[i] * dt        -- tight contiguous loop
        end
    end
end
-- Server rewinds every player to the shooter's render time,
-- so a hit that looked true on the client is validated fairly.
local function validateShot(shooter, origin, dir, clientTime)
    local t = clamp(clientTime, now - MAX_REWIND, now)
    for _, target in ipairs(candidates(origin, dir)) do
        local box = rewindHitbox(target, t)    -- historical position
        local hit, dist = rayBox(origin, dir, box)
        if hit and dist <= weapon.range then
            if not lineOfSight(origin, box.center) then continue end
            local dmg = falloff(weapon, dist) * zoneMul(box.part)
            return { ok = true, id = target.id, dmg = dmg }
        end
    end
    return { ok = false }                       -- reject; never trust the client
end
// POST /api/match/:id/score - typed, validated, authenticated.
// One DB transaction: never half-write a leaderboard row.
const Body = z.object({ score: z.number().int().min(0), runId: z.string().uuid() });

export const submitScore: Handler = async (req, reply) => {
  const user = await requireUser(req);            // 401 if no valid session
  const body = Body.parse(req.body);              // 400 on bad shape
  const match = await db.match.findUnique({ where: { id: req.params.id } });
  if (!match || match.ownerId !== user.id) return reply.code(403).send();

  return db.$transaction(async (tx) => {
    await tx.score.upsert({
      where:  { runId: body.runId },                 // idempotent on retry
      create: { runId: body.runId, userId: user.id, value: body.score },
      update: { value: body.score },
    });
    const rank = await tx.score.count({ where: { value: { gt: body.score } } });
    return reply.send({ ok: true, rank: rank + 1 });
  });
};
// Optimistic React hook: paint the guess instantly, reconcile to the
// server, and roll back cleanly if the socket rejects the write.
export function useLiveQuery<T>(key: string, initial: T) {
  const [data, setData] = useState<T>(initial);
  const socket = useSocket();

  useEffect(() => socket.subscribe(key, setData), [key]);   // server is truth

  const mutate = useCallback(async (next: T) => {
    const prev = data;
    setData(next);                                // optimistic paint
    try {
      await socket.send(key, next);                 // await server ack
    } catch {
      setData(prev);                              // rollback on reject
    }
  }, [key, data]);

  return [data, mutate] as const;
}
03 3D / Environments

Architecture, modeled & lit in Blender.

Seven buildings on a shared downtown block, modeled from primitives with distinct PBR materials (warm concrete, sandstone, red brick and tinted curtain-wall glass), recessed windows and rooftop plant, lit by a low golden-hour sun. Rendered in Blender (Cycles).

Seven-building downtown block at golden hour, rendered in BlenderBLENDER · CYCLES
Office tower with tinted curtain wall
01 Office Tower · Tinted Curtain Wall
Brick and sandstone mid-rise
02 Brick & Sandstone Mid-Rise
Concrete block with banded glazing
03 Concrete Block · Banded Glazing
03 Game Assets, Weapons

A game-ready weapon set, modeled from scratch.

Nine weapons modeled from scratch with real proportions and beveled edges, in PBR steel, gunmetal, brass, leather and wood, rendered top-down in Cycles as a clean inventory sheet. Hover any name to inspect it, or click the frame for the full set.

⛶  View full set
Weapon 01 / 09
Longsword

Double-edged steel blade, brass crossguard and pommel, leather-wrapped grip.

SteelBrassLeather
LongswordDaggerCombat KnifeBattle AxeWar HammerSpiked MaceSpearBowPlasma Blaster
04 Roblox Engineering

Hard systems and a procedural world.

Server-authoritative Luau built for scale, area-of-interest replication, flow-field pathfinding for thousands of agents, and a deterministic procedural dungeon generator. The fortress below is key art for that world, modeled and lit in Blender (Cycles).

Fairytale castle fortress modeled and rendered in Blender
Castle fortress · modeled & lit in Blender (Cycles)
Blender / CyclesProcedural PBR stoneDisplaced alpine terrainModeled from scratch
04 Production Luau

Three systems that scale.

Flow-field pathfinding

One Dijkstra pass per goal feeds an O(1) per-agent lookup, so thousands of units share a single field instead of each running A*.

FlowFieldPathfinding.luau
-- Thousands of agents, ONE
-- shared field. Dijkstra from
-- the goal; each agent just
-- reads the downhill slope.
while #heap > 0 do
  local i, c = pop()
  for _, n in ipairs(DIRS) do
    local nc = c + cost[n] * n.w
    if nc < integ[n] then
      integ[n] = nc
      push(n, nc)
    end
  end
end

AOI replication streamer

Entities live only on the server. Each player gets spawn / despawn / delta updates for what is inside their interest radius, via a spatial hash.

ReplicationStreamer.luau
-- Relevancy is ~O(nearby),
-- never O(all entities).
for dx = -span, span do
  for dz = -span, span do
    local b = cells[key(cx+dx, cz+dz)]
    if b then
      for id in pairs(b) do
        if within(id, p) then
          now[id] = true
        end
      end
    end
  end
end

Procedural dungeon

A seedable LCG rebuilds the exact same dungeon on the server and every client. Rooms are linked by an MST of L-shaped corridors.

ProceduralDungeon.luau
-- One seed, same dungeon
-- everywhere (Park-Miller).
local rand = rng(opts.seed)
for _ = 1, maxRooms * 6 do
  local r = randomRoom(rand)
  if not overlaps(r, rooms) then
    carve(grid, r)
    rooms[#rooms+1] = r
  end
end
connectMST(rooms, grid)
05 Interactive

A live sandbox. Move your cursor, the field reacts.

Hand-built Canvas 2D particle system, no library. The cursor repels the field and weaves cyan links to nearby nodes in real time.

Raw requestAnimationFrame · mouse-reactive · 60fps

07 Contact

Let's build
something real.

benwebbuilds@outlook.com
DISCORD · dexspecialROLE · FULL STACK ENGINEERSTATUS · AVAILABLE