benadams.

Walk through every project in a 3D museum.
About 18 MB download
Prefer the boring version? Keep scrolling
A full raft squeezing past a rock in a sunny rapid, close enough to count as a near-miss.
In development
Middle Fork Rafting Simulator
A co-op rafting game where everyone paddles the same raft.
A multiplayer rafting game I'm making in Godot. You and your friends play river otters in oversized helmets, paddling one raft down a procedurally generated Idaho canyon to deliver cargo to the take-out. The water physics are based on real rivers.
- Jobs. Pick a cargo like a wedding cake, a beehive or a piano and get it to the take-out flag. Hit something too hard and you lose a tier of the cake.
- Join by code. Friends can join with a three-word code or a link, even after the trip has started. If the host leaves, the trip keeps going.
- Real rapids. Each canyon is generated from a seed. Rocks can pin the raft, holes can trap it, and waves can launch it.
- Rescues. Use throw bags and ropes to pull swimmers back in or haul the raft off a rock. If someone gets stranded, a bird carries them back to the raft.
Testing on Android
Oathkeep
A guild chat app with a co-op idle ARPG built around a daily check-in.
Once a day the app asks everyone in the guild whether they kept their oath. You decide what your oath is, like a run, a lift or twenty minutes of practice, and it's on the honor system. Checking in powers up your hero, the guild's hearth and that week's raid. Fights play out while you're away, and you can watch the replay when you come back.
- Builds. Put any support gem on any skill it fits, pick from a constellation of over a hundred stars with keystones that change the rules, and respec for free. Builds can get pretty broken. Court of Bones never attacks, and its minions do five times the damage of a basic build in the same gear.
- Fight breakdowns. After each fight you get the time, DPS and damage taken, plus a breakdown of where the damage came from, your biggest hit and your best second. Fights are seeded, so a guildmate can replay yours exactly.
- Endgame. The Unlit Hall is the twelfth and final zone. After that, the Unlit Depths keep going one level at a time, with a boss every ten levels. Gear stops improving, but the difficulty keeps going up.
- Rest days are fine. Your power is based on the last two weeks, not your total playtime. Taking a day off doesn't cost you or the guild anything.

A Court of Bones skeleton army fighting the final zone's boss.

Each feature is a building you walk to. Tap the seal at the bottom to check in for the day.
Prognosticator
Command Center
The home screen links to all the tools: Now Playing, Effect Picks, the Disperser, Lights, Gear Setup, Scene Controls, and your playlists and tags. When you import a Spotify playlist, it downloads each track from YouTube and gets the BPM and key from VirtualDJ.

Command Center
hobbit.house
Phone control app for a living room mini PC. Launch games and streaming apps, run a music visualizer on the TV, and control lights, Kodi and cameras. A QR code turns a guest's phone into a game controller.

Smart light controls
Prognosticator: visualizer scenes
Prognosticator also sends its beat grid and DMX output to a visualizer I built in Godot, so the same light cues play in a virtual venue.

The biggest outdoor area with the whole rig in red, and the giant structures on the horizon.
Warehouse
A procedurally generated club, lit only by DMX values. The same rigs, actions and Effect Picks cards that run the real lights also run its 104 virtual fixtures. Each load builds a new layout: concrete rooms, blacklight hallways with graffiti, and outdoor plazas up to 200 meters across with huge wheels, towers and arches on the horizon. A virtual camera cuts between wide, drone, jib and crowd shots on the beat.

Mario running toward a bank of coins used as blinders, under star-shaped pars and a laser.
Super Mario 64
The warehouse's DMX lights reskinned for Super Mario 64: the pars are Power Stars, the moving heads are cannons, the lasers are Amps, and the lava is eight pars. The open-source decomp port runs as a library inside Godot, and Godot renders each frame. All 45 areas have their own lighting setup and DJ Peach on the decks. An autopilot plays Mario in time with the music while the camera cuts between nine angles. Bring your own ROM.

CPU drivers racing through Luigi Raceway, Toad's Turnpike and Bowser's Castle at night, with the lights running live.
Mario Kart 64
Mario Kart 64 running under the same 104-light rig as the warehouse, so the lights, rigs and Effect Picks cards that run the club also run the racetrack. The decomp's PC port is built as a library that Godot steps one frame at a time and renders. All 20 courses (16 race tracks and 4 battle arenas) have their own lighting setup. When nobody's playing, CPU drivers race while the camera cuts between 12 angles on the downbeat, and up to four people can grab a controller and play split screen. Bring your own ROM.

