State Vector December 24


Happy Hollydays, everyone!

I mean, I’m a bit late for Christmass, a bit early for new year, and probably way too late for both when you get around to reading this. But during these days I have some on-and-off spare time in-between things that don’t necessarily allow for any deep focus, but are just fine for chipping away at a devlog, and since one is due anyways, that seemed a good thing to do…

Certified orbital mechanic

..Is a thing I am not, unfortunately. As you may know if you read this devlog regularly, the current focus of development is to put orbital mechanics in the game. So far, they’re mostly fake. Delta-v calculation is kind of accurate, and everything in the game has an orbital shape, but nothing actually has a position. Changing that is necessary for several reasons. One, to make the game more interesting, two to make it more consistent and predictable by orbital transfers not just having some random window, and three because my conscience just won’t shut up about it.

But changing that makes things a whole not more complicated. I had the first idea of how complicated it would get before I started, since I’m halfways acquainted with the basics. As is often the case in software development, however, I didn’t have the second and the third idea. Progress is accordingly slow, and hard fought over.

Ork it!

Like any reasonable software developer, I started by looking for libraries to make my life easier. One shouldn’t reinvent the wheel without good reason, and certainly most of the problems I was about to tackle had already been solved. It turns out that’s not exactly the case. In the JVM ecosystem, I found only two libraries that seemed like they’d fit the bill. Something from NASA that doesn’t seem to have been updated in ages, which is usually a no-go unless we’re talking about very mature software, which this doesn’t seem to be. And then there’s orekit, which still seems to enjoy development, and seems to be the standard when it comes to orbital propagation.

There is, however, one major problem with that library for my use-case: It’s too serious! Orekit is not a tool for games. It’s a tool for real-life space applications. It doesn’t just do propagation. It does n-body perturbation, it does relativity (read time dilation), and it does bloody non-spherical gravity, all of which requires a whole bunch of data to initialise, and it won’t work without that. While the library itself is only 5 MB in its compiled state, the data needed to make it all tick is around 20 MB. That on its own wouldn’t necessarily be a deal breaker. But of course I do not have accurate data available for the time around 2100 when the game takes place. Obtaining it would be a time investment in and of its own. But then, there’s that whole complexity that will make the very simple, naive propagation that’s perfectly sufficient for this game more complicated to work with.

All of that would still have been fine, still have been worth it, if orekit would have provided me with tools to automate flightplan and manuever calculation. But Orekit has nothing of the sort. Because that kind of thing is not really useful in the context where orekit is usually employed, i.e. current-day, real-life space applications. You simply don’t need any kind of automation that calculates how your satelite gets from trajectory a to trajectory b. You want a team of people fiddling with that until they nail it down to the absolute minimum of propellant required, down to the last gram. Orekit comes in when you need to simulate and evaluate the result, not for planning the trajectory per se.

And so, at the end of the day, all I’d have gotten from orekit was orbital propagation, a couple orders of magnitude too precise and too complex for my use case, in a black box that might hold some surprises and caveats down the line in an oversimplified scenario. I decided that’s too many drawbacks. Instead of integrating orekit into the game, I decided to “Ork it” instead. I.e. build the simplest thing possible and bash it with a hammer until it fits. Possibly paint it red while I’m at it. Orekit still had a place in this, though. It allowed me to design reliable test scenarios that my own code could be run against to make sure it works. Which was by no means an unimportant part, considering how many bugs I squashed while running those tests…

The moving target isn’t the problem. Moving your aim is!

Naive, purely deterministic keplerian orbit propagation isn’t that big of a deal. Well, not after Kepler worked out the equations and we have nice rundowns on the net like this one here, which was very valuable indeed for coding this up. I knew that just the propagation wasn’t the major problem in advance. It’s not entirely my first rodeo. If simplistic propagation was extremely complicated, I’d probably still have gone with orekit. But with today’s availability of information, it largely boils down to coming up with a good code structure and dropping equations that you don’t necessarily have to understand in their entirety into the blank spaces that calculate your orbital properties, and voila, your stuff starts to move in orbits.

