Studfall - Wave Breaker

Systems designEncounter designTechnical design

A brick-breaker roguelite for Fortnite where the balls fire on their own: you move and aim, and the skill is reading the angles.
Designed and shipped solo in three weeks for Epic Games' UEFN Student Bootcamp 2026.

My part
Solo developer · design, systems, balance, playtests, publishing, trailer
Time
3 weeks · Aug 2026
Engine
UEFN · Verse, Scene Graph
Live
Since 14 Aug 2026 · PC, mobile, Switch 2
Watch the gameplayWatch the trailer

01Overview

The 30-second version

The brief

Build a LEGO® island for Epic Games' UEFN Student Bootcamp 2026. Judged on three things, below: what I did for each, and how it went.

The constraints

  • Three weeks, soloFive days of training, two weeks to build.
  • No rigid bodiesScene Graph has no physics to lean on: every bounce is arithmetic.
  • Phones tooFortnite runs on mobile and Switch 2: a full wave holds 60 fps on a Galaxy S26 Ultra.

The brand in the play

What I did

Brick enemies and studs to collect: the LEGO® idea flipped from building to breaking.

How it went

partly

The break-apart polish was cut for time.

The first minutes

What I did

Straight into play: from the hub, the first kill comes at 12 seconds and the first upgrade at 24.

How it went

held

68% of launch-day sessions went past two minutes (43 sessions).

A reason to replay

What I did

Saves between runs from day one. The boss (17 Aug) and a second class bought with studs (19 Aug) came after launch.

How it went

missed

4.65% of launch-day players came back the next day (two). 70% of sessions ended within five minutes: about one run.

02The game

You never pull the trigger

You control two things: where you stand and where you aim. The balls fire on their own and the waves walk toward you, so the skill moves from reacting to reading: you don't die to a missed input, you die to an angle you judged wrong. Inspired by modern brick-breaker roguelites.

That only works if the aim line never lies. Preview and live ball run the same simulation, so the line you see is the shot you get.

Three pressures, not a difficulty ladder

Each enemy threatens something different, so a wave gets harder in more than one way.

Lancer health

Kill it before it crosses the line: one that gets through damages you.

In the clip a Lancer gets through and damages the player.

Tank time

Tankier than the rest: more HP, and a shield that blocks every shot to the face. It eats shots meant for others and forces you off the straight line.

In the clip shots to the face bounce back; a bank shot off the wall kills it from the side.

Mage attention

Fires a telegraphed fireball at where you were: the reason movement matters.

In the clip the fireballs aim where you were; step aside and they fly past.

The arena from above

Shapes in the drawing: LancerTank, shield in orangeMage
1234512345
  1. 1Enemies spawn off-camera: no wave pops in.
  2. 2Seven lanes, walking toward you at a set pace.
  3. 3Crash line: an enemy that crosses it hits you.
  4. 4You move freely and aim; the balls fire on their own.
  5. 5Tank shields face you: go off the wall, in from the side.

The Thunder Lord walks in

He walks down the corridor while your fire holds, and only then does his bar appear. Two phases.

Phase 1. He either brings the hammer down, telegraphing which lanes it will flatten (one always safe, never the same twice), or fires a fan of 13 bolts with gaps to read.

Phase 2. He powers up both attacks, chaining them in threes, and spawns five orbiting spheres that eat your balls and hurt you if you get close.

The second class is a trade-off

Finish one run and a statue appears in the hub. The second class is a trade-off: you give up free movement for a rail and a paddle, and fire more slowly. In return, the balls that come back can bounce off your paddle and go in again at ×1.5 damage.

The loops

A level-up offers three cards, each a random stat boost (damage, speed, health or studs): a stand-in for the build of balls in the postmortem.

ShootWaveRunMeta
  1. Shoot loopa ball every 0.4 s↻ next ball

    • Move and aim
    • Bounce
    • Hit or kill
  2. Wave loop20–40 rows↻ next level-up

    • Kills give XP
    • Level up
    • Pick 1 of 3 upgrades
  3. Run loop4–5 minutes↻ again, faster

    • Wave 1
    • Wave 2
    • Wave 3
    • Boss
    • Cash out or continue
  4. Meta loopbetween runs↻ next run

    • Studs banked
    • Buy a class
    • Play another class
    • or another level planned
