11  ·  Eskiv  ·  complete
projectsabout

Sydney

11 · Eskiv

A game from high school

We used to play Eskiv in high school. During Covid I recreated it and wrote a bot that got pretty good at it. This was before I was using coding agents; the game and bot were my own work.

It's different from the learning agents elsewhere on this site. This one looks ahead through possible moves and chooses somewhere it thinks it can survive.

pythonpygamelookahead searchrecreated during Covid
The game

What you’re watching

FIG. 0 · One game, played at speed
A recording of the brute-force agent playing, on YouTube (about 10 minutes).

The large square is the player, the circles are enemies and the small squares are pickups. As more balls fill the field, getting to a pickup safely becomes harder. The bot looks a hundred ticks ahead. If it can't find a target with a safe enough future, the run ends.

Looking back at the bot

What is it actually doing?

Later I made a headless version and ran 10,000 games, recording the frames. Watching a run gives a feel for it, but I wanted to look at a few things across many games:

  1. Does the agent move in straight lines? How close to the shortest route does it actually walk, and does that change as the field gets crowded?
  2. Where does it spend its time? Does a brute-force agent with no notion of “danger zones” still discover them empirically?
  3. How does it die? Is it mostly clipped by fast enemies, or does it trap itself in corners when the field fills up?
Path ratio

Path ratio vs clutter

Straight-line distance divided by actual path walked, per pickup. 1.0 means the agent walked a straight line. Bucketed by how many balls were on the field at the time.

FIG. 1 · 742,146 pickups across 10,000 games
Loading chart…
Mean ratio (line), interquartile range (band), sample count (bars).

Even early on, the bot takes detours around enemies. As the field gets crowded, the paths become much longer. With over a hundred balls, a pickup can require a route more than four times the direct distance.

Where it stands

Where the agent stands

Player-position density by score bucket. Log-smoothed, 16.4 million samples. Auto-scrubs through the game’s life.

FIG. 2 · 12 score buckets, smoothed density
Loading chart…
Top-left is the top-left corner of the game field. Watch it crawl to the walls.

It spends the early part of a run near the centre, then moves towards the walls as the middle fills up. At high scores it often stays near one edge. There's no explicit instruction to hug a wall; that pattern comes out of the search.

How it dies

How it dies

Final score per game. Brute agent, lookahead=100, small field.

FIG. 3 · 10,000 games · mean 381.1 · median 385
Loading chart…
Every death was by trap; zero deaths by direct hit.

In these 10,000 runs, every ending was recorded as a trap, not a direct hit. The search ran out of targets it considered safe before a ball collided with the player. So the zero-hit count says something about how the bot stops, as well as how it dodges.

Things I'm curious about

How cautious does it need to be?

Open question

A hundred ticks of lookahead may be more caution than it needs. I'd be interested to see how the scores change with a shorter horizon, including whether it starts ending through collisions instead.

Open question II

I'd also like to compare it with a learned policy. Would it end up on the same walls, or take risks this search rules out?

Open question III

The routes get steadily more indirect as balls accumulate. I wonder how much of that is unavoidable and how much belongs to this particular bot.

MaterialsPython, NumPy, SciPy, pygame
WhenRecreated during Covid · analysis in 2026
Scale10,000 games · 16.4M steps · 742k pickups
Source github/xnmp/Eskiv_new
Press / for the other projects11 / 12
Index12 / 12

  • 01Tauri ExplorerMy file explorer · Rust and Svelte · notes on building it
  • 02ScrivoMy Markdown reader and editor · Typora-style live preview
  • 03BallastMy mood diary · Markdown files · desktop and Android
  • 04Quickshell barMy Hyprland bar · agent state and quota pacing
  • 05Tableau FrogData exploration · linked charts · AI experiments
  • 06LambdaQueryPython-to-SQL compiler · started in 2017, revisited in 2026
  • 07Ashen CathedralA first-person Diablo experiment · Unreal Engine 5 · paused
  • 08Brood War AIBrood War agent · imitation learning · work in progress
  • 09AutomatedSpikeMagic deck search · learned pilots · XMage experiments
  • 10Zheng Shang YouOur family card game · learning agents · playable version
  • 11EskivA game from high school · recreated during Covid · search-based bot
  • 12Intuition on the Central Limit TheoremCentral limit theorem · interactive mathematical exposition
↑↓ move↵ openesc closeTap a project to open it