testq
A job queue for all the Godot runs on my PC.
The warehouse, the two Nintendo scenes, the rafting game and Oathkeep all run their tests and captures on one PC, from a couple dozen worktrees at once. When two test suites started at the same time, they slowed each other down enough to fail timing-sensitive tests, and those failures looked just like real bugs. testq is a small daemon that hands out the machine's CPU and GPU slots, and each run script checks with it before launching Godot.
- Separate from the projects. A capture in the DJ app and a physics test in the rafting game don't know about each other, so the queue lives in its own repo outside both.
- Shortest first. It estimates each job's length from its past runs, so a 20-second test doesn't get stuck behind two 11-minute suites. Jobs that have been waiting a long time move to the front.
- Hung runs get killed. If Godot stalls or runs past its time limit, testq kills it and frees the slot. If a client crashes, testq takes its slots back in about five seconds.
- Status page. A web page and a tray icon show what's running, what's queued and roughly when it'll start. Finished runs are saved in SQLite, which makes flaky tests easy to find.
Scrandle
A weekly game made from my friends' dinner photos. You get ten pairs of plates and pick the one the group rated higher, then see the ratings and who cooked each one.

Two plates from the Discord. Pick the one people rated higher.
Scranbot
The Discord bot behind Scrandle. Every day it posts a food photo matchup in our group's channel, keeps the votes hidden until voting closes, and then posts the result. Once a week it posts standings with rank changes.
Today's matchup


Rank the plates



Yut Hut
A Discord bot for my friends that turns workout check-ins into Old School RuneScape progress. Each check-in counts as a Slayer session using the game's real XP and drop tables, and the bot posts the results as OSRS-style cards.
- Two a week. Your first two check-ins each week count in full. After that they count for half, then a fifth. Rest days get logged and don't cost you anything.
- Morning check-in. Each morning the bot posts a yes-or-no question and updates the post as people answer.
- Real game data. Monsters, Slayer masters, drop rates and gear all come from the OSRS Wiki. The only number I tuned is how long a session lasts.
- Goals. Clue caskets, a choice of three rewards, gear drops, an Achievement Diary, a quest, and a group boss each week.
Act 1 · Week 3 · Day 17 in Lumbridge
Did you work out in the last 24 hours?
Yesterday: Bramble (verified by Odo), Odo, Tamsin. 3 of 6.
Week so far: 4 in form, 1 with one to go.
Quest: Rune Mysteries, supplies 2/3.
🌿 Bryophyta ██████░░░░░░ 46%. Every check-in takes a swing.
🎁 Today's spoils: Magpie impling jar (rare) is on the table for every full-value check-in.
✅ Bramble, Odo · 😴 Marlowe · 3 still to answer
Bramble checked in (2nd this week, full value). ⚔️ 23 hill giants slain (23/40 on task). Strength 54! Slayer 58!

🎁 Bramble opened a magpie impling jar (rare): 2 diamonds, 1 dragonstone, 5 gold rings, 8,200 coins, 3 ruby rings, 4 emeralds. 62.4k gp.

Odo checked in (1st this week, full value). 📜 Odo opened a hard casket: Robin hood hat!

Slayer 60!


✨ Bramble's gear


Magic: The Gathering
Tools for Commander players and deck builders
MTG Commander Scorekeeper
Touch-friendly scorekeeper for Commander. Four-player quadrant layout with life, poison, and commander damage tracking.
Magic Tutor Helper
Import a decklist from Archidekt and filter it by mana cost and card type, with Scryfall card images.
MTG Token Helper
Import a deck and it finds every token the deck can make. Track them on the battlefield with tap/untap, counters, and buffs.

Tutor Helper
FloatWise
Float trip planner. Hourly forecast tables for multiple locations with the live Yellowstone River flow, and a map for pinning put-ins, take-outs, and swim spots.

Dota 2 Randomizer
Spin two wheels to get a random hero and a random item to build. Canvas-animated wheels fed by live OpenDota data, with sound and confetti.

IRLScape
Old School RuneScape streaming overlay. Game UI on a live camera feed with Twitch chat integration and Joycon controls.
OSRS Progress Generator
API for generating progress report images for Old School RuneScape players. Collection log items, OSRS Wiki integration.

