Guide 14 — Zap Attack!!
Tony Williams
What you're building
Blobby the Electro Slime escapes Avalon's lab and joins the resistance against the corporation hoarding Kalon City's electricity. Fast, trial-and-error precision platforming: unlimited lives, dash through enemies, zip along power lines, homing attack, slamming. Four sectors of ten levels each with hub towns, bosses, locked levels behind a power generator, and online time attack.
Let's be straight about scope. Forty levels, four hubs, a level-select system, unlockable abilities and a leaderboard is more than a semester — probably more than a year. Your design is genuinely good; there's just a lot of it.
This guide builds your systems and then tells you how to cut. The systems are the hard part and they're mostly done in three hours. Everything after is levels, and levels are where you decide how big your game is.
Read section 3 before anything else.
1. Before you start
- Finish Guide 0.
- Read Guide B §B1 (player), §B2, §B4 (enemies).
- One new input action:
Dash.
2. Scripts you'll use
Core — Guide B
PlayerController2D · PlayerAnimatorBridge · Health · DamageOnContact · Checkpoint · RespawnManager · CameraTargetAssigner · SceneLoader · GameManager · AudioManager · HUDController · MovingPlatform · ParallaxBackground
Combat (Tier 2)
Team · Hurtbox · Hitbox · Knockback · EnemyPatrol · BossController · BossArenaTrigger
Movement (Tier 3)
Dash · WallSlideJump · RailRide + Rail
Hazards & progression (Tier 4)
SpinningSaw · SpikeTrap · ElectricZone · KillZone · Door · LevelData · LevelSet · LevelProgress · LevelTimer · LevelSelectButton · LevelSelectMenu · ChoiceFlagManager · Collectible · ItemType · CollectionTracker
Saving (Tier 7)
SaveData · SaveSystem
3. Cut the scope before you build
Here's what I'd actually make, in order. Stop wherever the semester ends.
| Tier | What | Why |
|---|---|---|
| Must have | 1 sector, 8 levels, 1 boss, level select, timer | A complete, finished game |
| Should have | The generator door gating level 5 | Your best mechanic — see section 8 |
| Nice to have | A hub town, a second sector | |
| Cut for now | Sectors 3 and 4, the secret sector, the two extra assassins | |
| Cut entirely | Online time attack | See below |
On online leaderboards
Online play needs a server, accounts, and anti-cheat. That's a semester on its own and none of it is game design. LevelTimer already saves your best time locally and shows it on the level select. That gives you the whole feel of time attack — beat your own record — with none of the infrastructure. Ship that.
Why eight levels, not ten
Ten is arbitrary; eight is one fewer week of level building. If you finish eight and have time, add two. Nobody has ever looked at a game and thought "this needed two more levels."
Every system below works identically whether you make eight levels or forty. The cut costs you nothing structurally.
4. Build Blobby
Guide B §B1 with your Blobby sprite:
| Component | Setting | Value |
|---|---|---|
Health | Max Health | 1 |
| Invulnerability Time | 0 | |
PlayerController2D | Move Speed | 10 |
| Acceleration | 80 | |
| Deceleration | 100 | |
| Jump Force | 15 | |
| Coyote Time | 0.12 | |
| Jump Buffer Time | 0.15 |
Max Health 1 with unlimited lives
Your pitch says "unlimited lives and you will die many times until you learn the pattern." That's Super Meat Boy, and one-hit death with instant respawn is exactly how it works. Generous coyote time and jump buffering matter more here than in any other game in the class — the deaths must feel like your fault, not the controller's.
On RespawnManager: Use Lives ✗, Respawn Delay 0.4. Short delay, straight back in.
Add Knockback (Stun 0, Resistance 1 — no stagger in a precision platformer).
Children
Hurtbox— trigger collider, Hurtbox (Team Player), layerHurtboxWallCheck— empty at chest height, right sideGroundCheck— at the feetDashHitbox— trigger collider around the body, Hitbox (Target Enemy, Damage 1, Knockback 10), layerHitbox, GameObject unticked
The abilities
| Component | Settings |
|---|---|
| Dash | Speed 24 · Duration 0.14 · Cooldown 0.35 · Direction Facing · Air Dashes 1 · Invulnerable ✓ |
| WallSlideJump | Wall Check → the child · Wall Layer Ground · Slide Speed 2 · Wall Jump Force (11, 15) · Lock Time 0.15 |
| RailRide | Rail Layer Rail · Ride Speed 12 · Attach On Touch ✓ · Ride Height Offset 0.5 · Jump Off Force 15 · Momentum Carry 1 |
Dash-through-enemies
Blobby dashes through enemies rather than attacking them. Wire it:
Dash.OnDashStarted→DashHitbox→GameObject.SetActive✓Dash.OnDashEnded→DashHitbox→GameObject.SetActive✗
Two wirings and your signature move works. The dash is already invulnerable, so you pass through unharmed.
5. Build power lines
Your zip-along-power-lines mechanic.
- Empty GameObject
PowerLine. - Add an Edge Collider 2D. Click Edit Collider and drag its points to draw the wire — it can have as many bends as you like.
- Tick Is Trigger, set Edge Radius to 0.3 (makes it much easier to land on).
- Layer →
Rail. - Add the
Railcomponent (no settings — it just marks the collider). - Add a Line Renderer following roughly the same path, or a stretched sprite, so the player can see it.
Blobby attaches automatically when he touches one in mid-air, rides to the end, and can jump off at any point carrying his speed.
Design tip: a power line that drops the player onto a hazard at the far end is a trap they'll only fall for once. A power line that launches them across a gap they couldn't otherwise cross is a reward. Build the second kind.
6. Hazards and enemies
Electric arcs — your theme. Empty GameObject + trigger collider + DamageOnContact (Instant Kill ✓) + ElectricZone:
| Field | Value |
|---|---|
| Always On | ✗ (timed) or ✓ (constant) |
| On Time / Off Time | 0.8 / 1.2 |
| Warning Time | 0.3 |
| Stun Duration | 0.5 |
| Flicker ✓ · Flicker Rate | 20 |
Saw blades — Guide 1 §6b.
Spikes — trigger + DamageOnContact (Instant Kill ✓).
Kill zone — under everything.
Enemies — Guide B §B4 with Health 1, Hurtbox (Team Enemy), BodyHitbox (Instant Kill on the player, since Blobby has 1 HP). Keep them simple; your game is about movement, not combat.
Blobby is made of electricity. If you want electric hazards to be harmless to him thematically, set that hazard's
DamageOnContactTarget Tag toEnemyinstead ofPlayer. Cheap, and it's a nice bit of world-building — Avalon's defences don't work on their own escaped experiment.
7. The green electricity collectible
- Right-click Project → Create → GAME1303 → Item Type, name it
GreenElectricity. Score Value 0. - Prefab: sprite + trigger Circle Collider 2D + Collectible (Item Type →
GreenElectricity, Bob ✓). - Add a
CollectionTrackerto the scene with Persist Across Scenes ✓ — you carry it between levels.
8. The generator door — build this one properly
Your pitch: "5th and final levels will be locked behind the power generator, for that the player must collect required amount of green electricity." This is your best structural idea and it works at two scales.
In-level: a door in front of the exit
- Empty GameObject
GeneratorDoor+ sprite + solid Box Collider 2D. - Door component:
| Field | Value |
|---|---|
| Requirement | Collect |
| Required Item | GreenElectricity |
| Required Count | 5 |
| Consume On Open | ✗ (it's a quota, not a key) |
| Open Mode | Slide |
| Open Offset | (0, 4) |
- Add a trigger child, drag it into Proximity Zone.
- Wire
Door.OnProgressto a text showing3 / 5— do this, or a short player has no idea why the door won't move. - Wire
Door.OnOpenFailedto a buzz sound.
At level-select: a locked level
LevelData also has an unlock cost, but it spends through CollectionTracker the same way. Set unlockCost 5 and unlockCurrency to your GreenElectricity asset on the level-5 LevelData.
Pick one. Doing both means paying twice. I'd use the in-level door — it's more visible, it's in front of the player rather than in a menu, and it makes the collectibles feel like they're powering something.
9. The timer
- Empty GameObject
LevelTimer+ the component:
| Field | Value |
|---|---|
| Mode | CountUp |
| Level Id | must match this level's LevelData id, e.g. sector1_level1 |
| Auto Start | ✓ |
| Timer Text | a TMP text, top-right |
| Best Time Text | another TMP text below it |
| Best Time Prefix | Best: |
- Wire
LevelExit.OnCompleted → LevelTimer.StopAndRecord. Without this, no time is ever saved. - Wire
LevelTimer.OnNewRecordto a sound and a "NEW RECORD" text.
⚠️
Level Idis the save key. Renaming one after playtesting silently wipes that level's best time and cleared status. Decide your naming scheme now —sector1_level1throughsector1_level8— and don't change it.
10. Level select
Once one level works, this is asset creation.
The assets
- Per level: Create → GAME1303 → Level
- Level Id
sector1_level1…sector1_level8 - Display Name
1-1etc. - Scene Name — the actual scene name, and add it to Build Settings
- Unlocked From Start ✓ on level 1 only
- Leave Requires Cleared empty — the default is "the previous level in the set"
- Unlock Cost 0 (you're using the in-level door)
- Level Id
- Create → GAME1303 → Level Set, name it
Sector1. Drag all eight LevelData in, in order.
The scene
- New scene
LevelSelect. Canvas → Panel with a Grid Layout Group (Cell Size ~160×120, Spacing 12). - Build a
LevelSelectButtonprefab: a UI Button containing a thumbnail Image, a TMP name, a TMP best-time, a padlock Image, a checkmark Image. Add the LevelSelectButton component and drag each part into its slot. - On the Panel: LevelSelectMenu — drag your
Sector1LevelSet into Sets, the button prefab into Button Prefab, the Panel's own transform into Container. - Add a
SceneLoaderto this scene. - Add TMP texts for the sector title and
{0} / {1} clearedprogress.
The menu rebuilds every time it's enabled, so returning from a level updates the locks immediately.
A clear-save button
Add a Button wired to LevelSelectMenu.ResetAllProgress. You will want this constantly while testing — progress lives in PlayerPrefs and survives rebuilds, which is the usual answer to "why is level 3 still unlocked?"
11. Wire it up
| On this object | Event | Drag in | Choose |
|---|---|---|---|
Player → Health | On Died | RespawnManager | RespawnManager.OnPlayerDied |
Player → Dash | On Dash Started | DashHitbox | GameObject.SetActive ✓ |
Player → Dash | On Dash Ended | DashHitbox | GameObject.SetActive ✗ |
LevelExit | On Completed | LevelTimer | LevelTimer.StopAndRecord |
LevelTimer | On New Record | AudioManager | PlaySFX (string) → record |
Door | On Open Failed | AudioManager | PlaySFX (string) → door_locked |
CollectionTracker | On Count Changed | HUD | HUDController.UpdateItemCount (Dynamic) |
Player → RailRide | On Attached | AudioManager | PlaySFX (string) → rail_on |
Boss → BossController | On Boss Defeated | GameManager | GameManager.LevelComplete |
12. First playtest
Build one short level with a wall, a power line, a saw, an electric arc, three green electricity pickups, a generator door and an exit.
- Blobby runs and jumps. Fast — Move Speed 10 should feel quick.
- One touch of anything kills, and you're back in under half a second.
- Dash works and passes through enemies without harming you.
- Wall slide and wall jump.
- Landing on a power line attaches you and you ride to the end.
- Jumping off a rail carries your speed.
- Green electricity counts up.
- The generator door shows progress and opens at 5.
- The timer runs and stops at the exit.
- The best time is saved — replay and see it displayed.
- Level select shows level 1 unlocked and 2 locked, and clearing 1 unlocks 2.
Steps 9–11 are the progression spine. Test them once and they work for all eight levels.
13. Then add
- Levels. Eight of them. This is the whole rest of your project.
- A boss at level 8 — Guide 7 §9 recipe.
- Animation — Guide B §B6 plus
Dash,IsWallSliding,IsRiding. ParallaxBackground— Kalon City in layers. Upper level bright, lower level grim.- A hub town — a small level with
InteractableNPCs and aLevelExitper destination. Guide 10 §5 if you want them to talk. - Sector 2 — a second
LevelSet, added toLevelSelectMenu's Sets list.NextSet/PreviousSeton arrow buttons. - Only then, if there's time, sectors 3 and 4.
14. Design notes for your game specifically
Your restraint budget is the most important thing in this guide. Everything in your pitch is a good idea. The failure mode isn't a bad design, it's an unfinished one. Set a date — say four weeks out — where you stop adding systems and only make levels. Then hold it.
One-hit death demands generous controls. In a game where you die constantly, every death must read as the player's mistake. Coyote time 0.12 and jump buffer 0.15 are more generous than the kit's defaults, deliberately. If playtesters say a death felt cheap, raise them further before you change the level.
Respawn Delay 0.4 is doing heavy lifting. Super Meat Boy's genius was that death cost almost nothing. Long enough to register, short enough that you're back before frustration lands. Don't raise it.
Build the level, then the decoration. Grey boxes, get the run feeling right, then art. A precision platformer's layout is measured in exact jump distances, and it's far easier to move a rectangle.
Power lines should reward speed, not just transport. A rail that carries momentum into a gap you couldn't otherwise clear teaches the player that going fast is the point. Place them at the end of a run-up, not from a standing start.
Your locked-level-behind-a-generator idea is genuinely good. It makes collectibles matter without making them mandatory everywhere — you can collect casually through levels 1 to 4 and then find you're two short at the gate, and go back. That's a real decision. Show the progress readout, or it's just a wall.
Local best times are enough. Beating your own record is most of what leaderboards deliver emotionally, and it costs you one component. If online genuinely matters to you, do it after the game is finished, as a separate project.
15. Common problems
| What you see | What's wrong |
|---|---|
| Dash doesn't hurt enemies | OnDashStarted → SetActive(true) not wired, or the hitbox is on the wrong layer |
| Dash hitbox stays on | The OnDashEnded → SetActive(false) wiring is missing |
| Can't attach to a power line | Layer isn't Rail, or no Rail component, or the collider isn't a trigger, or you're grounded |
| Falls straight through the rail | Edge Radius too small — set it to 0.3 |
| Rail ride ends immediately | Edge Collider has fewer than two points |
| Best time never saves | LevelExit.OnCompleted → StopAndRecord not wired |
| Best time resets | Level Id was renamed |
| Level select is empty | LevelSet has no levels, or Button Prefab unassigned |
| Every level is unlocked | Unlocked From Start ticked on all of them, or old PlayerPrefs — use the clear-save button |
| Levels stay locked after clearing | Level Id in LevelData doesn't match the LevelTimer's Level Id in that scene |
| Generator door won't open | Required Count higher than what you placed, or CollectionTracker isn't persisting between levels |
| Green electricity resets each level | CollectionTracker Persist Across Scenes unticked |