Game Engine Prototype

This is my solo project to build a prototype with custom engine for Rayark.

Challenges

Rust is a programming language focusing on thread safety, and therefore it prevents developers from violating data sharing rules to avoid data race conditions.

  • Rust does not allow sharing mutable state objects
    • Change states in a game world
    • Render sprites -> change OpenGL states and write to framebuffers
  • Define various types of resources
  • OpenGL ES is single threaded, and cannot be called by other threads
  • Build system should be easy to deploy

Resolutions

Mutable shared objects

Functional programming paradigm comes to rescue.

We can treat a mutable state object as a single value, and pass it through function calls instead of static variable. Thus, state transition functions are logically pure and easy to parallelize.

fn update(state: mut State) -> State {
  // update state
  // return modified state
  state // return the updated state
}
let stateA = ...;
// next frame
let stateB = update(stateA);

Resource Definition

Every resource has its own metadata that defines the way to load it.

Additionally, I designed three types to make resource loading easier and flexible:

  • FactoryBuilder: A builder object to register concrete resource types
  • Factory: A true factory object for searching and loading resources
  • Loader<T>: A loader class that defines the way to load the resources of a the type T
  • Handle<T>: A clone-able reference that allows users to share the resources of the type T

Plus, I made use of several open source libraries to speed up development and improve integration.

  • futures: primitives of async-await
  • serde: serialization interface

Rendering

The renderer is composed of 3 parts:

  • Resource Processor creates or destroys resources on demand (via queue)
  • Scene Renderer translates the scene representation into virtual commands
  • OpenGL Executor executes virtual commands in OpenGL thread

In other words, the renderer is a producer-consumer system that receives requests from other threads.

Build System

I built a docker image that runs Linux with Android SDK and custom Rust compiler to isolate the build environment from host computers.