/pong — synthesized game logic

No human wrote this game.

0:0
pong — 22 verified rules, zero human logicpress ↑ / ↓ to take over the right paddle
rules firing livenext_poswall_bouncepaddle_hitspeed_upscoreserve

Every rule in play — ball motion, wall bounce, paddle collision, scoring, the tracking AI, the speed-up on each rally — is built from programs the nsynth synthesizer discovered from input/output examples, verified against held-out cases, then transpiled Mog → TypeScript. The function bodies running this page are the literal transpiler output. The only human-written code is the canvas renderer, the animation loop, keyboard reading, and argument-routing glue.

provenance

The 22 synthesized rules — examples in, Mog program out, TypeScript verbatimopen ▾

For each rule: the I/O examples it was synthesized from, the Mog program nsynth discovered, and the TypeScript this page actually runs. Where a first synthesis fit the examples but not the game's full input domain, the verifier's counterexamples were fed back as new examples until the program survived an exhaustive sweep (counterexample-guided synthesis).

next_possearch_scalar_expr · 8 examples · 11,781 domain cases verified

examples — what the synthesizer saw

next_pos(10, 2) = 12
next_pos(5, -3) = 2
next_pos(0, 4) = 4
next_pos(100, -7) = 93
next_pos(42, 0) = 42
next_pos(799, 11) = 810
next_pos(-5, -11) = -16
next_pos(600, 1) = 601

discovered Mog program

fn next_pos(a: i64, b: i64) -> i64 {
    return (b + a);
}

transpiled TypeScript — runs on this page

function next_pos(a: number, b: number): number {
    return (b + a);
}
hit_topsynth_gradient · 8 examples · 1,521 domain cases verified

examples — what the synthesizer saw

hit_top(0) = 1
hit_top(-1) = 1
hit_top(-5) = 1
hit_top(1) = 0
hit_top(3) = 0
hit_top(100) = 0
hit_top(600) = 0
hit_top(-20) = 1

discovered Mog program

fn hit_top(a: i64) -> i64 {
    x: i64 = a;
    acc: i64 = 1;
    if x == 0 {
        return 1;
    }
    while x > 0 {
        d: i64 = x % 11;
        x = x / 11;
        if acc != 11 {
            acc = acc / 2;
        }
    }
    return acc;
}

transpiled TypeScript — runs on this page

function hit_top(a: number): number {
    let x: number = a;
    let acc: number = 1;
    if (x == 0) {
        return 1;
    }
    while (x > 0) {
        let d: number = x % 11;
        x = Math.trunc(x / 11);
        if (acc != 11) {
            acc = Math.trunc(acc / 2);
        }
    }
    return acc;
}

hit_bottomsearch_single_branch · 9 examples · 361 domain cases verified

examples — what the synthesizer saw

hit_bottom(600, 600) = 1
hit_bottom(599, 600) = 0
hit_bottom(601, 600) = 1
hit_bottom(610, 600) = 1
hit_bottom(0, 600) = 0
hit_bottom(300, 600) = 0
hit_bottom(400, 400) = 1
hit_bottom(399, 400) = 0
hit_bottom(405, 400) = 1

discovered Mog program

fn hit_bottom(a: i64, b: i64) -> i64 {
    if (a % 10) != 0 {
        return (a / b);
    }
    return (a / b);
}

transpiled TypeScript — runs on this page

function hit_bottom(a: number, b: number): number {
    if ((a % 10) != 0) {
        return (Math.trunc(a / b));
    }
    return (Math.trunc(a / b));
}
moving_upsynth_gradient · 10 examples · 51 domain cases verified

examples — what the synthesizer saw

moving_up(-1) = 1
moving_up(0) = 0
moving_up(1) = 0
moving_up(-5) = 1
moving_up(7) = 0
moving_up(-11) = 1
moving_up(11) = 0
moving_up(3) = 0
moving_up(-12) = 1
moving_up(12) = 0

discovered Mog program

fn moving_up(a: i64) -> i64 {
    acc: i64 = 1;
    i: i64 = 0;
    while i <= a {
        acc = acc / 3;
        i = i + 1;
    }
    return acc;
}

transpiled TypeScript — runs on this page

function moving_up(a: number): number {
    let acc: number = 1;
    let i: number = 0;
    while (i <= a) {
        acc = Math.trunc(acc / 3);
        i = i + 1;
    }
    return acc;
}
moving_downsynth_gradient · 10 examples · 51 domain cases verified

examples — what the synthesizer saw

