Flythrough.Space Retrospective

I’m not going to rehash don’t remake an old game, but the principle very much applies. Flythrough.Space is a 3d remake of the EV series, and as such suffers from the “remastering someone else’s game” problem. That said, it was a long and involved software project, so there’s got to be something to take away from it, right?



Content Design

Don’t do content design up front. I had reams and reams of content for this project, a holdover from an even older project, making the oldest data seven years old! And the design of the map dates back to an EV Nova TC I attempted in 2005 or 6. The first plan involved using the graphics from Onyx’s Old Shipyard, back when the whole thing was going to be sprite based. FTS, while using the existing data, was 3d from the beginning so needed its own entire suite of assets.

I ended up using Blender because it’s Free Software and I wanted to keep the toolchain as free as possible. I wanted anyone to be able to pick up the same tools and build more content. It took me a while to become minimally proficient with Blender. One thing that ended up looking really cool was making rough textures with blender’s texture paint then applying a “paint” layer in GIMP with clean lines but dusted up with a rough brush and a makes for a worn look. The ships aren’t exactly up to modern standards, but I’m proud of the results nonetheless.

The planets turned out pretty good. Never did nail clouds though.

inshes.png

Technology

Flythrough.Space started out with very basic requirements. I wanted to do the game in 3d, I wanted menus, I wanted to be able to write object oriented code and I wanted to be able to break code into multiple files. Web was a platform I’d been working on for my whole career up to that point, and I wanted to make the game very easy to pick up and play, so web it was. There was a long period of using babel and Angular to compensate for the shortcomings of JS, but eventually we got all the goodies right in the browser! Once I was working in vanilla ES6 with no precompiler or other baggage, working with the code was pretty much a joy.

ECS

I tried to build an entity/component system. All of the game’s behavior is implemented in “systems” which are functions that get run each frame, requesting entities that have specific components to work on. For example:

export function velocitySystem(entMan){
  // Provides inertia.
  for (let ent of entMan.get_with(['velocity', 'position'])) {
    // Do physics
  }
}

The game state all belongs to entities or the player save object. This turned out to be a fairly awkward way to program a game. It was very nice that, say, velocity or AI could be added to any entity pretty easily. But there just weren’t that many different classes of things in FTS. A class hierarchy wouldn’t have become overly complicated, considering the small number of different entity types in the final game (ship, beam, planet, asteroid, projectile, explosion.) One major drawback was how it changed the code layout of the project. If you want to see what code controls the behavior of a ship, you need to browse several different files and it’s extremely unintuitive. Likewise, if you want to know what parameters a ship can have, there is similarly no single place to check out. There is no FTS bible. One possible evolution would be to put every possible ship param into the implicit base class, but then you’ve got a few parameters where absence matters…

Collisions

I wrote a primitive collision library myself, and my attempt to integrate a proper one later was frustrated by a lack of the primitives I needed, specifically objects with no rotation components.

The crowning achievement of the collision system is the line segment collider. Managing to implement (not invent, mind you, merely implement) allowed continuous collision detection which made combat work much better. It also enabled beams, which are a staple of the genre.

Missions

The missions system leverages ES6’s actually very nice text interpolation to make nice templated text. It uses eval all over the place to do it. It’s a bit fiendish how it works, and it works very nicely for stuff like “deliver cargo” but to add features like “go blow up ship” you’d need to add something in the system code to spawn ships depending on active missions. Probably wouldn’t even be so hard, but it’s low hanging fruit that I haven’t picked. Missions where a very late addition, right before the Alpha release. The json to define a mission looks like this:

  "smuggle": {
    "short_name": "Smuggle ${cgo(this.cargo.type)} to ${this.dest.spob}",
    "desc": "Some shady exporters need ${this.cargo.amount} tons of ${cgo(this.cargo.type)} moved discretely.",
    "offer_if": "true",
    "offer_state": "missions",
    "cargo": {
      "type": "${get_illegal_cargo()}",
      "amount": "randint(5,10)"
    },
    "dest": "get_spob_same_govt()",
    "reward": 14000,
    "accept_modal": {
      "text": "The dockhands quietly load the mislabeled containers of \"${cgo(get_legal_cargo())}\" into your hold."
    }
  },

