---
title: "Odyis: lunar lander (1979) clone written in
Rust"
url: https://ad301.org
---
Link to the repository on Codeberg.org
Reading the blog post and looking at the game or its source code you may notice things. Things, only experienced developers might know. Since my goal with this game is to learn and improve my (so far non-existant) Rust skill, please share any feedback you have either on the repository in the form of issues, as a comment below or if you want to get into a conversation send me an E-Mail at [email protected].
Seeing as Rust seems to be become an increasingly favoured programming language by many programmers, I wanted to see what the hype is about! After writing a “Hello, world” I was intrigued, the compiler seems to be quite nice to work with and the writing experience smooth - and this language is supposed to be as well suited for embedded programming as C?
However, just writing “Hello, world” to the console obviously does not give much of an insight into how good a programming language feels to work in or gets the job done, so I had to create a marginally larger application to really dip my toes in.
That idea eventually became Odyis, a clone of the classic lunar lander game (which I admittedly have lot played myself) that serves as an intro to the language for me.
My original idea for Odyis was not a lunar lander clone but rather an idea about trying something in Rust I considered hard in C: drawing something to the screen. 1
This was just an experiment, but googling “draw triangle rust” quickly led me to this library: Macroquad.rs… and man, that lib is nice!
Getting something rendering is as easy as this:
That’s it? That’s it! It displays as this:
Image displaying what the above
minimal example would look like when rendered: A few primary
shapes on a red background
Granted, that does not look very good (seriously, green on red?) but it’s amazing how easy that was! This felt even simpler than it would in Python.
From there it was honestly pretty straight forward, I wanted to display the ship and learned about how structs are done in Rust:
That way we can store everything we need to. Gameplay actions like turning and burning (haha) are simply operations on these structs organized by area into files. For example ship.rs contains both the previous ship definition aswell as the code to burn and turn (haha, but the other way around):
I split the game into these parts:
| main.rs | Controls the game loop and calls all other components. |
| ship.rs | Defines Ship aswell as most functions to alter its state. |
| terrain.rs | Defines Platform aswell as the terrain generation (Vec<Vec2> where Vec2 is the custom Macroquad vector type). |
| gui.rs | Draws all graphical elements. |
| math_utils.rs | A bunch of usefull functions, i.e. generating points rotated around an origin for the graphics. |
| physics.rs | Handles collision detection. |
In most modern games the way to get a texture on the screen is to render a billboard rect with an image on it. I wanted to got more “hands on” for fun and rendered all of the graphics from code.
This meant having to create some helper functions to generate points of primitive shapes around the center of the ship. For example in math_utils.rs I created rotate_around() to rotate one point arount an origin for a certain angle.
In math_utils.rs:
This could then be used to draw a rotated polygon with 6 sides depending on the rotation of the player ship.
In gui.rs:
Comments
.png)
![Better Data Is All You Need [video]](https://www.youtube.com/img/desktop/supported_browsers/opera.png)