moving_down(-1) = 0
moving_down(0) = 0
moving_down(1) = 1
moving_down(-5) = 0
moving_down(7) = 1
moving_down(-11) = 0
moving_down(11) = 1
moving_down(3) = 1
moving_down(-12) = 0
moving_down(12) = 1

discovered Mog program

fn moving_down(a: i64) -> i64 {
    if a > 0 {
        return 1;
    }
    if a != a {
        return a;
    }
    if a != a {
        return a;
    }
    return 0;
}

transpiled TypeScript — runs on this page

function moving_down(a: number): number {
    if (a > 0) {
        return 1;
    }
    if (a != a) {
        return a;
    }
    if (a != a) {
        return a;
    }
    return 0;
}
gtecomposed: hit_top(sub2(b, a)) · 0 examples · 58,081 domain cases verified

examples — what the synthesizer saw

discovered Mog program

// No new program synthesized — pure reuse of verified skills:
//   gte = hit_top(sub2(b, a))
// Primitives used: hit_top, sub2 (each synthesized + swept independently).

transpiled TypeScript — runs on this page

function gte(a: number, b: number): number {
    return hit_top(sub2(b, a));
}
crossed_leftsearch_two_branch · 14 examples · 3,525 domain cases verified

examples — what the synthesizer saw

crossed_left(40, 30, 34) = 1
crossed_left(40, 34, 34) = 1
crossed_left(40, 35, 34) = 0
crossed_left(34, 30, 34) = 0
crossed_left(33, 28, 34) = 0
crossed_left(50, 45, 34) = 0
crossed_left(35, 20, 34) = 1
crossed_left(100, 90, 34) = 0
crossed_left(30, 36, 34) = 0
crossed_left(36, 36, 34) = 0
crossed_left(60, 50, 55) = 1
crossed_left(56, 55, 55) = 1
crossed_left(55, 50, 55) = 0
crossed_left(54, 60, 55) = 0

discovered Mog program

fn crossed_left(a: i64, b: i64, c: i64) -> i64 {
    if (2 + c) < a {
        return (c / b);
    }
    if a <= c {
        return 0;
    }
    return (c / b);
}

transpiled TypeScript — runs on this page

function crossed_left(a: number, b: number, c: number): number {
    if ((2 + c) < a) {
        return (Math.trunc(c / b));
    }
    if (a <= c) {
        return 0;
    }
    return (Math.trunc(c / b));
}
crossed_rightcomposed: flag_and(gte(plane, next_pos(prev, 1)), gte(next, plane)) · 0 examples · 3,025 domain cases verified

examples — what the synthesizer saw

discovered Mog program

// No new program synthesized — pure reuse of verified skills:
//   crossed_right = flag_and(gte(plane, next_pos(prev, 1)), gte(next, plane))
// Primitives used: flag_and, gte, next_pos (each synthesized + swept independently).

transpiled TypeScript — runs on this page

function crossed_right(prev: number, next: number, plane: number): number {
    return flag_and(gte(plane, next_pos(prev, 1)), gte(next, plane));
}
flag_andsearch_scalar_expr · 4 examples · 4 domain cases verified

examples — what the synthesizer saw

flag_and(0, 0) = 0
flag_and(0, 1) = 0
flag_and(1, 0) = 0
flag_and(1, 1) = 1

discovered Mog program

fn flag_and(a: i64, b: i64) -> i64 {
    return (a * b);
}

transpiled TypeScript — runs on this page

function flag_and(a: number, b: number): number {
    return (a * b);
}
flag_orsynth_gradient · 4 examples · 4 domain cases verified

examples — what the synthesizer saw

flag_or(0, 0) = 0
flag_or(0, 1) = 1
flag_or(1, 0) = 1
flag_or(1, 1) = 1

discovered Mog program

fn flag_or(a: i64, b: i64) -> i64 {
    if 0 != a {
        return 1;
    }
    if a != a {
        return a;
    }
    if a != a {
        return a;
    }
    return b / 1;
}

transpiled TypeScript — runs on this page

function flag_or(a: number, b: number): number {
    if (0 != a) {
        return 1;
    }
    if (a != a) {
        return a;
    }
    if (a != a) {
        return a;
    }
    return b / 1;
}
selectsynth_gradient · 10 examples · 8,978 domain cases verified

examples — what the synthesizer saw

select(1, 5, 9) = 5
select(0, 5, 9) = 9
select(1, -3, 7) = -3
select(0, -3, 7) = 7
select(2, 100, 200) = 100
select(0, 0, 1) = 1
select(1, 0, 1) = 0
select(0, -50, 50) = 50
select(1, 400, 300) = 400
select(0, 400, 300) = 300

discovered Mog program