But that sort of thing only covers random cargo missions. I’d designed the world for FTS without giving too much thought to how it would become involved in any sort of story, besides the idea that the Loyal Suns wanted to take everybody over and the Itaskans wanted you to visit every homeworld. This is a problem because in EV games, you’re supposed to play missions to unlock faction ships, and most of the ships in the game (especially the ones I’m most proud of) where faction ships. My inelegant solution: all ships available all the time. No dynamism. Nobody wins or looses. Some people just fight sometimes and if you hail them they’ll give you the slogans of their government. I think that without plotlines, there isn’t much of a hook. There’s certainly no endgame besides grinding up to an Absolver, Nightshade, Capital, Taoiseach, etc.

Data Driven

Every ship, star system, etc is defined in json files. Many previous game attempts had done a lot of work on making a perfect data loader. In this case, I was able to leverage Javascript’s own builtins to make something I’d consider basically perfect (or at least perfect in that it represents an idea taken to its full extent.) You can declare another object as a given object’s prototype and it just works, inheriting values that aren’t overridden. Objects are created on screen by instancing the data (with some enhancement, of course, but it’s all fairly easy to follow.) There’s no intermediary data is what I’m getting at; the javascript objects in the data directly translate to javascript objects in-game. Upgrades work by acting like a diff. Getting all of this to just work was one of the funnest parts of the project and will be the hardest part to let go of.

Community

The babylonjs community, by way of their forum, was extremely helpful. Having real live people who want your project to succeed and can help you use the tools they’ve built is a joy. I would definitely recommend treating community as a critical feature when picking frameworks and libraries.

That said, you also need to cultivate a community around your own project. That’s one angle where I failed in a big way. It isn’t easy to get other people to demo your game. Starting with something very you can get right into, rather than starting a player out as some sort of lowly level one wimp in an RPG might make a lot of sense. I eventually added cheat codes in the form of querystrings (bonus points if you can find them by looking through the source) so players could start in more powerful ships (and so that I could test them without grinding.) But without a large number of testers, tons of bugs slipped through the cracks. It took me way to long to realize that using Control as the fire button simply wasn’t going to work on mac, for example.

If you want to use FTS

I tried to do with FTS what Ambrosia never did with EV: make a totally open system that anyone can pick up, make a game, and truly own that game with. FTS is licensed under the GPL so if you throw in your own assets and release any code changes, you (yes, you!) can make a commercial EV Clone with it. The game scenario lives in the data and assets folders. If anyone has specific questions about how to implement something, I’d be glad to help. But I realized something: nobody is going to mod your game if they don’t love your game. Making a game easy to mod needs to be a secondary concern to making a great game. If you really truly want to build technology rather than a game, I would recommend partnering with someone with a vision for an excellent game, which brings us to our next point.

Putting the cart before the horse

I thought I knew exactly the game I was trying to build from scratch. However I was building it largely in a vacuum and I certainly wasn’t going back to EV Nova to see how the ship movement and turn speed compared. This was probably a mistake. I was so mired in what I could achieve technically that I wasn’t stopping to ask if the game I was building was actually fun or not.

I should have spent the bulk of the development on the basic combat loop, making sure the ship handling was fun, the AI was correct and tight and fun to play against, and the game balance was decent. Instead I focused on creating tons of content and features because I was trying to work from a feature checklist. Feature parity with a twenty year old game does not a compelling game make, as it turns out. On paper, FTS has what it needs, but I feel that it does not live up to that potential.

It’s a mistake I don’t intend to repeat. Future projects I’d like to get in front of people faster, I’d like to be less stuck on design decisions I didn’t even make, and I’d like to have the emotional fortitude to disengage from a project before it takes up half a decade.

Flythrough Space: Beta

It’s been a couple of months since I last wrote about Flythrough.Space. It was the first time I ever got any feedback on the project from people who understood what I was going for, so it was pretty informative. I had productive discussions about perspective and (as I’d feared) overlapping 3d models are a bit weirder than overlapping sprites.

In any case, if you tried it before and thought it was rubbish, you might as well give it another try because it’s radically different, at least in appearance. Go to the settings menu and try out the different options. Message me if you want cheat codes to try different ships (or figure it out from the source!) When in doubt try resetting the settings or refreshing the page.

