🌓

SpaceTurf: Building an Offline Homage to Subspace Continuum SpaceTurf is an offline single-player 2D space shooter inspired by Subspace Continuum, with many maps, ships and battles with up to 99 AI bots.

by
on September 13, 2026
(10 minute read)

I spent a lot of time playing Subspace in the late 1990s. Later it became Subspace Continuum, but the basic idea was the same: small 2D spaceships, huge maps, simple controls, lots of other players, and surprisingly deep fights over territory.

Please donate to keep this server up

It was one of those games that didn’t need much explanation. You joined a zone, picked a ship and started flying.

The graphics were basic even by the standards of the time, and the controls were almost entirely keyboard-based. There were no elaborate progression systems or endless menus. The interesting part came from the movement, the maps, the different ships and what the other players decided to do, and I loved it.

I recently looked at it again and, while Continuum still exists, the population is obviously nowhere near what it used to be. That’s understandable. It’s a very old game competing with an absurd amount of newer stuff, from free-to-play games to massive AAA releases.

Still, playing around with it again reminded me how much I like that kind of design. A game can be visually simple and mechanically small while still being very good.

That eventually turned into SpaceTurf, an offline single-player 2D space combat game inspired by that experience.

You can play it here: https://xaviesteve.com/pro/spaceturf/

SpaceTurf isn’t a recreation of Subspace. I didn’t want to copy its maps, ships, artwork or exact mechanics. It is more of a homage to the sort of game I remember enjoying: large maps, inertia-based spaceship movement, territory control and battles where positioning matters as much as shooting.

The main difference is that SpaceTurf doesn’t need any other players so you can play it any time anywhere, it even plays on slow computers, and offline.

Making a multiplayer-style game that doesn’t need multiplayer

The obvious problem with making something inspired by an old online game is population.

A multiplayer arena can be great with 50 people and almost pointless with two. For a personal project, relying on enough people being online at the same time didn’t make much sense.

I decided to design SpaceTurf as single-player PVE from the beginning.

A match can have anywhere from 2 to 100 ships. The player is part of one team and everyone else is controlled by AI, including the ships fighting alongside you.

That means a full match can have 99 bots running at once.

I didn’t want those bots to exist simply to provide things to shoot at. They needed to play the actual game.

They capture flags, defend territory, attack enemies, escort teammates, retreat when damaged, look for safe places to recover, support pushes and switch objectives as the situation changes.

Bots can also flank rather than always following the most direct route. They react to mines, incoming projectiles, shields, cloaked enemies and teammates that need help.

There are six broad bot personalities: Vanguard, Raider, Warden, Skirmisher, Escort and Opportunist.

A Vanguard is more willing to stay in a fight. A Raider cares more about territory and alternative approaches. Wardens lean toward defense. Escorts protect useful teammates, while Opportunists tend to notice exposed objectives and damaged enemies.

These aren’t fixed classes, a bot can still change its tactical role during a match.

There is also some individual variation underneath those personalities. Bots have their own courage, preferred combat distance, accuracy, patience, movement tendencies and energy reserves. Those characteristics stay with them after they respawn. The idea was to avoid having 99 copies of exactly the same AI flying around.

Turf rather than deathmatch

The main SpaceTurf game mode is built around flags scattered across the map.

Flying inside a flag’s capture area contributes to taking it. If enemies are there too, they can slow or completely stop the capture depending on the numbers involved. Sending several ships to an objective captures it faster, although there is a limit to how much speed you gain from piling everybody onto the same flag.

Enemy-owned territory also takes more work to capture. First the flag has to be pushed back to neutral. Only then can your team capture it.

Each side starts the match with a number of tickets. Ships consume a ticket when they redeploy after being destroyed, but kills aren’t the only way to reduce the opposing team’s supply.

If your team controls more territory, the enemy continuously loses tickets.

That changes the way a match develops. A team can be doing well in individual fights and still lose because it has given up too much of the map.

It also gives the bots something meaningful to think about besides the nearest enemy. Sometimes attacking another ship is useful. Sometimes staying inside a capture radius is more useful. Sometimes leaving a fight and defending a flag on the other side of the map is the right decision.

That tension is a large part of the game.

Twelve zones with different layouts

SpaceTurf currently has 12 zones, ranging from compact arenas to maps several thousand pixels across.

I didn’t want them to be the same arena with walls shuffled around. The capture and ticket rules remain identical, but the geometry changes how teams move.

Frontier Basin is an 8,000 × 8,000 map with open routes, covered sections and remote objectives. It is large enough for several fairly independent fights to happen at once.

Pulse Yard is much tighter. Three neutral flags sit close to each other in an exposed central area, so teams have to spread across the yard while remaining close enough to support one another.

Switchback Foundry is arranged more like a front line, with teams progressing through bends and staging areas toward a large central chamber.

Undertow Docks has flags inside dead-end bays. Going deep into a dock to capture one leaves you with the problem of getting back out through the same entrance.