Show the tuning sheet
SystemValuesWhy
Fire and ballone shot every 0.4 s · 1,600 units/s · up to 16 balls in flight · 20 bounces · aim cone ±70°The fire never stops; 16 balls, not 50, so phones hold 60 fps.
LancerHP 20 · crash 25 · XP 10Cheap to kill, expensive to ignore.
TankHP 50 · crash 10 · XP 25 · frontal immunity · max 4 per row, never in adjacent columnsHP went 80 → 50 after measuring ~43% frontal contacts.
MageHP 20 · crash 10 · XP 15 · a fireball every 3 s at 400 units/s, flying 900 units past its targetAims where you were, so a dodge reads as a dodge.
Waves20 / 30 / 40 rows · a row every 1.65 s · 11 s pause · Tanks/Mages 0/0 → 15/5 → 20/15%The row interval is derived (grid step ÷ speed), never hand-tuned.
Loops (each restart, harder)enemy speed 105 / 110 / 115% · HP ×1.3 per loop · crash damage ×1.5 · partial heal of 25–50 between wavesHP grows slowly; speed and crash damage carry the difficulty. A full heal erased every mistake.
Boss (Thunder Lord)HP 2,000 · phase 1: a hammer on 2 of 3 lanes (1.2 s warning) or a fan of 13 bolts over 180° · phase 2 at 50%: both attacks chained in threes, 5 orbiting spheres that eat balls and hurt up close · 0.8 s of invulnerability after a dodgeable hitOne safe lane, never the same twice. The invulnerability never covers a crash.
Paddle Brick200 studs · paddle 16 studs wide · fire rate ×0.75 · returning balls ×1.5 damagePriced to be reachable in one run during judging.
Economy~210 studs per base run · fixed XP per kill · score = damage dealt, credited on the killA kill pays at once, not on average.

03How it's built

Follow one shot

There is no physics to lean on: Scene Graph, the system that holds the island's objects, has no rigid bodies. So every shot is worked out by hand, in five steps, and each step belongs to one module.

  1. You aim AimController

    Where the shot starts and where it points, inside a ±70° cone.

  2. The line is drawn TrajectoryPreview

    It asks step 4 for the path and draws it as dots.

  3. A ball leaves every 0.4 s BallController

    Up to 16 in flight, each one leg at a time: from where it is to the first thing it meets.

  4. The path is worked out BounceMath

    123
    1. Step through the enemy grid, cell by cell (the shaded cells).
    2. Stop at the nearest contact: a wall, an enemy, the boss or the paddle.
    3. Bounce on the edge it crossed: a side edge flips it left–right, a front edge flips it back.

    Why The line in step 2 and the ball in step 3 ask this same function, so they cannot disagree: the path the line draws is the path the ball takes.

  5. Damage, then the next leg BallController

    At each contact the damage lands first, then the ball relaunches from there, up to 20 bounces. Every leg looks again at where the enemies are: they walk about 20 times slower than the ball.

Try the aim in your browser

Tap the arena to aim and shoot, or drag sideways and lift your finger.Move the mouse to aim and click to shoot, or press Fire. The left and right arrow keys aim too.

The dotted line and the ball call the same function: it steps through the grid cell by cell and reflects on the axis it crossed. Side walls bounce; the far end and your end let the ball go.

Bricks hit: 0

A sketch of the idea, rewritten for the web: grid, walls and contact rules simplified, no enemy movement.

Around the shot

Three more pieces keep the arena the same for everyone who reads it.

Scene managerone device

Runs everything else: the hub, the waves, progression and saves, the HUD, the boss and the classes.

Why The arena's edges come from five markers placed in the editor, not from numbers in the code: they moved several times during development and the code never changed.

Why Saves carry a version number, so the second class could arrive five days after launch without breaking anyone's progress.

EnemyMovement

One fixed-speed move per enemy, from spawn to the crash line.

Why The gap between rows is worked out from the grid step, so rows stay together at any speed.

MovementConstraint

Keeps you inside the arena; the rail for Paddle Brick.

Why It uses the same arena edges, so when the markers moved, the player's walls moved too.

What it costs Profiled in the editor on 18 Aug: a per-frame task should run 300 times in a 10-second window, the server's 30 ticks a second. In the densest wave the three heaviest ran about 241 times: roughly 20% of their frames skipped, in bursts. The cost grows with the number of enemies, not with the boss; I left it.

04Playtests

Playtests: what testers found, what I changed

Three rounds on private builds before launch (11–14 Aug), with two external testers on Discord playing with no context from me. Round 1 was called “Testing the first minute”: the bootcamp's LEGO® island brief judged the first minutes of play.