New Features:

  • Sound effects. Pew pew, etc.
  • Anti-tunneling collisions. Players complained that it was hard to hit stuff; this was partly because of a well known problem called collision tunneling. I bit the bullet and ported over a line collider, so now fast-moving shots should connect more frequently.
  • Implemented a settings menu so that as I started to add GPU and CPU hungry effects I wouldn’t leave people (or my own laptop) behind. It’s slightly jank so I recommend refreshing the page after you leave the menu to make sure the settings take effect.
  • Guided weapons.
  • Asteroids! Mine them for fun and profit! Blow the metal (orange) ones into very small (hard to see) pieces and scoop them up by flying over them. Then go to a market and sell!
  • Lighting effects. Though each star system could already define its own lights, now ship explosions cause a flash in addition to particles. I was reading The Dark Forest and the descriptions of space made it necessary. Also shadows are in but don’t work very well.
  • Piracy! You can now plunder disabled ships for cash and cargo. Press ‘B’ when you’re close to a disabled ship.
  • Starfield. Classic space videogame effect… it lets you see where you’re going. Got some good help on the babylonjs forum with this one. I originally tried to build it with a shader, but gave up and did it with a massive number of sprites.
  • Perspective (or, well, the camera looking at your ship from an angle) is now optional. If you prefer your space-shooters to be top down (because planets getting bigger and smaller is disorienting, for example) you can have that now. An ortho camera proved to be not quite what I wanted, though it would still be cool if combined with a vertex shader that applied perspective to individual objects, to better achieve the look of a sprite-based game but with the lighting benefits of a 3d engine.
  • Impact Physics! When you hit stuff, it gets pushed!
  • Zoom! It became too hard to debug weapon placement without it, so I added it in. Use [ and ] to zoom in and out.
  • Beams! Take an XIC Prospector or drillship out for a cinematic experience.
  • Textures. Ships have them now, including an (optional) glow effect around emissive (self-lit/glowing) bits which I think look pretty cool. Each model has multiple (per-faction) skins which are easy enough to palette swap and add more.
  • Fixed various bugs, including making the map show up right away when you pause the game (now you don’t need to drag it) and explosions now show up reliably.
  • Particle effects everywhere!
  • Every item (ship or upgrade) should be available for purchase somewhere. There’s no notion of unlocks, you just need to get enough cash and drop by the right stellar object. There’s now a test which enforces this!
  • Trade routes. The trade system is still a bit confusing, but the fluff text should direct you to some decent trade routes (or some very lucrative ones, if you are willing to brave pirate infested space!)
  • Alert text at the bottom to tell you, for example, that you’re too close to the system center to engage your sidereal drive (jump to another system.)
  • Optional ‘arcade’ mode where shots don’t inherit velocity from the things firing them. Should make hitting stuff easier. I think it matches the behavior of other genre games. I don’t like it very much myself, but that’s why it’s a setting.
  • Carriers can launch fighters! They don’t do anything particularly clever yet though, they just use the normal AI for the most part. Q to launch, (hold) R to recall, F to attack your target.
  • Saving and loading, so your progress isn’t erased every time you land on the page. Like settings, for now saves are using local storage. You can also upload or download a save file from the same menu.
  • Pause button now takes you to the main menu; press ‘m’ for map and esc to return from the map. This means I don’t need to debounce map button presses and as a result it’s less janky.
  • You can now see which systems are mission destinations in the map, even if you haven’t explored them yet. An orange circle around a system indicates that your mission is there.
  • Code changes: Entity manager is now a singleton, so I should not have to pass it around everywhere. Refactored the HUD into individual widgets. Ships can now inherit from other ships with the “extends” property, which should cut down on clutter in ships.json and make nova-style ship variants much more possible. Input is a lot less gross.
  • Control changes. Using CTL as the fire button wasn’t feasible on Mac. Same deal with +/- for zoom.
  • Data Changes: Cleaned up terminology for factions so it should be much easier to read the data files.

Where we go from here

So what’s next? Well, I’d really, really like feedback. Yelling into the void is less than satisfying. I’d like people to give the game a spin and tell me how horrible it is. One thing I’m especially concerned with is making sure the ships feel right – not too quick, not too fast, not too slow. The weapons could also be a lot more balanced. The biggest improvements to the game at this stage will be all about tweaking the numbers. Nothing would delight me more then someone downloading the game and trying out different tweaks to see if they can find the fun. Yes, I realize that this would ideally be done in the prototype rather than the final game but hey, not all projects can go perfectly.

What do I still want to add? I’d like to fill out the galaxy with more planets and more NPC placement. If anyone wants to write planet descriptions I’ll do my best at editing. A lot of the Loyal Suns, League, and a bit of Freehold territory still needs attention. More diverse asteroids would be cool too. As far as big code features, well, fleets are a big one. More missions would be nice. A more in-depth hailing system to allow planetary domination would be cool and give the game more of an end-state. Also, the AI is full of bugs and would really benefit from the level of unit testing I’ve applied to player.js.

I may take a hiatus from development for a short while, or I might not. I keep telling myself I’ll try to work on another project, but I keep coming back to FTS.

FlyThrough.Space: Alpha Release

