## Passing like ships in the night

My Lambert Solver will plot a course that will intercept any target body. However, really it is only aware of your start, end and centre of attraction. If your course involves departing from an orbit around Luna heading for Titan then Lambert gives you a Sol relative velocity to match and doesn’t care about the effects of gravity from Luna, Earth or the fact that your course might well take you on a collision course with either.

They are problems that can be solved, or at least accounted for. But a more insipid issue is also at play. The Lambert Solution doesn’t care if you pass within the gravitational influence of anything along the way. It knows nothing of the various planets or moons whose orbits you cross along the way to your destination. So once Lambert suggests a course, we need to see if it brings us too close to some other bodies. We need to predict encounters, that is, determine the time that a point (ship) moving on a conic path is a set distance from another point (planet/moon) on a separate conic.

Guess what turns out to be really hard?

I was able to find research papers on determining the closest approach between two objects, but they were beyond my understanding, referencing topics in maths way passed what I know, and even then you would have the theoretical closest point, no information as to if they actually are ever near each other at the same time. Now knowing the minimum distance would have use, but I couldn’t fathom it.

Then, around Christmas I downloaded and tried a game I’d heard about since early in it’s development, I’ve followed it’s progress ever since the main guy behind it was looking for information on the Orbiter forums about ways to present orbital mechanics simply in a game around the same time I was using them for research. The game is Kerbal Space Program, a 3D rocketry sim about designing rockets and trying to get them to space. Once I got over the malaise of seeing how much he had accomplished over the same time that I’ve been floundering (mainly as it’s his job and works with a team and I scrape together time usually when I’m already too tired to juggle rocket science) I saw that he was predicting encounters.

His spacecraft would project their path and he would detect where/when it was going to touch the sphere of influence of a body and use that to calculate a series of Patched Conics. So, I went back to the orbiter forums and asked him, and he explained at a high level. As I’m using 2D some further options are available to me than to the 3D scenario he has, but the idea will be basically the same. Use orbit size tests as a first pass rule out, then find the closest pass point, then test for an encounter, then search backwards in time from there for the actual encounter point.

That search through time is potentially expensive and so I wanted to rule out potential candidates and narrow the ranges to search for the remaining ones. As my orbits are always co-planar I believe there is a chance that an encounter could occur after the closest point, as the orbit on the ‘inside track’ could catch up with the other as they were growing further apart, as such, I determine the segments of the ships orbit that are within the threshold of being able to encounter the body, i.e. between the bodies (periapsis – sphere of influence) and (apoapsis + sphere of influence.

I would like to know when it is actually in the accurate path of the body’s sphere of influence, but that is much more complicated and hopefully this isn’t so overzealous as to be an issue. This gives me the time and zone that an encounter could occur for the ship. I then determine where the body could be to have an encounter and where it will be when the ship could have an encounter. Getting the overlap of where the body will be and where it would need to be narrows the range, or rules out an encounter if it won’t be in the zone at the right time. Then using the times that the body will be in this narrowed range, if it exists, I determine where the ship will be while the body is in the target area. If these last two ranges are too far apart it rules out another candidate. Otherwise I have a narrowed range of time to test if an encounter exists and then to find the point when it first occurs.

Next is actually finding the point of encounter itself, if it exists…

## You have to make your own mistakes

No amount of reading about how the entity-component model is the design architecture of modern games convinced me I should be using it myself. It’s useful for having a wide variety of different types of game entity without having a wide variety of classes with elaborate inheritance or repetition, but I only planned three real types of entity, ship, planet and station with a fairly reasonable inheritance. I also never really understood how separating various functionalities that often had strong linking and dependency on each other would work. I wasn’t sure how they’d communicate with each other without breaking the idea of sperate independent components.

This was all, of course, until the scope of things grew and communication between different aspects became difficult. Though the real driving force came from the fact that I was adding debug graphics while implementing a new feature and managing that new line was becoming a core. I wanted to be able to add some simple object and have it maintain itself. Some sort of self contained functionality component, if you will.

This developed and now I have a ‘ComponentContainer has Components’ relationship between GameScreens and Managers and between Entities and Components. The Game has a ServiceLibrary which first has global level things added to it. It’s then passed to each GameScreen which adds services specific to that screen. One of those is the EntityManager which loads all the entities passing the ServiceLibrary to each so that different Components can add themselves. Basically each layer inherits from the previous and adds services specific to it locally.

Of course that took time refactoring to basically recreate the same outward functionality as before, but it should hopefully be easier now when I go back to the functionality I was working on that spurred the need.

Added benefit was that I can now have interesting control on what functionally things have. The Sun doesn’t need to have an orbit functionality or most of the other components, asteroids don’t need to have a sphere of influence, even if their mass might suggest they would. And that would all be configurable through XML at run time rather than hard coded types of entity.