The first minuteshipped build

Seven findings

6 changes shipped (4 before launch, 2 in the second update), 1 left open on purpose.
Open a row for the full card.

  1. Too many Tanks at once

    Tester · round 2Fixed 13 AugTanks never in adjacent columns, at most 4 per row; HP 80 → 50.
    Observed
    A tester found the Tanks too hard: running into many of them at once was frustrating, and they asked for a rebalance.
    Cause
    A fair point: shields face you, so a crowd of Tanks leaves almost no angle that works.
    Change
    I took the feedback and changed the spawn rules: Tanks never in adjacent columns, at most 4 per row. And since ~43% of hits were landing on the shield, their HP came down from 80 to 50.
    Evidence
    The diagram: where Tanks could spawn in the 12 Aug build, and in the shipped one.

    Where Tanks may spawn

    12 Aug buildTanks could spawn side by side

    Worst case: a full row of shields. Every angle meets one.

    ShippedNever in adjacent columns, max 4 per row

    Every Tank keeps a free column beside it: an angled shot reaches its side.

    • Shield: blocks hits to the face only
    • Crash line
    The main fix is where Tanks may spawn; their HP also went 80 → 50, after measuring ~43% frontal contacts.
  2. The upgrade popup stole the controls

    Tester · rounds 1–2Fixed 13 AugThe run pauses while you choose. Upgrades only at the end of a wave would have meant a rebalance.
    Observed
    With the three cards open, the character froze while enemies kept walking.
    Cause
    The friction was real; the suggested fix (upgrades only at the end of a wave) was not a UX fix. Several level-ups could pile up before a wave ended, and moving them all to the end would have been a design change: the balance and the stats would have had to change with it.
    Change
    The run pauses while the choice is open: enemies and balls hold, then resume.
    Evidence
    Clips: the 11 Aug alpha, then the shipped build.
    Before, 11 Aug alpha: cards open, bricks still walking.
    Shipped: cards open, the run holds.
  3. The aim line was lying

    My tests · round 1Fixed 12 AugThe line and the ball run the same function.
    Observed
    The trajectory preview didn't bounce off enemies the way the real ball did.
    Cause
    Two pieces of code drew the line and moved the ball, and they disagreed.
    Change
    Preview and ball call the same function. The line is the shot.
    Evidence
    The 11 Aug alpha, below; How it's built shows the shared function.
    Before, 11 Aug alpha: the dotted line runs through the first brick.
  4. Fireballs vanished mid-air when dodged

    Playtest · round 2Fixed 13 AugThey fly 900 units past the target.
    Observed
    Mage projectiles stopped exactly where the player had been.
    Cause
    Correct and unreadable: a dodge didn't look like a dodge.
    Change
    Projectiles fly 900 units past the target.
    Evidence
    The Mage clip, below.
    Shipped: the fireballs fly past where you were.
  5. Touch buttons sat on the aim zone

    My tests · from round 1Update 2 · 19 AugFire buttons off for touch players: firing is automatic anyway.
    Observed
    On phones, the native fire buttons covered exactly where you drag to aim.
    Cause
    A known issue from the first build: on touch, aiming is the input.
    Change
    Fire buttons disabled for touch players (they stay visible, translucent): firing is automatic anyway.
    Evidence
    Shipped build on a Galaxy S26 Ultra, below.
    Galaxy S26 Ultra, shipped build: the native buttons on the aim side stay translucent.
  6. Health carried over between runs

    My tests · after launchUpdate 2 · 19 AugHealth back to the maximum at the start of every run.
    Observed
    Found in a private test: after a won or banked run, the next one started with the HP you finished on, and max HP crept up for the whole session.
    Cause
    A technical bug, not a design choice: starting a new run didn't reset health or the max-HP upgrades. It only hit people who played well, so it read as “I'm stronger”, not “it's broken”.
    Change
    Health restored to the authored maximum at the start of every run.
    Evidence
    Fixed in Update 2; in production from launch.
  7. How many hits does a brick need?

    Tester · rounds 1–2Open on purposeColour per health was too costly here. Next: damage numbers or light impact effects.
    Observed
    A tester couldn't read how close a brick was to breaking, and suggested a colour for each health step.
    Cause
    The friction was real; the suggested fix less so. Colour per health would need a separate mesh for every stage (materials can't change at runtime); a sound or flash on every hit, with up to sixteen balls in flight, would be noise.
    Change
    Left open on purpose. Next: damage numbers or very light impact VFX.
    Evidence
    Not changed.

05Launch & data

Shipped, then measured

Published on Fortnite during Epic Games' UEFN Student Bootcamp 2026 and submitted for judging. A bootcamp island with no paid promotion: its reach came from Discover, which showed it for four days. The page describes v3, the last update (19 Aug 2026); the data runs to 13 Oct and uses the Creator Portal's own names.

Four days on Discoverchart: the first three weeks

Impressions
70,064
14 Aug – 13 Oct; 95% in Discover's window
Clicks
494
CTR 0.71%
Plays
70
sessions started, not unique players
Impressions and plays per day, 14 Aug – 3 Sep 2026
DayImpressionsPlaysRelease
14 Aug62,11943Launch
15 Aug2,2805
16 Aug8504
17 Aug1,1682Update 1 · the boss
18 Aug2702
19 Aug670Update 2 · the class
20 Aug310
21 Aug602
22 Aug1000
23 Aug1620
24 Aug1574
25 Aug1201
26 Aug730
27 Aug280
28 Aug320
29 Aug620
30 Aug630
31 Aug470
1 Sep540
2 Sep311
3 Sep170
Daily impressions on a log scale, plays below. Discover showed the island for four days, 14–17 Aug: 95% of all its impressions. The boss arrived on the last of those days; the second class, the first thing to spend studs on, two days after. From 18 Aug to 13 Oct: 16 plays. 494 clicks opened the island's page, but only 70 plays started: most players who looked never began a run, and with a queue of 1 to 5 seconds, the wait wasn't the reason.

Launch day, 14 Aug43 sessions

Past 2 min
68%
2 in 3 sessions; 70% ended within five
Average session
4.3 min
about one run
Day 1 retention
4.65%
two came back; Day 7: none
Bounce and retention as the Creator Portal defines them. Epic reads a high bounce at five minutes as a first experience that doesn't hold.
Show the known issues at v3
  • The player sometimes snaps from one spot to another.
  • Standing at the edge and aiming outward can fire balls outside the arena.
  • Rarely, enemies spawn misaligned or get stuck.

All three are rare and logged; none is fixed in the live version.

06Postmortem

Postmortem: against the brief

Measured against the three things the bootcamp's LEGO® island brief judged:

  • partly

    The brand in the play

    Building flipped into breaking; the pieces flying off on every hit were cut for time.

  • held

    The first minutes

    2 in 3 launch-day sessions went past two minutes; the first kill comes at 12 seconds.

  • missed

    A reason to replay

    About one run per session: 70% ended within five minutes. My reading: nothing outside the run asked for another; at launch there was no boss and nothing to buy.

Keep

  • One simulation for the aim line and the ball.
  • Enemies made of rules, not stats: a shield and a fireball made three pressures. More can come, as long as each one plays off what is already there.
  • A core loop that works, for three weeks: it held the first minutes; what it needs is content around it, not a new loop.

Change

  • A ball build, not stat ranges: damage won almost every pick.
  • A fairer heal: the shipped 25–50 heal rolls flat, so luck can swing a run; a bell-shaped roll keeps the variety and cuts the extremes.

Next

  • The ball build, before new content.
  • Goals beyond the run: zones, bosses, classes.
  • A break-apart on hits and deaths.
  • Readable hits: damage numbers.
  • Co-op, if the angles survive four players.
Show what I cut, and why (7 cuts)

Two weeks of build: the goal was a working loop as fast as possible, so I cut for risk.

  • Tycoon mode (build with the bricks you collect): a second game with its own economy, built on the LEGO® assembly device, a different asset pipeline from the arcade's static meshes.
  • Co-op: aiming was global, not per player, and the popup and statue were shared. Everything else was per player from day one, so it stays possible.
  • Classes that level up with studs: the save already has room for class levels; what was missing was a long-term economy to price them.
  • Ball fusions and evolutions: a ball's mesh can't be swapped at runtime, so every new look is another pool of entities; in-run or permanent was still open.
  • Zones of different width: the helper modules read the arena bounds once at start; a changing arena needs them to re-read safely.
  • More bosses: each boss is its own attacks, telegraphs and shape. One finished boss over two rough ones.
  • Bricks losing pieces when hit: a fake break-apart, a few animated chunks per enemy within a per-frame budget; with sixteen balls in flight, the riskiest polish item.