Can WordPress run Doom? (of course it can, here’s how)

tl:dr; Can WordPress Run Doom? Yes. Skip to the button if you want to play. Though please subscribe to my newsletter else I’ll set a cacodemon on you. For the rest of you who want to read how I did it please continue below.

A picture of a WordPress Cacodemon and a Wapuu, in pin badge form

I’m very much a child of the 90’s, and none more so than in the world of video games. In fact, within arms reach of me as I write this an abundance of PC, Playstation and Megadrive games (along with late stage C64 games) are all accessible in their original hardware. Nestled towards the end of the second shelf down of PC and Playstation games is one of them is one of my favourite games ever – Doom.

Doom is one of the two games that manage to find itself on any system I ever own. The game needs no introduction – it’s a first person shooter that sees you play spare marine on a mission to Mars, tasked with blowing up a bunch of monsters spawned from hell using all manner of weapons. From shotguns and pistols to chainsaws and plasma rifles – all to a rocking soundtrack. At the time of release it was seen as bloody, violent and gory. Now, although it still is rocks an ESRB rating of “Mature”, I think it’s tame, relaxing fun. A perfect brain dead game to switch off to as I finish development for the day.

The origin and growth of the “can it run Doom?” meme

As I’ve gotten older I’ve come to learn the story behind Doom which has grown my love of the game even more. There are two beautiful things about it. First off is that it shouldn’t have been able to run on the hardware at the time. It does a lot of neat programming tricks that squeezes out every clock of processing power out of mid 90’s desktop PCs. It’s not something that I really understand myself but if you’re interested in taking a deep dive into it, then I’d recommend the Game Engine Black Book coverage of it. Be warned: it’s technical! I struggle to understand it and I’ve been calling myself a computer programmer since the mid 2000’s.

Secondly, the code for Doom is open source. The Linux code that uses to run Doom is available on Github to be played with and ported. You still need some data (known as WAD files) for it to work, but it’s there. If you legally own that part, then you should be able to compile and run it yourself.

Both these two things lead to the meme “it runs Doom”. Intrepid programmers have taken the source code and ported it to a number of devices. From a home pregnancy kit, to a card payment terminal to gut bacteria. It may not always be playable, but it fascinates me and a browse of the itRunsDoom subreddit has shown that you can run it on things you really, really shouldn’t.

This got me thinking. Can we run Doom on WordPress? It feels like we can, surely?

Getting Doom to work in a Web Browser

I feel like there’s a couple of steps to get Doom working in WordPress, and the first is to get Doom working in a web browser. Thankfully this is quite common – hell the Internet Archive has some DOS games already working – so digging there seemed like a great place to start. I quickly found JS-DOS, which is a simple JavaScript DOS emulator. Creating a WordPress plugin to run it is quite straightforward. You take a piece of software – in our case, the shareware version of Doom (the first episode that is free to distribute as part of the Shareware model) – create a Game Studio bundle, and include that, along with the JavaScript, and a simple WordPress shortcode so I could create the div that would eventually run JS-DOS.

Sure enough, after less than an hour work on a Friday evening, I got WP Doom built and working locally.

Loading the custom plugin into WordPress Playground

Now, it’s ready enough to use on WordPress now, however I feel like it’s one of those plugins that you probably need to see working. I could easily tell people to install it, or give people a URL of a default WordPress installation with it running – but the former requires users doing work, and the latter requires me doing work, which for a weekend side project would be too much.

Instead I looked at WordPress Playground.

I talked about WordPress Playground before in my roundup of WordCamp Europe 2023, but the general jist of it is that it’s a WordPress instance that runs in the browser that you can use to test run WordPress quickly and easily. It had a bit of a rough start – all plugins were opt out testing rather than opt in meaning a lot of developers had broken versions of their plugins running on WordPress – but I think it’s a fascinating project and I given it a brief go in testing my WordPress plugins and to test WordPress plugins. I’ve become a fan.

It feels like a perfect use case for WP Doom.

Loading a Plugin from Github

The first thing was to load and activate the plugin. Unfortunately, I’m not sure that JS-DOS is GPL compatible and Doom’s Shareware release certainly isn’t, so I doubt WP Doom would ever be approved to the WordPress Plugin Repository. Thankfully, you can build a “blueprint”. Blueprints are JSON files that will set up your Playground Instance however you wish. Blueprints have split into “steps”, which is a list of tasks that are carried out when WordPress’s playground is installed and created.

One such step is “InstallPlugin” that installs a plugin. Giving a resource of a URL means that it doesn’t point at the WordPress plugin repository and instead loads from a ZIP file, which I’ve hosted on Github.

{
      "step": "installPlugin",
      "pluginZipFile": {
        "resource": "url",
        "url": "https://github.com/rhyswynne/WP-Doom-Playground/blob/master/wpdoom.zip"
      }
}

This lead to the first problem, after trying to run this I got a CORS error, meaning that WordPress couldn’t access the file on Github. Thankfully they give a really helpful error report that was easy enough to fix.

Changing the URL to the Raw Github URL – https://raw.githubusercontent.com/rhyswynne/WP-Doom-Playground/blob/master/wpdoom.zip – as described above, means there isn’t a CORS policy on that URL meaning WordPress can download the file. After testing this, WordPress has WP Doom installed and working.