fn select(a: i64, b: i64, c: i64) -> i64 {
    v0: i64 = c;
    if a != 0 {
        v0 = b;
    }
    result: i64 = v0;
    if v0 >= 2 {
        result = v0;
    }
    return result;
}

transpiled TypeScript — runs on this page

function select(a: number, b: number, c: number): number {
    let v0: number = c;
    if (a != 0) {
        v0 = b;
    }
    let result: number = v0;
    if (v0 >= 2) {
        result = v0;
    }
    return result;
}
score_if_out_rightcomposed: next_pos(score, exited_right(ball_x, w)) · 0 examples · 11,986 domain cases verified

examples — what the synthesizer saw

discovered Mog program

// No new program synthesized — pure reuse of verified skills:
//   score_if_out_right = next_pos(score, exited_right(ball_x, w))
// Primitives used: next_pos, exited_right (each synthesized + swept independently).

transpiled TypeScript — runs on this page

function score_if_out_right(score: number, ball_x: number, w: number): number {
    return next_pos(score, exited_right(ball_x, w));
}
score_if_out_leftcomposed: next_pos(score, exited_left(ball_x)) · 0 examples · 11,986 domain cases verified

examples — what the synthesizer saw

discovered Mog program

// No new program synthesized — pure reuse of verified skills:
//   score_if_out_left = next_pos(score, exited_left(ball_x))
// Primitives used: next_pos, exited_left (each synthesized + swept independently).

transpiled TypeScript — runs on this page

function score_if_out_left(score: number, ball_x: number): number {
    return next_pos(score, exited_left(ball_x));
}
exited_leftsynth_gradient · 8 examples · 461 domain cases verified

examples — what the synthesizer saw

exited_left(-1) = 1
exited_left(0) = 0
exited_left(1) = 0
exited_left(-10) = 1
exited_left(400) = 0
exited_left(800) = 0
exited_left(-3) = 1
exited_left(12) = 0

discovered Mog program

fn exited_left(a: i64) -> i64 {
    x: i64 = a;
    acc: i64 = 1;
    if x == 0 {
        return 0;
    }
    while x > 0 {
        d: i64 = x % 10;
        x = x / 10;
        if acc != 3 {
            acc = acc / 2;
        }
    }
    return acc;
}

transpiled TypeScript — runs on this page

function exited_left(a: number): number {
    let x: number = a;
    let acc: number = 1;
    if (x == 0) {
        return 0;
    }
    while (x > 0) {
        let d: number = x % 10;
        x = Math.trunc(x / 10);
        if (acc != 3) {
            acc = Math.trunc(acc / 2);
        }
    }
    return acc;
}
exited_rightsearch_single_branch · 9 examples · 461 domain cases verified

examples — what the synthesizer saw

exited_right(801, 800) = 1
exited_right(800, 800) = 0
exited_right(799, 800) = 0
exited_right(810, 800) = 1
exited_right(0, 800) = 0
exited_right(-5, 800) = 0
exited_right(401, 400) = 1
exited_right(400, 400) = 0
exited_right(200, 400) = 0

discovered Mog program

fn exited_right(a: i64, b: i64) -> i64 {
    if a != b {
        return (a / b);
    }
    return 0;
}

transpiled TypeScript — runs on this page

function exited_right(a: number, b: number): number {
    if (a != b) {
        return (Math.trunc(a / b));
    }
    return 0;
}
max2composed: neg(min2(neg(a), neg(b))) · 0 examples · 160,801 domain cases verified

examples — what the synthesizer saw

discovered Mog program

// No new program synthesized — pure reuse of verified skills:
//   max2 = neg(min2(neg(a), neg(b)))
// Primitives used: neg, min2 (each synthesized + swept independently).

transpiled TypeScript — runs on this page

function max2(a: number, b: number): number {
    return neg(min2(neg(a), neg(b)));
}
min2synth_gradient · 6 examples · 160,801 domain cases verified

examples — what the synthesizer saw

min2(3, 7) = 3
min2(9, 2) = 2
min2(4, 4) = 4
min2(-5, -2) = -5
min2(0, -9) = -9
min2(12, 15) = 12

discovered Mog program

fn min2(a: i64, b: i64) -> i64 {
    v0: i64 = b;
    if b >= a { v0 = a; }
    result: i64 = v0;
    if -2 >= a { result = v0; }
    return result;
}

transpiled TypeScript — runs on this page

function min2(a: number, b: number): number {
    let v0: number = b;
    if (b >= a) { v0 = a; }
    let result: number = v0;
    if (-2 >= a) { result = v0; }
    return result;
}

