No human wrote this game's logic — it was discovered from examples and verified.

Synthesized Pong

Every rule below — ball motion, wall bounce, paddle collision, scoring, the paddle-tracking AI, even 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 on this page are the literal transpiler output. The only human-written code is the canvas renderer, the animation-frame loop, keyboard reading, and the argument-routing glue that wires synthesized primitives together.

0:0
auto-play — press ↑ / ↓ to take over the right paddle

The synthesized rules

For each rule: the I/O examples it was synthesized from, the Mog program nsynth discovered, and the TypeScript this page actually runs. Where the 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 discovered program survived an exhaustive sweep (counterexample-guided synthesis). Rules the synthesizer refused as posed (wall bounce, paddle overlap, clamp, the tracker AI, speed-up) were decomposed into smaller contracts it could discover and verify — the composition glue is shown below the rules.

next_possearch_scalar_expr · 8 examples · 11,781 domain cases verified

1 · 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

2 · Discovered Mog program

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

3 · 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

1 · 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

2 · 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;
}

3 · 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

1 · 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

2 · Discovered Mog program

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

3 · 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

1 · 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

2 · 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;
}

3 · 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

1 · 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

2 · 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;
}

3 · 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

1 · Examples (what the synthesizer saw)

2 · 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).

3 · 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

1 · 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

2 · 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);
}

3 · 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

1 · Examples (what the synthesizer saw)

2 · 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).

3 · 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

1 · 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

2 · Discovered Mog program

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

3 · 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

1 · 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

2 · 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;
}

3 · 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

1 · 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

2 · 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;
}

3 · 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

1 · Examples (what the synthesizer saw)

2 · 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).

3 · 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

1 · Examples (what the synthesizer saw)

2 · 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).

3 · 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

1 · 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

2 · 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;
}

3 · 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

1 · 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

2 · Discovered Mog program

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

3 · 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

1 · Examples (what the synthesizer saw)

2 · 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).

3 · 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

1 · 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

2 · 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;
}

3 · 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

1 · 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

2 · Discovered Mog program

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

3 · 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

1 · Examples (what the synthesizer saw)

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

2 · Discovered Mog program

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

3 · 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

1 · Examples (what the synthesizer saw)

2 · 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).

3 · 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

1 · Examples (what the synthesizer saw)

2 · 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).

3 · 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

1 · Examples (what the synthesizer saw)

2 · 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).

3 · Transpiled TypeScript (runs on this page)

function reflect_x(vx: number, hit: number): number {
    return select(hit, neg(vx), vx);
}

Composition glue

The synthesizer is strongest on small pure functions and honestly refuses contracts that are too big as posed. These five game rules are therefore wired together from the synthesized primitives above. 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 built

  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 manifest above shows examples, Mog, and TypeScript for every rule.