But that was just the ground work. Navigating in space is all about being in the right place at the right time, and if you miss one of those criteria, you’ve accomplished nothing. Since all my stuff now is in a certain place at a certain time, the player’s trajectories have to get those two criteria right, or things fall apart. And that’s where the trouble started.

I had introduced some simplifications right off the bat. Everything currently has the same longitude of ascending node. Chances are you don’t know what that means, and it’s not that important. It doesn’t really have any effect on the game, apart from looking a bit boring on a map. But a map there isn’t yet, so I’m not worrying about that yet. The other simplification is that all stations are moving in perfectly circular orbits. This is at least approximating reality in that any space station that would expect regular traffic from various orbits would do its damn best to keep its orbit circular. Why we would ever have a series of space stations that optimize for mutual reachability rather than optimising for being reached from one certain point is another question entirely that I’m not going to go into here.

The LAN simplification removes a couple terms from a couple equations and allows me to build a first iteration of the whole system with one factor less to worry about. Making all potential departure and arrival orbits circular… Well now, that makes everything a lot simpler, as it turns out. Much more so than I anticipated. Which doesn’t mean that just finding transfers between circular orbits was exactly easy, at least not for someone that sucks at math as much as I do. No, what it means is that once an orbit is not circular anymore, things get way more complicated than I thought they would get. Which is what I’m currently hung up on a bit.

See, I thought I could just implement Hohmann transfers between circular orbits, integrate that into the game, and then have the whole game work in exactly the way it does right now, except trajectories would now make more sense. That wasn’t the final goal, since I also wanted to embed navigation into the current game mechanics, i.e. something the player gets at least some say in rather than just being railroaded. But it would have been a nice intermediate state to push an update and continue working from. Alas, there was just a tiny problem I’ve overlooked.

It may seem eccentric, but it’s no extravaganza…

So, the player starts at a station, which, as mentioned, has a perfectly circular orbit. They plan a Hohmann transfer to a target, which is also in a circular orbit. So far so good. But once they inject themselves into their transfer trajectory, they’ll be moving on a rather eccentric orbit (For the laypeople, that means a big honking elipse). The elipse was fairly simple to calculate since it is very narrowly defined by the starting and ending orbit. But let’s just assume for a moment that instead of doing their scheduled rendezvous burn, they mess it up. Or sleep through it entirely. Well, now they’re on an eccentric orbit to nowhere, neither meeting up with their target nor their origin, potentially ever again. To get a new intercept, that eccentric orbit needs to be modified. Right now, the game simply fakes out of this problem, which is no big deal since it fakes its entire orbital mechanics. The player just magically gets a new rendezvous burn, because no positions are tracked in the first place.

But now that they are being tracked, that kind of magic no longer works. You’re just not in the right place at the right time, and you need to do something so in the future, you will be. And that’s where the whole complexity of calculating intercepts from a circular orbit exploded into my face rather unexpectedly. And I’m not even doing anything fancy. Just playing with the highest and lowest point in the orbit to alter its period so it intercepts the target again. While working with circular orbits, everything had an elegant, analytical solution (you don’t even need eccentric anomaly to calculate a hohmann transfer between circular orbits). But trying to get even a simple intercept from an eccentric orbit turns out to be messy and loaded with iteration and approximation. There’s no neat equation that can be solved by someone smarter than me so I can plug it into my code. I need to make the code do what a human would do, which is iterate, modify, increase precision, repeat the whole circus until a sufficiently precise solution is found or you loose patience. It’s not that complex algorithmically, but it’s tedious and slow-going, as has been almost everything else. And it’s not even integrated into the game yet at this point, this is just getting all the tools ready so I can integrate it.

So what’s the benefit going to be for the game?

That’s what irks me the most right now… I can’t really tell. Considering the whole thing is a considerable investment, that’s bad. A lot of things could be implemented in the same time where I can see definitive benefits for the game in its current state. But I decided to do this first, mostly because more predictable time costs are necessary going forward, but I might just have… faked them a bit more predictably. This way will be more immersive, certainly more realistic, and for someone like me it would be pretty much a must-have feature in a game like this. But right now I’m not even sure how exactly navigation is going to integrate into the gameplay.

