Settings

Theme

Show HN: I've re-implemented the Doom fire effect in plain JavaScript

github.com

108 points by filipedeschamps 7 years ago · 23 comments

Reader

fabiensanglard 7 years ago

The original reverse-engineering done by Samuel Villarreal was already using javascript. I assume by "plain" you mean you removed easeljs library for canvas management and added buttons?

  • filipedeschampsOP 7 years ago

    Yes Fabien! Also thanks for your article, it really inspired me to code my own version. Had a great time! I'm planning to make a video about all this and I will tweet you when it's published.

ricardobeat 7 years ago

Maybe it wasn't clear in the original article [1], but what you see inline are javascript implementations of the effect - there is a link to the source code at the end:

https://codepen.io/svkaiser/pen/xXmOvY

[1] http://fabiensanglard.net/doom_fire_psx/

  • isharamet 7 years ago
  • eterm 7 years ago

    The blog post is sadly not easy to follow along to try to do an implementation due to what appear to be minor description mistakes or poor writing which confuses.

    It switches from saying that 0 in the map represents white, to saying it is black, and then in the loop it states that the first row isn't changed but the loop pseudo-code skips over the first row only to then overwrite that first row in the code:

    > firePixels[src - FIRE_WIDTH] = firePixels[src] - 1;

    The comment, "Notice that line 0 is not updated" doesn't make clear it's not talking about the start of the buffer: It clearly changes index 0. In fact if line 0 is the 'generator' row it is in fact the last line in the buffer and the description of why it doesn't change is wrong: It's not unchanged because the loop starts at 1, it's unchanged because the loop is modifying 'src-FIRE_WIDTH'.

    Maybe some of the description or pseudo-code described are describing two different implementations one of which maybe is working with a reversed buffer.

    The principle however is clear, and it is interesting to see in the browser, although I'm sticking to just loading it into a canvas directly with CanvasRenderingContext2D.putImageData which lets you directly write an image buffer (noting that it is RGBA so 4 bytes per drawn pixel).

    In fact the 'cleaned up' version linked at the bottom appears to do the same.

    • filipedeschampsOP 7 years ago

      I've addressed those semantic issues in the version I wrote. I also got very confused by the article explanation.

mrspeaker 7 years ago

I first learned to do this effect in 1999 thanks to the incredible Denthor/Asphexia tutorials. I looked forward to new releases of these that my friend would (somehow) get and give to me on a floppy disk.

Most of them were in Pascal, but the fire one was in asm (http://archive.gamedev.net/archive/reference/articles/articl...) - it was the first time that assembler really clicked for me!

  • myth_drannon 7 years ago

    Oh wow. Denthor's tutorials were very good. Brings lots of good memories. Too bad this culture was overrun by internet.

    • haasted 7 years ago

      I remember those! Incredibly accessible. Also remember writing Den(e?)thor as an insecure, new-to-the-internet 16-year old asking whether more tutorials were in production. Never received an answer, unfortunately.

      Wonder what he (?) is doing today.

  • perakojotgenije 7 years ago

    Oh yes, brings back memories. For us older folks who'd like to revisit those tutorials here's the archive: http://archive.gamedev.net/archive/reference/listed82.html?c...

  • j45 7 years ago

    I remember this tutorial's intro via ASM to help solve a challenge of making fire run the same on a 386 sx16 as a 486 dx2/66, a big jump at the time.

    Still a little humorous that optimizing fire is still a topic that gathers attention and optimization despite the increase in computing power.

z3t4 7 years ago

It's a bit slow. I suggest 1) Use existing table instead of creating a new table at each frame/interval. 2) Or use Canvas because DOM is so slow 3) requestAnimationFrame instead of setInterval

  • filipedeschampsOP 7 years ago

    Open Source community is awesome, someone already made a Pull Request about this: https://github.com/filipedeschamps/doom-fire-algorithm/pull/...

  • city41 7 years ago

    For canvas I’d be curious which would be faster: grabbing an ImageData and continually update then set or use fillRect.

    • z3t4 7 years ago

      You always get surprises when optimizing, for example IE11 and probably other browsers use DOM optimization with hardware acceleration, so keeping it as a table, and just changing the bgColor instead of creating a new table, might be fast, fast enough, or even faster then canvas. As for imageData vs fillRect I would go with fillRect first as it makes it easier to scale to the clients pixelRatio, eg you want to scale to 200% on a device that has a pixel ratio of 2 in order to make it look crisp. In my experience, manipulating single pixels are sometimes also slower! But if you really want to get advanced you could divide the screen up in different pieces and use many (off-screen) canvas's and/or web workers, but it would probably only work on Chrome, and then you would operate on the imageData buffer.

      • city41 7 years ago

        Yeah it’d probably require implementing all approaches and benchmarking in various browsers.

        For scaling I find using CSS works well instead of scaling the canvas. Most browsers support `image-rendering: pixelated` now. Of course no MS browser does.

        I’ve always been impressed with canvas. I recently wrote a little app that creates 1024 16x16 canvases and I’ve yet to find any browser (including mobile) break a sweat.

mmphosis 7 years ago

Apple ][ Fire Demo -- 64 Bytes http://deater.net/weave/vmwprod/apple2_fire/

21 7 years ago

But can you implement JavaScript in Doom?

berkut 7 years ago

Didn't MS VC++ 4 to 6 ship with an example which emulated this effect as well via a custom control?

There were different tabs for things like "wood", "gas", "cryptonite" which changed the overall colour of the effect.

Ayraa 7 years ago

It would be really cool if you could paste the url to an image, have a generator overlay the fire effect on top, and you can save that as a gif.

Keyboard Shortcuts

j
Next item
k
Previous item
o / Enter
Open selected item
?
Show this help
Esc
Close modal / clear selection