sub2synth_gradient (CEGIS iter 1) · 16 examples · 160,801 domain cases verified

examples — what the synthesizer saw

sub2(7, 3) = 4
sub2(2, 5) = -3
sub2(0, 0) = 0
sub2(10, -4) = 14
sub2(-3, -8) = 5
sub2(100, 1) = 99
sub2(-300, -300) = 0
sub2(-270, -300) = 30
sub2(-240, -300) = 60
sub2(-210, -300) = 90
sub2(-180, -300) = 120
sub2(-150, -300) = 150
sub2(-120, -300) = 180
sub2(-90, -300) = 210
… 2 more

discovered Mog program

fn sub2(a: i64, b: i64) -> i64 {
    return a - b;
}

transpiled TypeScript — runs on this page

function sub2(a: number, b: number): number {
    return a - b;
}

negsynth_gradient · 6 examples · 4,001 domain cases verified

examples — what the synthesizer saw

neg(3) = -3
neg(-2) = 2
neg(5) = -5
neg(0) = 0
neg(-11) = 11
neg(7) = -7

discovered Mog program

fn neg(a: i64) -> i64 {
    v0: i64 = a * a;
    return 0 - a;
}

transpiled TypeScript — runs on this page

function neg(a: number): number {
    let v0: number = a * a;
    return 0 - a;
}

abs2composed: neg(min2(neg(v), v)) · 0 examples · 4,001 domain cases verified

examples — what the synthesizer saw

discovered Mog program

// No new program synthesized — pure reuse of verified skills:
//   abs2 = neg(min2(neg(v), v))
// Primitives used: neg, min2 (each synthesized + swept independently).

transpiled TypeScript — runs on this page

function abs2(v: number): number {
    return neg(min2(neg(v), v));
}
growcomposed: select(gte(v, 1), next_pos(v, 1), next_pos(v, -1)) · 0 examples · 51 domain cases verified

examples — what the synthesizer saw

discovered Mog program

// No new program synthesized — pure reuse of verified skills:
//   grow = select(gte(v, 1), next_pos(v, 1), next_pos(v, -1))
// Primitives used: select, gte, next_pos (each synthesized + swept independently).

transpiled TypeScript — runs on this page

function grow(v: number): number {
    return select(gte(v, 1), next_pos(v, 1), next_pos(v, -1));
}
reflect_xcomposed: select(hit, neg(vx), vx) · 0 examples · 102 domain cases verified

examples — what the synthesizer saw

discovered Mog program

// No new program synthesized — pure reuse of verified skills:
//   reflect_x = select(hit, neg(vx), vx)
// Primitives used: select, neg (each synthesized + swept independently).

transpiled TypeScript — runs on this page

function reflect_x(vx: number, hit: number): number {
    return select(hit, neg(vx), vx);
}
Composition glue — wiring only, every branch carried by a synthesized functionopen ▾

The synthesizer is strongest on small pure functions and honestly refuses contracts that are too big as posed. These five game rules are wired together from the synthesized primitives. The glue contains no human logic — every branch decision is carried by a synthesized function (select, flag_and, flag_or, reflect_x); the glue only routes arguments.

wallBounce(y, vy, h)flip vertical velocity when the ball is at a wall and moving into it
reflect_x(vy, flag_or(flag_and(hit_top(y), moving_up(vy)), flag_and(hit_bottom(y, h), moving_down(vy))))
clampV(v, lo, hi)keep a value inside [lo, hi]
min2(max2(v, lo), hi)
paddleHit(by, py, ph)is the ball vertically within the paddle span [py, py+ph]?
flag_and(gte(by, py), gte(next_pos(py, ph), by))
paddleTrack(pc, by, sp)move toward the ball, at most sp units per frame (the AI)
min2(max2(sub2(by, pc), neg(sp)), sp)
speedUp(v, vmax)grow speed magnitude by 1 per paddle hit, capped at vmax
select(gte(abs2(v), vmax), v, grow(v))
How this was builtopen ▾
  1. Each game rule was specified only as input → output examples on an integer grid (800 × 600) — no code, no pseudocode.
  2. The nsynth Rust synthesizer searched its program space (expression search, branch search, gradient-guided synthesis) until it found a Mog program consistent with every example and 500 held-out cases.
  3. The transpiled JavaScript was then swept across the game's entire reachable input domain against a reference oracle; any mismatch became a new training example and synthesis re-ran (CEGIS) until zero mismatches remained.
  4. The Mog → TypeScript transpile (mog_transpile.rs) output was embedded verbatim in synthesized.ts — the gallery above shows examples, Mog, and TypeScript for every rule.