Render Quake 3 Arena maps with Elm and WebGL!

Hi folks, I would like to show you a pet project I’ve been working on during the past weeks. It’s a Quake 3 Arena map renderer, written entirely in Elm and WebGL. I’ve made it mainly to become more acquainted with WebGL, since my experience with it was confined to simple 2D games.

I’ve put a demo online.

I won’t describe in depth the project here, since if you are curious the README on the Github repo gives you a technical overview about how it works.


Perfomance is quite good: I’ve tested the demo with Safari, Firefox and Chrome browsers on my late 2014 Mac mini. Safari always runs at 60 FPS without issues, while Chrome seems to suffer the most from garbage collection, which makes to drop a few FPS here and there–or at least this is my superficial explanation. :slight_smile:

Elm and WebGL

The WebGL part of the project was quite smooth. It’s really a nice API to work with. However, I have a couple of use-cases I would like to be addressed:

  1. The ability to create a texture using raw bytes, maybe exactly Bytes values.
  2. The ability to write the output of a fragment shader into a texture.

I know 2) is somewhat planned. 1) would help this project because Quake 3 light maps are bundled into BSP files and it isn’t straightforward to use them as URL, as requested by current Elm WebGL API.


Collision detection is the next big thing I want to implement. Other than that there are a number a visual effects that needs to be added in order to be faithful to the original game. I’ve listed them on the repo README.



Twenty years ago I spent a lot of hours playing these maps and it looks like I will again.


Very cool! Can’t wait to see more :sunny:

Wow. This is really cool. Well done!

Looks beautiful, TY for sharing !

No strafe jump is a joy killer. Should we reintroduce the bug? :smiley:

1 Like

Was that a bug? It’s all so long ago now.

Oh yes, falling down, and rotating view, kept some acceleration after the fall.

1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.