Skip to content
This repository has been archived by the owner on Apr 30, 2022. It is now read-only.
/ doom-fire-interop Public archive

🔥 An implementation of the Doom Fire in Rust exported via FFI, with three apps (Web, iOS, Android) that use it

Notifications You must be signed in to change notification settings

evaporei/doom-fire-interop

Repository files navigation

doom-fire-interop

gif-of-doom-fire-on-browser

An implementation of the Doom Fire in Rust exported via FFI, with three apps (Web, iOS, Android) that use it. I actually did this project for a Rust LATAM talk.

This project is not intended to be the best way to create a Rust library that can compile to Android, iOS and WebAssembly.

It was created with the idea to share something that is not a hello world example of FFI that compiles to more than one platform.

It also contains a lot of the knowledge that me and Philipe Paixão (aka @piiih) acquired on building a project at Pagar.me (@pagarme) that uses the same technology and ideas, that unfortunally because of regulamentation issues, needs to be closed source.

Project Structure

doom-fire-interop
│
└───src
│   └─── all Rust code implementing the Doom Fire algorithm
│
└───DoomFireAndroid
│   └─── android app that consumes Rust library via FFI
│
└───DoomFireIOS
│   └─── ios app that consumes Rust library via FFI
│
└───DoomFireWeb
    └─── web app that consumes Rust library via WebAssembly

How it works?

The idea is that the Rust library has a PixelBoard struct that contains a Vec of bytes (u8). Each of those values represents the intensity of the fire for each of the pixels on the screen. Following this color pallette:

color-pallete-image

Then for each iteration of an infinity loop, an algorithm traverses all pixels and calculates their fire intensity based of: the pixel below, a "wind", and a random number.

Example of usage

The code below is the implementation needed to actually run the Rust code (actually WebAssembly that was compiled from Rust) on JavaScript and render it on screen.

import * as doom from 'doom'

function start() {
  const pixelBoard = doom.create_board(60, 40)

  doom.create_fire_source(pixelBoard) // sets the first line of pixels to 36

  setInterval(() => doom.calculate_fire_propagation(pixelBoard, renderFire), 50)
}

function renderFire(pixelsArray) {
  // pixelsArray = [35, 36, 22, 26, ...]
  // ... do rendering on screen
}

start()

Where this idea came from?

There is a whole book about tricks that the Developers of the Doom game engine did, and there is an article, by the same author, just about the menu's fire:

http://fabiensanglard.net/doom_fire_psx/

Also, @filipedeschamps did a whole video about this, trying to simplify the algorithm:

https://www.youtube.com/watch?v=HCjDjsHPOco

The video is in portuguese, but it has subtitles 🙂

He also has a repository containing a LOT of implementations of this algorithm. Some of them actually made this project possible.

https://github.com/filipedeschamps/doom-fire-algorithm

How to compile and run it?

Android

Well, it isn't actually that simple, I recommend on reading this article by Mozilla that explains how it works to compile a Rust library and use it on an Android app: https://mozilla.github.io/firefox-browser-architecture/experiments/2017-09-21-rust-on-android.html.

iOS

Same as Android, it requires a lot of configuration, here is a tutorial by Mozilla: https://mozilla.github.io/firefox-browser-architecture/experiments/2017-09-06-rust-on-ios.html.

Web

This one is actually simpler 😁

  1. Install these tools: https://rustwasm.github.io/book/game-of-life/setup.html;
  2. Clone this project;
  3. Change directory to its folder (aka cd doom-fire-interop);
  4. Run wasm-pack build;
  5. Change to the new pkg folder created by wasm-pack (cd pkg);
  6. Run npm link;
  7. Change to the DoomFireWeb folder (cd ../DoomFireWeb);
  8. Run npm install;
  9. Run npm link doom;
  10. Run npm start;

Then you should be able to see this at this URL: http://localhost:8080:

browser-doom-fire-print

Thanks

marcela-ziliotto-photo

Marcela Ziliotto for lending her 2011's Macbook so that I could create the iOS app. 💻 🍎

philipe-paixao-photo

Philipe Paixão for working with me on the Pagar.me project that lead to all the knowledge I know about WebAssembly and FFI. 👨‍💻 👨‍💻

deivis-photo rodrigo-melo-photo mateus-moog-photo leonam-pereira-photo allan-jorge-photo pagarme-logo

Deivis Windgert, Rodrigo Melo, Mateus Moog, Leonam Pereira, Allan Jorge and Pagar.me for letting me practice my Rust LATAM presentation to them and giving me feedback. 💬

kassiano-photo murilo-da-paixao-photo mateus-moog-photo

Kassiano, Murilo da Paixão and Filipe Deschamps for putting your implementation open source so that I could actually know how to render pixels on screen. 🌐 🎮

More people contributed to this, like my family and girlfriend, and other people at Pagar.me. Thank you all!! ❤️

About

🔥 An implementation of the Doom Fire in Rust exported via FFI, with three apps (Web, iOS, Android) that use it

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published