Ashfall Ring puts a large solid reactor in the middle of the map, forcing traffic around it, while Driftglass Expanse has the opposite character. Its center isn’t very useful and the objectives sit far apart, so movement and interception become much more important.

The other zones experiment with fortified courtyards, divided battlefields, relay rooms, gates and different combinations of safe and exposed objectives.

I like having the variation come from the map rather than introducing a new collection of rules for every zone.

Eight ships, one special ability each

There are currently eight playable ships.

They differ in hull strength, acceleration, maximum speed, turning, weapons and combat role.

The Needle is fast and accurate and has a long-range Snipe special. The Seeker gets a Homing projectile. The Lancer combines high sustained primary damage with a Shield.

The Specter is heavier and slower and can Cloak.

The Seraph is the support ship. Its normal weapon is weaker, but it can heal nearby teammates.

The Mauler is deliberately slow and works best at short range. Its primary weapon fires a broad five-projectile spread, while its Payload special launches a slow bomb over a much longer distance.

The Marauder deploys mines.

Finally, the Bastion is a heavy defensive ship that can Deflect incoming projectiles. Its Deflect ability can also clear nearby enemy mines, which becomes useful when fighting around narrow routes.

Every ship also has Turbo on Shift.

Turbo isn’t another special ability. It consumes weapon energy while you hold it, which means travelling or escaping faster reduces the energy available for firing. I prefer small interactions like this to adding another resource or cooldown system.

Keeping the old keyboard flight model

Movement was one of the parts I cared about most.

SpaceTurf uses keyboard controls rather than mouse-directed movement. You turn with left and right, thrust with up, reverse with down, fire with Space, use Turbo with Shift and activate your ship’s special ability with Q.

The ships have inertia. They don’t instantly point themselves in the direction of travel or stop when a key is released.

Different hulls also feel different to move. Some accelerate and turn quickly, while heavier ships take noticeably more commitment to change direction.

This sounds simple from the player’s side, but it made the bots considerably more complicated.

An AI-controlled ship can’t just move toward an (x, y) coordinate. It has to steer toward it using the same turning, thrust and inertia system as the player.

It also has to avoid walls, navigate around blocked routes, slow down before corners, dodge threats and still keep its weapons pointed somewhere useful.

SpaceTurf builds routes around the zone geometry and then combines those routes with local steering. Bots can skip unnecessary waypoints when they have a clear line, choose alternative paths around mines, brake before obstacles and attempt to recover when they get stuck.

Doing all of that with 99 bots meant performance became part of the AI design as well.

Plain JavaScript, Canvas and no server

The whole game is intentionally small from a technical point of view.

SpaceTurf is written in HTML, CSS and plain JavaScript. Gameplay is rendered with the Canvas 2D API.

There isn’t a game engine involved, and there isn’t really a build system either. The deployed version is essentially the source files and assets copied into the public directory.

Audio is generated in the browser too.

Instead of including sound effect files, audio.js creates the weapon sounds, hits, explosions, mines, specials and other effects at runtime using the Web Audio API, mostly from oscillators and filtered noise.

SpaceTurf also works as a Progressive Web App. Once the necessary files have been cached, it can run offline.

That ended up fitting the project particularly well.

There is no login, no matchmaking server and no dependency on an active player community. I can open it years from now, choose 100 ships and still have a full match.

What I wanted to keep from old games

I don’t think old games are automatically better because they’re old. There were plenty of terrible games in the 1990s too.

What I miss in games like Subspace is something more specific.

You could understand the basic game almost immediately, while still spending a very long time getting better at it. Most of the depth came from the interaction between movement, weapons, maps and other players rather than from having hundreds of systems layered on top.

SpaceTurf became my attempt to build something around that idea.

It has more AI underneath it than the graphics suggest, and there are plenty of details in the capture system, ships and maps, but the part the player sees is still straightforward: pick a ship, enter a zone, fly around, shoot things and try to control more territory than the other team.

Simple Cloud Hosting Built for Developers

No account is required, 100% free, and nobody else needs to be online. For a game inspired by something I was playing almost 30 years ago, that feels like the right format.

Play SpaceTurf: https://xaviesteve.com/pro/spaceturf/

Free 100% online banking account

💳 Get your free debit Mastercard

No comments yet

Your email address will not be published. Required fields are marked *

Treasure Chest

Get notified of new projects I make
Usually one email every 3 months

Follow me for cool new products and interesting findings on graphic design, web development, marketing, startups, life and humor.


/*Twitter*/ !function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs"); /*Facebook (function(d, s, id) {var js, fjs = d.getElementsByTagName(s)[0];if (d.getElementById(id)) {return;}js = d.createElement(s); js.id = id;js.src = "//connect.facebook.net/en_GB/all.js#xfbml=1&appId=28624667607";fjs.parentNode.insertBefore(js, fjs);}(document, 'script', 'facebook-jssdk'));*/ /*Google+*/ window.___gcfg = {lang: 'en-GB'};(function() {var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;po.src = 'https://apis.google.com/js/plusone.js';var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);})();