WP Doom installed and activated in WordPress Playground

Creating a Page in WordPress Playground to host WP Doom

The plugin is now installed, however you still need to create a page to run Doom. We can manually create one or alternatively generate one. Thankfully this is quite straightforward. From a local WordPress installation I created a page with the shortcode on it (I also put it into a Cover block so it has a nice background and stretches across the page) and then exported it. This is using default WordPress Import/Exporter (located at Tools > Export). This exports an XML file which I uploaded to Github. WordPress Playground has within the BluePrint API the ImportWxr step, which will allow you to import a WordPress XML (don’t worry about the file not having an .wxr extension, it allows a .xml to be imported fine).

    {
      "step": "importWxr",
      "file": {
        "resource": "url",
        "url": "https://raw.githubusercontent.com/rhyswynne/WP-Doom-Playground/master/wpdoom.xml"
      }
    },

This creates a page within WordPress Blueprint with the shortcode and the cover on it.

Loading the blueprint & setting a default page

So the next step was to make sure the first thing people who load the playground instance see Doom. There was two ways you could achieve this:-

  1. Set the page created in step 1 as the home page.
  2. Point the instance to the page in question.

I decided on the latter (for reasons I’ll share later). This can be achieved using the landingPage option, or adding a url parameter to a query string. One slight problem I encountered was that – by default – the permalink was the page ID. For future-proofing there’s no guarantee that the page ID (which was consistently creating as 353) would remain, so I thought of implementing “pretty permalinks”, so it’s a consistent wp-doom.

I could have played around with the options, however I decided to use the WPCLIStep and a WordPress CLI command for setting permalinks.

{
      "step": "wp-cli",
      "command": "wp rewrite structure '/%postname%/'"
}

Playing around with the Blueprint editor I did generate an error:-

I’m not entirely sure why the error was generated, as running it it worked as intended!

Edit: 8th May 2024

Although it works, I was having issues when creating the blueprint, as I got this error (click to expand).

With that said, it still ran and worked as intended, however it was ugly to show it off in this post, so I replaced it with the default permalink for now.

Adding in an anchor to the cover, I then made sure to set the landingPage variable, which is set outside of the steps above.

"landingPage": "/wp-doom/#hurt-me-plenty"

A quick upload and a refresh, and loading the blueprint within the query string, and we were good to go! For reference you can see the entire Blueprint file here.

Putting it All Together

So, all we need to do now is load the Playground instance with the required query string and then Doom should run. I could embed it into an iframe but I thought it’s better to give you a direct link, which you can load by clicking the button below.

Click “Skip loading saves” and the big play button, and Doom should run in WordPress.

I’d recommend playing it on a desktop computer with a mouse, as the controls are not ideal. Here’s the controls:-

Directional KeysMove Forwards/Backwards & Turn Left/Right
EnterAction Menu Item
Mouse ClickFire Weapon
SpaceInteract with environment (open doors/press switches)
Number KeysChange weapons
< & >Strafe Left/Right

Ways I’d like to Improve WP Doom

As this is a bit of a side project, I’m not sure how much I’ll be improving it. However here’s a few things I’d love to do at some point.

  • Run it on WebAssembly – I feel it’s a bit of a cheat. It’s not WordPress running Doom, but rather DOS emulation running in JavaScript. WordPress is indeed very much on the side. There are ways to execute code in WordPress Playground, and you can run WASM-Doom which is Doom in WebAssembly. I’m sure it’s possible.
  • Turn it into a Gutenberg block – I’m running everything from a shortcode as it was quicker and easier for me to build. Eventually I’d love to turn it into a block.
  • Sound – you will notice that there is no sound. This I believe is due to not being able to set it up before loading Doom. Those of us of a certain vintage would know you’d have to setup Doom with a soundcard before playing the game. We have skipped this step in the creation of the JS-DOS bundle. Fairly sure we can work around it, again maybe running it as WASM-Doom would fix this.
  • Controls are a bit all over the place – The controls are really bad. I wish there was a way to configure it. Again, maybe something for WASM-Doom.
  • Still too many steps for my liking – you have to skip the loading files, and click play, to make sure it works. It’d be nice to skip these steps, maybe WASM-Doom would fix it?

I’m happy with how this experiment has turned out and happy to assist others in running it. It was just something fun to do over a weekend for me, and to play around with WordPress Playground. I’d love somebody to do a speedrun of this version of Doom.

Conclusion and next steps

Should you wish to dive into the code itself I’ve created two Github repositories. WPDoom is for the plugin “WP Doom” and the WP Doom Playground is for everything that gets pulled into the WP Doom Playground above. Feel free to have a tinker, as I will be accepting pull requests.

I would like to pre-emptively apologise should you not get any work done today, as you slay the demons of hell. Sorry about that.

Subscribe to my WordPress newsletter

If you’ve enjoyed this post, then I run semi-regular-ish newsletter for this site, so you can keep abreast of posts. I’d love you to subscribe. You can do so below.

Please wait

Thank you for signing up! You should have received an email to confirm your subscription. Please click on that and you'll be all set!

You’re free to unsubscribe at any time.

Links marked with [aff] are affiliate links

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.