Just want to play my game without reading this whole post? Play the game here – press a key, mouse button, or touch the screen to fire the thrusters, and try to land at less than 4 m/s with as much fuel left over as possible.
In 1969, when all the nerds were still excited by sending humans to the moon instead of flinging cars around the sun, the hottest video game was Rocket (or Lunar) for the PDP-8. Originally implemented in FOCAL by high school student Jim Storer and soon afterwards ported to BASIC (the other dominant language to come as standard with microcomputers), Rocket became the precursor to an entire genre of video games called “Lunar Lander games“.
The aim of these games was to land a spacecraft on the moon or similar body by controlling the thrust (and in some advanced versions, the rotation) of the engine. The spacecraft begins in freefall towards the surface and will accelerate under gravity: this can be counteracted with thrust, but engaging the engine burns through the player’s limited supply of fuel. Furthermore, using fuel lowers the total mass of the vessel (a large proportion of the mass of the Apollo landers was fuel for use in the descent stage) which reduces its inertia, giving the engine more “kick” which must be compensated for during the critical final stages. It sounds dry and maths-y, but I promise that graphical versions can usually be played entirely “by eye”.
Let’s fast-forward a little. In 1997 I enrolled to do my A-levels at what was then called Preston College, where my Computing tutor was a chap called Kevin Geldard: you can see him at 49 seconds into this hilariously low-fi video which I guess must have been originally shot on VHS despite being uploaded to YouTube in 2009. He’s an interesting chap in his own right whose contributions to my career in computing deserve their own blog post, but for the time being all you need to know is that he was the kind of geek who, like me, writes software “for fun” more often than not. Kevin owned a Psion 3 palmtop – part of a series of devices with which I also have a long history and interest – and he taught himself to program OPL by reimplementing a favourite game of his younger years on it: his take on the classic mid-70s-style graphical Lunar Lander.
My A-level computing class consisted of a competitive group of geeky lads, and we made sort-of a personal extracurricular challenge to ourselves of re-implementing Kevin’s take on Lunar Lander using Turbo Pascal, the primary language in which our class was taught. Many hours out-of-class were spent in the computer lab, tweaking and comparing our various implementations (with only ocassional breaks to play Spacy, CivNet, or my adaptation of LORD2): later, some of us would extend our competition by going on to re-re-implement in Delphi, Visual Basic, or Java, or by adding additional levels relating to orbital rendezvous or landing on other planetary bodies. I was quite proud of mine at the time: it was highly-playable, fun, and – at least on your first few goes – moderately challenging.
Always game to try old new things, and ocassionally finding time between the many things that I do to code, I decided to expand upon my recently-discovered interest in canvas coding to bring back my extracurricular Lunar Lander game of two decades ago in a modern format. My goals were:
- A one-button version of a classic “straight descent only” lunar lander game (unlike my 1997 version, which had 10 engine power levels, this remake has just “on” and “off”)
- An implementation based initially on real physics (although not necessarily graphically to scale)… and then adapted as necessary to give a fun/playability balance that feels good
- Adapts gracefully to any device, screen resolution, and orientation with graceful degredation/progressive enhancement
You can have a go at my game right here in your web browser! The aim is to reach the ground travelling at a velocity of no more than 4 m/s with the maximum amount of fuel left over: this, if anything, is your “score”. My record is 52% of fuel remaining, but honestly anything in the 40%+ range is very good. Touch the screen (if it’s a touchscreen) or press a mouse button or any key to engage your thrusters and slow your descent.
And of course it’s all open-source, so you’re more than welcome to take it, rip it apart, learn from it, or make something better out of it.
9 replies to Lunar Lander
What’s the optimum score? Getting 40% is easy but beating 48% was quite tricky. I managed 50% after many attempts.
As a shortcut, the two-body problem is solved by time-sampling rather than polynomially. Time-sampling is limited by processing speed on the computer running the simulation; typically to 60Hz but potentially less on lower-powered devices and especially if your browser de-prioritises the thread (e.g. if you switch tabs mid-descent for a bit). As a result, the simulation varies slightly from system to system, probably by enough in real-world cases to make a few % difference in optimal score. I could calculate the optimal score for ideal conditions (and I think it’d be close to 50%), but players on slower devices might be able to get a little higher with perfect play owing to the calculation shortcut.
An earlier version didn’t have this limitation, but performance was choppy on my mobile so I simplified the simulation.
tl;dr: it varies slightly by device.
I worked out the equations for landing and determined the optimal fuel to be 54%.
Some calculations (and a screenshot getting the perfect score!) at https://gist.github.com/sbliven/e5eacef1df5f64e820abf3c0be597c46
The trick is (spoiler -> base64)
I was a computer programming kid in HS so when my freshman year at college I went to an observatory and they had a moon lander simulation running I had build my own. Having no background in physics I guessed at the math. I think I did it in gwbasic or maybe pascal as well. At any rate had a decent version going in a couple days. Wish I still had it. All my computers and disks were stolen while they were in storage so I lost all my old code from that era. At any rate wanted to say nice game!
Thanks Dan – wanted to let you know that I used some of your code as inspiration for the LunarLanderBadge my son and I made for DEF CON 27. I’ll be putting my code up on github after August 2019. I used C++ with the Arduino IDE, running on a ESP32 — considerably more powerful than anything back when the original Lunar Lander game was created, You can see from the video on Kickstarter that my implementation is closer to the Atari game, but I found your code helpful in the early stages.
Dan Q mentioned this article on danq.me.
My record is 54%, 3522kg at -4m/s, after less than 8 attempts, without any math calculations… What really helps, is just put your mouse cursor at your last starting point of the burn. Then lower the mouse a bit each time for the next try. That last one with -4m/s was a bit of lucky of course, but this method really helps to find the optimal deceleration burn starting point.
Final improved record, still 54% but slightly more fuel left, 3524 kg.
60%. I could probably eke out another % but I already took about 20 tries to get this one and it’s gonna be harder to get that last %