Not bothering with automated trajectory calculation and instead implementing an interface that lets the player fiddle with the trajectory directly would have been easier by a fair margin (essentially, propagation would have been everything I’d have needed), and the integration into the game would be very much obvious. It would also be very tedious and get old really fast, obviously, taking up possibly half of the game time in total. And people would have to know orbital mechanics, and that’s an entry bar that seems too high for this kind of game. It’s alright for something like kerbal space program or children of a dead earth, where fiddling with trajectories is in fact a major point of the gameplay, and they tend to be different and interesting. But this is intended to be a small-business rpg where boring, repetitive tasks are very much part of the characters life, but shouldn’t slow down gameplay unless something interesting happens during those repetitive, mundane tasks. That’s the entire point of the resolution mechanic. If I ask players to plan very, very similar trajectories over and over again, I don’t think that’s going to go over well.

So I thought I could instead let the player define some inputs, then they do a skill check, and depending on the result they get a better or worse trajectory. Some inputs could give modifiers or bonuses, simulating that a trajectory with such properties would be easier or more difficult to calculate. Halfway through, I realized that there are several issues with this plan. For starters, the potential range of inputs is vast and confusing, and would require people to know orbital mechanics. I just said I don’t want that, so there was some rethinking required. I also didn’t like how it would again lead to a feeling of railroading. Though the player has some input, they’re still stuck with the one trajectory the skillcheck generated.

The version that’s hanging around in my head right now promises a bit more agency and information, but at a price. I think it might be good if I generate a menu of available trajectories, and the player is free to choose any of those options… except they have different prices. Not money, but some kind of point-buy system, where points are generated with a skill check. Characters with good wits would have it much easier to generate those points and could order their most preferred trajectory from the menu without too much sweat, while characters being weak on that front might have to invest more dice, possibly suffer some stress, or be content with a less optimal flightplan.

While this way of doing things is somewhat meta (the player gets a lot of information the character doesn’t actually have), I feel like it would be the best mix of character-skill driven gameplay and player agency. It sounds nice, at least on paper. How it’ll turn out in reality, I’ll need to see. The problem is that most trajectories on that menu will be very similar to each other in terms of complexity. In other words, the one that requires the least DV wouldn’t really be any harder to calculate than one that requires more DV, making the whole thing even more meta. The point prices for the trajectories would obviously need to depend on actual mechanical impact, not on real-life complexity, to really make sense in the game, yet the way the points are generated would suggest that those trajectories would somehow be more difficult to obtain. This rubs me a bit the wrong way, considering the major point of this whole undertaking is to give the game a better feeling of realism. If you’re reading this, and you understand what I’m talking about, and think you might have a better solution to the problem, I’m all ears. Comment away!

There’s also the fact that I’ll have to generate a whole bunch of trajectories upfront. Remember how I said above that some of these can be quite heavy on iteration? Yeah, that’s going to be a bit annoying. I’m not sure how it will fit into the flow of the game if you have to wait a couple seconds before having all your information on display when selecting a target. There’ll be potential optimisations later on to make this all use up less juice, certainly, but it’s another unknown to add to the growing pile. Considering the investment to get this feature on the road, it’s really too many unknowns. But I’m nearly far enough to actually start integrating in earnest, so I’m not going to pull back now. At worst, I will have wasted some time without adding anything significant to the game. That wouldn’t be great, but if it doesn’t happen too often, it won’t be a disaster.

I doubt I’ll make it there in january, though. The UI for this thing alone is going to set me back another two weeks at least. But late february feels possible. I’ll post another log in January to refine that estimation. Until then, I wish you a good launch into the new year!

Files

orbital-margins-linux-alpha.zip 326 MB
Version 0.10.0 62 days ago
orbital-margins-windows-alpha.zip 320 MB
Version 0.10.0 62 days ago

Get Orbital Margins

Leave a comment

Log in with itch.io to leave a comment.