Downloads · 30 days
0
Cochon123/tileman-io-ai
tileman-io-ai is a machine learning model from Cochon123. Use it for the machine learning task on the model card, and read the license before you ship it in a product.
A local Tileman.io-style multiplayer simulator, live AI spectator, and compute-efficient reinforcement-learning environment. The simulation core is written in Rust, the training interface uses Python/Gymnasium, and th…
Downloads · 30 days
0
Access
Public
Updated Jul 24, 2026
Repo size
475 MB
Likes
0
Public
Click a slice to open those files.
.zip18.7 MB · 100%
From the Hugging Face model README
A local Tileman.io-style multiplayer simulator, live AI spectator, and compute-efficient reinforcement-learning environment. The simulation core is written in Rust, the training interface uses Python/Gymnasium, and the spectator runs in the browser.
Clone the code and create an isolated Python environment:
git clone https://github.com/cochon123/tileman-io-ai.git
cd tileman-io-ai
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -r requirements-rl.txt
python -m pip install maturin huggingface_hub
Build the optimized Rust simulator:
maturin develop --release
Download the three published best models from Hugging Face:
hf download Cochon123/tileman-io-ai --local-dir runs
Start the world builder:
npm run dev
Open http://127.0.0.1:4173. Choose a world size, simulation speed, AI policies, and the number of instances of each policy, then press Start.
The selector includes the three main policies:
first: the original conservative capture policychampion: the tournament-selected multiplayer championkiller: the fresh-from-scratch combat policyThe world builder lets you choose:
Starting a simulation loads the selected policies on CUDA and opens the live world. Use the Exit button in the spectator header to stop that simulation and return to the world builder.
If CUDA is unavailable, change the device to cpu in direct Python commands.
You can verify GPU support with:
python -c "import torch; print(torch.cuda.is_available())"
maturin develop cannot find Rust, install it from
https://rustup.rs, restart the shell, and rerun the command.hf is not found, reactivate .venv or run
python -m pip install huggingface_hub.Run 32 clones of the best trained PPO policy on one shared 256×180 world:
npm run spectate -- --device cuda
Open http://127.0.0.1:4174. The first launch can take a little while while PyTorch initializes CUDA and loads the model.
Spectator controls:
The server batches every visible clone through runs/ppo-conservative/best/best_model.zip; these are instances of the trained policy, not scripted browser bots. World size, population, model, and tick rate are configurable:
python3 -m tileman_rl.spectator_server \
--model runs/ppo-conservative/best/best_model.zip \
--agents 32 \
--cols 256 \
--rows 180 \
--tick-rate 12 \
--device cuda
To watch the Killer policy, select its checkpoint explicitly:
npm run spectate -- \
--model runs/ppo-killer-v1-cuda/best/best_model.zip \
--device cuda
The spectator detects whether a model uses the original four observation channels or the multiplayer seven-channel view, so both generations of checkpoints remain usable.
To place half of the old agents and half of the new agents on the same map:
npm run spectate -- \
--model runs/ppo-conservative/best/best_model.zip \
--model-b runs/ppo-champion/best_model.zip \
--agents 32 \
--device cuda
The leaderboard labels the two groups OLD and NEW. With an odd population, the extra agent is assigned to the new model.
The same champion match has a shortcut:
npm run spectate:champion
To compare all three generations with 11 agents each:
npm run spectate:all
This runs the original model (OLD), the fresh-from-scratch combat policy
(KILLER), and the tournament-selected champion (CHAMP) on one shared map.
Policy assignments are interleaved by agent ID to reduce movement-order bias.
runs/ppo-champion/best_model.zip was selected by paired-seed tournaments, not training reward. Every world seed is replayed with model assignments swapped to cancel spawn and agent-ID advantages. In the final 32-agent, 256×180, 1,000-tick validation, the champion controlled first place for 56.4% of ticks versus 43.7% for the old model, with more captures and kills and slightly fewer deaths.
The champion is an evolved variant of the old capture policy with a small deterministic action-logit adjustment, discovered after PPO league branches were rejected whenever they failed the same tournament. Reproduce a comparison with:
python3 -m tileman_rl.tournament \
runs/ppo-champion/best_model.zip \
--baseline runs/ppo-conservative/best/best_model.zip \
--matches 4 --agents 32 --cols 256 --rows 180 \
--ticks 1000 --device cuda
Run the JavaScript model tests with:
npm test
The browser exposes the environment at window.tileman:
tileman.reset();
const transition = tileman.step("right");
console.log(transition.observation, transition.reward, transition.terminated);
Actions are up, right, down, and left. An observation contains a flat Uint8Array grid (0 empty, 1 owned, 2 trail), grid shape, player position/direction, trail length, area, and step count.
The browser reward now mirrors the conservative training reward: captures are positive, dying is -1, and exposed trails longer than 12 cells become progressively more expensive.
The Python environment uses:
straight, left, and rightThe reward is:
+0.01 × newly captured tiles
-0.0001 per step
-0.002 per step outside owned territory
-0.001 × every trail cell beyond 12
-1.0 on death
The excess-trail cost is applied on every exposed step. Long trails therefore become increasingly unattractive, but remain possible when a large capture justifies the risk.
Run all Python contract and rule tests:
python3 -m unittest discover -s tests -v
The single-agent and multiplayer training environments automatically use a native Rust core when it is installed. The multiplayer training core keeps the world, scripted opponent plans, trail kills, capture flood fill, respawns, rewards, and observation buffers in Rust, crossing into Python once per Gym step. The general shared-world class also has a compatibility-oriented Rust backend while preserving its mutable NumPy grids for spectators and policy leagues.
Build the extension in a virtual environment:
uv venv
uv pip install -r requirements-rl.txt
uv pip install maturin
uv run maturin develop --release
Confirm the selected backend and compare it with the NumPy reference:
python3 -c "from tileman_rl.env import TilemanTrainingEnv; print(TilemanTrainingEnv.backend)"
python3 -m benchmarks.benchmark_env --steps 50000
python3 -m benchmarks.benchmark_multiplayer --steps 30000
If the native module has not been built, both environments safely fall back to
their reference Python implementations. Pass backend="python" to
MultiAgentWorld or MultiplayerTilemanEnv for differential debugging;
PythonTilemanTrainingEnv remains available for single-agent parity testing.
Start a short CPU experiment:
python3 -m tileman_rl.train \
--timesteps 100000 \
--n-envs 8 \
--device cpu \
--output runs/ppo-conservative
Training begins with 20,000 actions from the conservative rectangle expert and four balanced behavior-cloning epochs. This prevents PPO from discovering the safe-but-useless strategy of circling inside its spawn forever. The expert bootstrap can be changed or disabled:
# Faster development probe
python3 -m tileman_rl.train --timesteps 10000 --expert-steps 5000 --bc-epochs 3
# PPO from scratch, mainly for comparison
python3 -m tileman_rl.train --timesteps 100000 --expert-steps 0
Once python3 -c 'import torch; print(torch.cuda.is_available())' returns True, use the GPU:
python3 -m tileman_rl.train \
--timesteps 1000000 \
--n-envs 8 \
--device cuda \
--output runs/ppo-conservative
Evaluate a checkpoint over fixed deterministic seeds:
python3 -m tileman_rl.evaluate \
runs/ppo-conservative/best/best_model.zip \
--episodes 100
Evaluation reports area, captures, survival, peak trail length, reward, and death causes. TensorBoard is optional; install it separately if training charts are wanted.
The multiplayer environment puts one learning agent and six opponents in a shared world. Its seven-channel local observation adds enemy territory, trails, and heads to the original four channels. Existing capture models are widened from four to seven channels while preserving all learned weights.
Training uses two stages:
Run the complete curriculum from the original capture model:
python3 -m tileman_rl.train_multiplayer \
--source runs/ppo-conservative/best/best_model.zip \
--timesteps 1000000 \
--combat-fraction 0.3 \
--n-envs 8 \
--device cuda \
--output runs/ppo-multiplayer
Continue outcome-only training from an already widened combat model:
python3 -m tileman_rl.train_multiplayer \
--source runs/ppo-multiplayer-v2/combat_model.zip \
--timesteps 700000 \
--combat-fraction 0 \
--n-envs 8 \
--device cuda \
--output runs/ppo-multiplayer-final
Evaluate under normal or trail-hunting opponents:
python3 -m tileman_rl.evaluate_multiplayer \
runs/ppo-multiplayer-final/best/best_model.zip \
--episodes 100 --envs 8 --device cuda
python3 -m tileman_rl.evaluate_multiplayer \
runs/ppo-multiplayer-final/best/best_model.zip \
--episodes 100 --envs 8 --device cuda \
--aggressive-opponents