0%
Still working...

Hello! And welcome to the first advance of the journey to develop a game engine in RUST from scratch. You may follow up summaries of the iterations here.

As I said in the introduction to this project, this is by far my most motivating and exciting project ever! Just a few weeks ago I had absolutely no idea on how a game engine works. Still today my knowledge is very limited, however the fun part is always the journey. Finding out what is needed to do this engine, how to do it and how the language works is the best part of this challenge.

Regarding what I’ve learn so far I can only say that the more I find out about the development done by id Software the more I respect and feel amazed by the work they did, but I will get to that real soon.

What is been done so far?

The first two topics in my toolbox were for entirely for knowledge gathering:

Rust and game engine reading afternoons

I know many people would argue something like “Why don’t you just learn by doing?”. I agree on that one, I think the best way to learn something new is by doing. I could read the context in Rustenstein3D from the people of NextRoll which gives an awesome explanation of how to do it with useful links and then jump into the code with the support of the RUST official documentation and google. Then iterate over it to enhance the engine.

I really thought very much about doing this, however, I decided to turn to a diver deep approach. I will indeed learn rust by doing as can be seen in my sandbox, which makes the first (documented) iteration of this project:

Here I learn by doing what I find in the documentation and tackling some coding challenges. It’s all unit tested and with a maybe awkward naming and nesting (I want to fix that as well, but is not really important, just odd)

For the second part of this advance let me summarize a bit of what I found of this awesome book, Game Engine Black Book Wolfenstein 3D from Fabien Sanglard.

Coding like it’s 1991

“Programming is not a zero-sum game”

John Carmack

(I really loved this phrase in chapter one!)

Back in 1991 the people from idSoftware re-purposed a tool built for office work into a gaming platform with a of limitations. Computer manufacturers hadn’t embraced gaming, so the id Software crew had to put a lot of resilience and cleverness to overcome what many could just drop and consider impossible.

These are the most important limitations they had.

Impossible Video:

  • Inability to double buffer: This created tears and wouldn’t allow to have smooth animations.
Tears or tearing
  • There were video adapters, the better at the time was VGA, but it was really hard to program and not intuitive at all
  • VGA had 2 major architectures (12h and 13h), one offered lower resolution, the other higher but was more expensive and looked terrible.
  • Slow bus and the VRAM was a bottleneck (impossible to have 70 frames/second)

Bearable Memory:

  • RAM addressing was very complex and highly prone to errors
  • Ram was very good, even up to 4MiB. However MS-DOS retrocompatibility ensured that it worked like in good ol’ 1976, they could only use 1MiB of RAM without fragmentation
  • There was a hack, Real Mode, to have 20-bit memory addresses but depended on a segmentation that lead to too many issues
  • You could expand you memory but it wasn’t an standard process and was complex as for the average user to make at home

Impossible CPU

“I love coding MS-DOS with intel 386”

No one ever
  • 3D graphics require float arithmetic, however it was so expensive and slow that even when they rendered pretty good images the game play speed would be totally unappealing to anyone.
  • A “hack” was to multiply and divide by powers of ten to use the fast integer arithmetic but these conversions are way too expensive and the result was either ugly or slow. Dang!

Very poor audio:

  • PCs speakers could only beep, additional sound cards were required to have decent sound effects
  • They had a fragmented audio ecosystem (different external cards with different capabilities and expectations)

Ok Inputs and Outputs:

  • All ports where all programmed different (You should appreciate to have USB and not worry about how to code for it)

Even with all of this, one of their first projects was to make a copy of Super Mario 3 for PC which they took to Nintendo who said “Great job! Now please close the door when you get out”. However even with this turn down the team got actually motivated since they proved themselves very capable of creating amazing games! Which they proved in games like Commander Keen, Dangerous Dave in the Haunted Mansion, Rescue Rover, Shadow Knights, Hovertank3D, catacomb 3D, Wolfestein3D, Doom, Quake, etc. Also they did all of these, surprisingly, without a version control system.

Who were they?

  • John Carmack (I must confess I’m a fan of Carmack) → Wrote the runtime code.
  • John Romero → Wrote the tools for the engines (IGRAB-ED, TED5, MUSE, etc.)
  • Tom Hall → Creative director, he made draws that would come to life in Adrian’s art
  • Adrian Carmack → Artists, had to do all the graphics with a VGA palette (No RGB option) choosing a table of 256 colors before even beginning to draw and using a mouse to draw in a 320×200 resolution (also Tom would accidentally kick the shared table every once in a while)
id Software crew

There’s so much more I’d like to add here about the early days of id Software and the conditions they had, but I’d better stop here and continue with the third part of this advance.

Architecture skeleton:

I have the very abstract picture of a game engine as a system that is heavily dependent on math (mainly linear algebra), physics, renders, music and the engine itself, hence I decided to add a very basic project with a library to host the math, physics, and renders modules.

├── Cargo.lock
├── Cargo.toml
├── .gitignore
├── README.md
├── src
│   ├── bin
│   │   └── engine.rs
│   └── lib
│       ├── lib.rs
│       ├── math
│       │   └── mod.rs
│       ├── physics
│       │   └── mod.rs
│       └── renderers
│           └── mod.rs
└── test
    └── lib.rs

Inside each module there is unit testing according to RUSTs standards to have the UT in the same file as the source code.

Also I added a test folder next to source to handle integration testings. So far this is a very humble first step, but I hope to make it possible for it to look every time more like an engine would do.

Regarding the next steps I’ll continue the very same 3 action items as this iteration

  • Keep getting rusty: Learn Rust
  • More context on how Wolfestein3D worked: Game Engine Black Book: Wolfenstein 3D
  • Try to begin to implement some more code, probably math and render module lib functions while at the same time gathering some requirements to prioritize and make better iterations on a more solid roadmap.

Thank you for reading!

Recommended Posts