BINX FORGEALL YOU NEED IS AN IDEA.Support BINX ↗
GAME RECIPES · ORIGINAL SOURCE INCLUDED

Make a Top-Down Shooter With Safe Projectile Hits

Build Signal Sweep: normalised movement, rate-limited shots, enemy collisions and a finite wave.

Actual Signal Sweep gameplay: a playable BINX reference
Signal Sweep · Actual gameplay

Thumbnail: an actual matching workshop game. It is a gameplay reference, not evidence that a save, inventory, network or native reverse-engineering integration has been demonstrated.

Difficulty: beginner to intermediate. Prerequisites: basic variables, functions and a test copy of your project. Reference: Forge workshop 1.0, browser ES modules and Node 24 checks. Engine-specific translation is a separate integration.

What you will build

Survive one twelve-enemy wave with three health and rate-limited fire.

Play Signal Sweep →Download complete MIT workshop
  1. Extract into a new folder and run node check.mjs from that folder.
  2. For the browser games, run python3 -m http.server 8080 with Python 3 and open http://localhost:8080/index.html. Do not open modules with file://.
  3. Read the full setup instructions and the original code licence. Keep your existing game on a separate test branch.

The JavaScript behaviour checks and native C comparison can run independently of the browser. Ghidra UI, physical-phone and your engine integration are separate checks. This is a small reference, not a certification of your project.

Explore the related game idea · Start with Build a Game · Improve your existing game

Five practical steps

Make a Top-Down Shooter With Safe Projectile Hits: Prove movement before shooting → Give shots a cooldown → Consume hits exactly once
Original implementation diagram · not gameplay or a tool screenshot
  1. Prove movement before shooting

    Choose Top-down shooter and Start. Use arrows/WASD or direction buttons. Divide the input vector by its length so diagonal movement matches horizontal speed. Clamp the player to the arena. The artwork is intentionally geometric while logic is tested.

    Expected result: Movement is equally fast in straight and diagonal directions.

    Check it: Compare one second right with one second diagonal; total distance should be approximately equal.

    stepObserve the inputs → check the state → compare the result
  2. Give shots a cooldown

    Hold Shoot or Space to fire. The simulation owns the 0.22-second cooldown and each projectile position. Movement and firing use elapsed simulation time; a 120Hz display must not double the fire rate. Avoid one independent interval per projectile.

    Expected result: A bounded bullet stream moving upward.

    Check it: Hold fire for a fixed interval at two update schedules and compare the shot count.

  3. Consume hits exactly once

    Mark a bullet and enemy dead when they collide. The next collision checks ignore dead objects; clean arrays after resolution. Removing array entries while iterating can skip neighbours, and a still-live bullet can wrongly kill several enemies in one frame.

    Expected result: One projectile causes one accepted hit.

    Check it: Put two enemies at the same bullet location; only one is defeated by that bullet.

  4. Bound damage and the wave

    Contact starts one second of invulnerability; an escaped enemy also costs health. Twelve finite spawns lead to a win when the wave clears or a loss at zero health. The example intentionally keeps escapes separate from contact invulnerability.

    Expected result: A finite game with readable health and outcome.

    Check it: Test overlapping enemies, an escape during invulnerability, zero health and no enemies between spawn intervals.

  5. Upgrade one verified system

    Add a second firing direction, one pickup or clearer hit feedback. Keep simulation decisions independent from particles. Faster projectiles can tunnel through targets; switch to swept tests or your engine physics before raising speed beyond what this fixed-step radius test can handle.

    Expected result: A playable original wave shooter and one controlled extension.

    Check it: Retest diagonal speed, pause, repeated restart, hidden-tab resume and keyboard/touch after the upgrade.

Read and reuse the actual code

shooter.mjs: complete source · Standalone behavioural checks · Shared browser runner and input. Original BINX Forge code, MIT; the package includes every required file and its notice.

Inspect complete shooter.mjs
export function create(){return {x:320,y:280,bullets:[],enemies:[],spawn:0,cool:0,remaining:12,kills:0,hp:3,invulnerable:0,ended:false,won:false};}
export function step(s,i,dt){
 if(s.ended)return;
 let dx=Number(!!i.right)-Number(!!i.left),dy=Number(!!i.down)-Number(!!i.up),len=Math.hypot(dx,dy)||1;
 s.x=Math.max(12,Math.min(628,s.x+dx/len*190*dt));s.y=Math.max(12,Math.min(348,s.y+dy/len*190*dt));s.cool-=dt;s.spawn-=dt;s.invulnerable=Math.max(0,s.invulnerable-dt);
 if(i.fire&&s.cool<=0){s.bullets.push({x:s.x,y:s.y,dead:false});s.cool=.22;}
 if(s.remaining>0&&s.spawn<=0){s.enemies.push({x:80+(12-s.remaining)%5*110,y:-15,dead:false});s.remaining--;s.spawn=.8;}
 for(const b of s.bullets)b.y-=360*dt;
 for(const e of s.enemies){e.y+=75*dt;for(const b of s.bullets)if(!b.dead&&!e.dead&&Math.hypot(e.x-b.x,e.y-b.y)<16){b.dead=true;e.dead=true;s.kills++;}if(!e.dead&&Math.hypot(e.x-s.x,e.y-s.y)<22){e.dead=true;if(s.invulnerable<=0){s.hp--;s.invulnerable=1;}}else if(!e.dead&&e.y>380){e.dead=true;s.hp--;}}
 s.bullets=s.bullets.filter(b=>!b.dead&&b.y>-20);s.enemies=s.enemies.filter(e=>!e.dead);
 if(s.hp<=0||(!s.remaining&&!s.enemies.length)){s.ended=true;s.won=s.hp>0;}
}

Code rights: the included MIT notice permits use, modification and distribution, including commercial games and source products, with the copyright and licence notice. Added third-party files have their own terms. Read the official licence & usage terms.

Common failures and fixes

One bullet kills a whole group

Consume the bullet on the first accepted hit and skip dead bullets thereafter.

Bullets pass through enemies

The radius test is discrete; bound speed or use swept collision when travel per step grows.

Diagonal movement is faster

Normalise the direction vector before multiplying by speed.

Make Your Game Better

Change one system after the baseline works. Keep the free reference and compare the same inputs before and after.

Optional building blocks from original creators

Inspect exact formats and editions on each resource page. Pay for a resource only when it fills an identified gap; the free code exercise needs no paid engine or pack.

Licensing summary, not legal advice. Before publishing or selling, check exact terms for finished-game use, reselling files and including files in a source/template product separately.

Learn at the original sources

Sources checked 11 October 2026. The numbered plan is original Forge instruction; linked documentation does not imply every engine or device has been tested.

Take this guide to your AI

Review and copy into your assistant. Nothing is sent automatically. These prompts include the complete focus source, full-package links, checks and compatibility limits.

Review a prompt or select its text manually.

Review build prompt
Review debug prompt
Review upgrade prompt

Read the complete guide and prompts as Markdown →

Keep learning

Browse every guide and recipe →