I’ve been sitting on this project for way too long. Doomed the project by not soliciting feedback early enough. Failed to heed the warnings of Agile. Kept coming up with reasons not to tell anyone about it, promising that I’d make it public after I added just one more feature. But I think there’s enough that people will be at least intrigued. Or annoyed. The point is that they’ll feel something. I’d be interested to hear any feedback on what’s there and which planned features you’d find most compelling or what would make you likelier to make a mod.

TL;DR: Code Here: http://github.com/eamonnmr/flythrough.space

Play Here: http://flythrough.space

Neat Features:

  • It’s written in Vanilla ES6, only depends on one library (the Babylonjs engine) which is included, so you can hack away on it to your heart’s content without setting up any sort of development environment. Just open up the files, edit them, and host them (locally)
  • 2.5d perspective in a full 3d engine with 2d sprites for planets and projectiles, and a 2d overlay on top.
  • EV/Endless-Sky-esque with the ability to trade cargo, purchase a new ship, add weapons, and do battle in asteroids-style high-stakes space combat. Arrow keys to move, left control to shoot. The default weapon may run out of ammo though!
  • Visible weapons on ships. It’s a capability, even if I haven’t added bones to most of the ship models to take advantage of it. If done right I expect it will be super immersive.
  • Original, handcrafted (unfinished) universe to explore. For all of you fans of non-procedural-generated worlds.
  • Open architecture allowing for radical gameplay changes and a totally data-driven model.
  • Press ‘Escape’ to see the star map (bug: drag it around if it does not show up right away). Select a system, exit the map, and press ‘J’ to jump to that star system. You can only see explored systems and systems linked to them, which won’t be very many at first, but there’re lots out there to explore.
  • Press ‘L’ to select a nearby planet and ‘L’ again to land
  • press ‘`’ to select the nearest other ship
  • Select “open contracts” after landing for random cargo missions

Planned Features (don’t count your features before they ship):

  • More missions/storylines.
  • Save and restore game. I’ve got it set up to save and load from local storage, just need a menu to select your save. I didn’t set out to make a roguelike.
  • Secondary weapons. Right now when you pull the trigger, everything goes off at once. Also a prerequisite for stuff like carried ships.
  • Beam-based weapons. Need to add a beam collider to the collision system. Explored adding a real physics system but they’re mostly overkill for this type of game; writing a beam/circle collision system may change that. It would also let me implement anti-tunneling for projectiles (collide a line segment between the previous position and the current position.)
  • Decide what to do with ai leading. You can switch leading on and off with querystring ?ai_leading=basic which will make the AI try to lead its shots. But it uses a basic approximation so it still misses a lot.
  • Turrets. Getting the math, blender export/in-engine-use toolchain set up to make visible turrets on ships has proven frustrating. Some of the code is there but it would take a not insignificant amount of work to finish. Which is probably why I keep putting off…
  • Starfield. Will have to probably do this by hand with star sprites.
  • Nice ship models with textures! I’ve been cranking out kinda lousy models as programmer art (thinking that the final art will maybe have different constraints – visible turrets being a big one), but someday it would be cool to put some more effort into it. Hampered by the fact that I mostly work on this on a train so I don’t usually have room to use a mouse.
  • Sound. There isn’t any. I just haven’t gotten around to it, I can’t imagine it’ll be too hard to throw in there.
  • Escorts/Carried Ships. The AI and collision systems are set up for it, and some recent refactoring has probably opened the door to it. Just takes some doing.
  • Board/Plunder/Capture-this just needs some doing, but shouldn’t be a huge technical hurdle.
  • Demanding tribute/galactic conquest/planetary destruction – would require a bit of additional work, but not much. Unclear to me if this is a feature people really want.
  • Zoom in / out: Just needs the controls rigged up to do this, but it’d be kinda cool (right?)
  • The GUI could definitely look a lot nicer, and the code could probably be cleaner. I’m not a graphic designer.

I plan to keep hacking away on it at the slow-but-mostly-steady pace that you can see from the (lengthy) commit history. If you want to play a complete game now, this isn’t for you. But if you’ve always wanted to hack on an EV clone but the other ones where too intimidating or weren’t 3d enough, maybe this is your ticket. Will definitely check out any Pull Requests (or, for that matter, emailed diffs) that come my way, and I’ll try and do a walk-through of major interesting bits in the code in future blog posts. If you’re still reading this far down, you are the target audience! Let me know what features you would like to see most, what would make this project compelling for you to use/fork, or what utterly repulses you about it. I’m all ears.