BINX FORGEALL YOU NEED IS AN IDEA.Support BINX ↗
REVERSE ENGINEERING · ORIGINAL SOURCE INCLUDED

Inspect Your Game’s Network Messages Without Trusting the Client

Study a small owned input protocol, sequence numbers and server-owned movement.

Actual Circuit Spark gameplay: a playable BINX reference
Circuit Spark · Actual gameplay · Related playable reference

Thumbnail: an actual related playable BINX demo. 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 learn

Study a small owned input protocol, sequence numbers and server-owned movement.

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

Inspect Your Game’s Network Messages Without Trusting the Client: Choose a permitted local session → Find the action boundary → Test ordering and duplicates
Original implementation diagram · not gameplay or a tool screenshot
  1. Choose a permitted local session

    Open your own browser game and Chrome DevTools Network. Filter Fetch/XHR or WS, then inspect messages generated by one controlled action. The included applyInput is a pure server-rule exercise; the workshop does not contact a multiplayer service.

    Expected result: A scoped observation plan with no unknown accounts or endpoints.

    Check it: Record only your test session and redact cookies, bearer tokens and other players’ identifiers.

    applyInputObserve the inputs → check the state → compare the result
  2. Find the action boundary

    The toy packet is {seq:1,dx:1}. It expresses one bounded movement request, not a claimed position or score. Compare idle, left and right messages in a real owned implementation; payload names alone are not proof of server authority.

    Expected result: A proposed input schema backed by controlled actions.

    Check it: Run applyInput on {x:10,seq:0}; accepted right input gives x=12 and seq=1.

  3. Test ordering and duplicates

    The reference accepts only an integer sequence newer than the last accepted packet and direction -1, 0 or 1. Repeat a packet and try an older sequence. In a deployed protocol, add bounded jumps, rate limits and reconnect/session rules as separate checks.

    Expected result: Replayed or stale packets cannot move this reference player twice.

    Check it: Apply seq 1 twice, then seq 0; only the first changes position.

  4. Keep the server authoritative

    Ignore client claims about score, health and final position. The server applies validated input and clamps its own state to bounds. This helper does not implement authentication, network transport, tick-rate limits, rollback or anti-cheat; those must not be inferred from one accepted packet.

    Expected result: A specific authority rule and explicit missing deployment systems.

    Check it: Send dx 999 or a string sequence; both reject without changing x or seq.

  5. Write an evidence-based protocol note

    Document message direction, fields, types, sequence behaviour and observed acknowledgements. Include a local replay fixture so colleagues can repeat the result. Do not probe third-party services or bypass access controls to fill gaps in an observation.

    Expected result: A narrow protocol description with tested and untested sections.

    Check it: Before inviting strangers, test disconnect, reconnect, flood limits, ownership and simultaneous actions in your own server.

Read and reuse the actual code

systems.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 systems.mjs
// Original BINX Forge practice code. MIT; see LICENSE.txt.
export function readSave(raw) {
  const s = JSON.parse(raw);
  if (!s || s.version !== 1 || !Number.isInteger(s.coins) || s.coins < 0 || s.coins > 9999 || !['room-a','room-b'].includes(s.room)) throw Error('Invalid save');
  return {version:1, coins:s.coins, room:s.room};
}
export function transfer(from, to, id, count, capacity=10) {
  if (!Number.isInteger(count) || count < 1 || !Number.isInteger(from[id]) || from[id] < count || Object.values(to).reduce((a,b)=>a+b,0)+count > capacity) return false;
  from[id]-=count; to[id]=(to[id]||0)+count; return true;
}
export function pointerInput() {
  const owners=new Map();
  return {press:(id,action)=>owners.set(id,action),release:id=>owners.delete(id),clear:()=>owners.clear(),held:action=>[...owners.values()].includes(action)};
}
export function enemyMode(distance, hp, cooldown) {
  if (hp<=0) return 'dead';
  if (cooldown>0) return 'recover';
  if (distance<24) return 'attack';
  return distance<180?'chase':'idle';
}
export function frameSummary(samples) {
  const s=samples.filter(Number.isFinite).filter(x=>x>=0).sort((a,b)=>a-b);
  if (!s.length) throw Error('No samples');
  return {median:s[Math.floor((s.length-1)*.5)],p95:s[Math.ceil(s.length*.95)-1],count:s.length};
}
export function fixedStep(clock, elapsed, update) {
  clock.carry+=Math.max(0,Math.min(.1,elapsed));
  while(clock.carry>=1/60){update(1/60);clock.carry-=1/60;}
}
// Owned protocol specimen: version:u8, coins:u16 little-endian, room:u8.
export function decodeRecord(bytes) {
  if(bytes.length!==4)throw Error('Expected four bytes');
  const v=new DataView(bytes.buffer,bytes.byteOffset,bytes.byteLength);
  if(v.getUint8(0)!==1||v.getUint8(3)>1)throw Error('Unknown record');
  return {version:1,coins:v.getUint16(1,true),room:v.getUint8(3)};
}
export function applyInput(player, packet) {
  if(!packet||!Number.isInteger(packet.seq)||packet.seq<=player.seq||![-1,0,1].includes(packet.dx))return false;
  player.seq=packet.seq;player.x=Math.max(0,Math.min(100,player.x+packet.dx*2));return true;
}
export function jumpTrace(speed=300,gravity=900,dt=1/120) {
  let y=0,vy=-speed,t=0,peak=0;
  const rows=[{t,y,vy}];
  while(t<3){vy+=gravity*dt;y+=vy*dt;t+=dt;peak=Math.min(peak,y);rows.push({t,y,vy});if(y>=0)break;}
  return {rows,height:-peak,airtime:t};
}

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

The client displays success but nothing persists

Inspect server acknowledgements and authoritative state; UI feedback is not proof of acceptance.

Duplicate inputs move twice

Track a sequence within the correct authenticated session and reject stale requests.

A reconnect rejects every packet

Define session reset/resume rules; an old sequence belongs to an explicit session.

Make Your Game Better

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

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

Original reverse-engineering practice lab · Sonic Unleashed creator-project study · SpaghettiKart creator-project study

Browse every guide and recipe →