Nerdsniped into building a gaming rig

I haven't gamed since the Half-Life 2 era but every now and again I get the urge to play a computer game. This is frustrated by not having a computer with a meaningful GPU, which almost everything needs. 

Even before the recent LLM driven inflation I just couldn't justify the quite expensive exercise that building a gaming PC had become. Nonetheless I "banked" lots of games made free on the Epic Games Store thinking I might one day play them.

I think that time has come. This is because a friend at the Hackspace bought a BC-250.

Designed to work as a crypto miner with multiple boards in a large server chassis it's a single board computer built around a variant/cut-down version of the AMD APU in the Sony PS5. When the bottom fell out of the market for these because mining moved on then they ended up on AliExpress at a huge markdown. At one point they were available for a pittance, maybe £50 but as of now you can get them for £120-130 if you pick your moment. The 'sales' are frequent and the price spikes up and down.

What you get for this is...

  • CPU: 6x AMD Zen 2 cores @ ~3.5GHz
  • GPU: 24 RDNA2 Compute Units (1536 shaders)
  • Memory: 16GB GDDR6 shared memory
  • TDP: 220W (50W idle - 235W max load)
  • OS Support: Linux only (no Windows GPU drivers)
Nothing stellar but when a gaming PC or laptop can easily be £1.5k this is very tempting. You won't be playing brand new AAAA games in 4K, but you can play recent games for example Cyberpunk 2077 in 1080p.

The other thing that's moved the needle is the arrival of gaming on Linux as a thing people just do. Driven by Valve's work on the Steam Deck many many modern games just work, sometimes better than they do under Windows.

There are several Linux distros taking advantage of this Linux gaming surge, notably Bazzite which pretty much turns any generic machine into a Steam Deck. Bazzite supports the BC-250 well. With the addition of "Heroic game launcher" you can play Epic Games Store items as well as things from Steam. So that library of free games I've wanted to play is back on the table.

There are some inconveniences.

Obviously you've got to add an SSD but I was lucky enough to have a small one kicking around.

Also you need a PSU. An ATX one will do but you don't need most of the connectors. I've bought a small server PSU and plan to make a custom power lead although most people use small Flex-ATX ones. I had an old ATX PSU that will power it but it's too bulky for a tidy case build.

Most tiresome is the need to 'peel' the heatsink so you can fit a conventional cooling fan to replace the high pressure airflow that would have been in the server chassis. That's a fiddly job I spent an afternoon doing.

As it's very much a unique form factor you can't just buy a case, but there's a whole community of people designing cases mostly 3D printed. I intend to make a wooden case from scratch.

So far I've got Bazzite on, set it up on a table in a spaghetti wired fashion and proved to myself I can play some games.

More on this when I get to building the case. I suspect the first game I'll play is Half-Life 2 as it's a 'comfort blanket' and a true landmark in design. I need to ease back in slowly.

Why is this related to my various prop building shenanigans? It's not really, but also the BC-250 runs off just 12V not the full set of ATX PSU voltages. Which might make running a moderately powerful Linux machine with a GPU in a field off a lead acid battery a thing. I've not used an LLM as an interactive NPC-like object in a LARP but it has been done and this might get me the hardware to do it without relying on cloud services.

There's a lot of negativity about LLMs in LARP, especially around the replacement of artists and writers and I'd never do that but a set of offscreen low-importance NPCs in our sci-fi LARPs that people can interact with would be interesting. We implemented MU|TH|UR with a Telegram chat but keeping up with it kept one of the GMs very busy.

MU|TH|UR v1.5 - PTT and two Telegram bots

Back when we ran High Frontier: The Drake Objective in 2024 I used a Raspberry Pi to turn Telegram messages into the "sad computer voice" prevalent in sci-fi movies.

This was a surprise hit in the game but there were a few problems...

  • One of our players is very hard of hearing - so unable to engage with much pure audio content
  • It's really easy to miss random out of the blue messages from a walkie-talkie unless you're actively engaging with it in the moment. Doubly so if somebody is talking to you in person at the time. We were asked to repeat messages all the time.
  • It used voice activation on the walkie-talkie doing the transmitting which wasn't totally reliable and it would occasionally clip the start of messages despite making a "beep" before talking
All of these were related to me just bashing it together in the fortnight before the event while also working on other stuff.

For High Frontier: The Weyland Factor we wanted to fix these and perhaps also have it transcribing incoming messages from the walkie-talkies for MU|TH|UR v2.0.

I started on the update then quickly decided to drop the transcription and constrain the project to just fixing the acknowledged problems before doing something that could suck a load of time and effort. 

The frequency range of audio transmitted by PMR walkie-talkies is limited and it can be hard for a person paying attention to distinguish speech sometimes so I surmised automated transcription would do more poorly, even the cloud based 'AI' version of it.

My original version had a single Telegram bot that was part of a group chat with a simple command interface. The event GMs could chat in the group normally but anything prefixed with the command "/say" would be turned into speech and sent to the PMR. The bot was just one of Telegram's example bots and Microsoft's Azure speech to text example smushed together, but it worked well. With no WiFi on-site I relied on a 4G dongle I had kicking around that "just worked" in the Raspberry Pi.

Everything looks like a nail

As Telegram worked well for the GM group and I had a load of Android tablets with LTE modems from other events, the obvious way to give the players a text channel to interact with MU|TH|UR through was just another group chat in Telegram.

While I had physical carry cases for the tablets the interface couldn't be skinned to be "diegetic" with the time I had. They just had some Android Tablets and Telegram but this is not an immersion destroying thing and to do anything else would have been a big pile of work. A custom Android app or Progressive Web App is something that's in my wish list for the future but wasn't realistic for this event.

So with two chat groups that created a requirement for two bots if I wanted to "separate control messages from user messages" which is a good design pattern even though this isn't exactly a highly sensitive application.

Two bots, one script

All the main Telegram bot Python examples are for one bot, which is fair enough. I am not a Python programmer and quickly found that the 'blocking but async event driven' default way of writing bots with the common library is inimical to running two bots at once. Well not exactly but you then can't use the 'convenience' methods and have to engage with the Telegram API at a lower level. Several people have asked for a multiple bot example but the library maintainer's response was of the vaguely dismissive "read the docs/now draw the rest of the owl" variety. Likewise lots of other responses kicking around on a search have pseudocode partial examples that just didn't run even when I tried to fill in the blanks.

So, sledgehammer to crack a nut time and I quickly taught myself how to use the multiprocessing library in Python. Wasteful but it's only a Telegram bot talking to webhooks on a system with one job to do. The two bots talk to each other via a multiprocessor Queue: player messages are passed to the GM bot and GM messages intended for distribution are passed to the player bot. Not unexpectedly there seems to be a lot of subtlety about whether certain things are thread safe in Python when using the async.io method the Telegram library uses itself. I think using the multiprocessing library and its own inter-process communication method insulates me from that but like I say I'm no Python programmer, my usual playground is C++ and FreeRTOS.

While I was doing this I added a tiny bit more subtlety to the control. Messages prefixed "/say" would go to the player group chat as well as being broadcast as speech. Messages prefixed "/send" would just go to the group chat. This was a speculative feature but ended up being useful.

Push to talk

There's no standard for connecting things to PMR walkie talkies but they do share a kind of common pattern. I used the same circuit as I did for MU|TH|UR v1 to match impedance/levels and added in a relay that grounds the 'tip' connection when you want to transmit.

From this it was simply a case of triggering a GPIO pin before 'speaking' to latch the relay and then release it afterwards.

The end result meant triggering the PMR was now much more reliable and receiving PMRs received the messages more consistently.

When 3G is no longer enough

With not long to go I had it all working and plugged in the dongle to do a bit of a final test. Which then stubbornly refused to work. I spent far too long trying to troubleshoot this, cursing bitrot and version creep in Raspbian but when it occurred to me to try the dongle in my laptop it didn't work there either.

Despite being listed as "4G" in some specs that show up when you search it turns out the dongle I'd been using for ages was actually some variant of 3G that the big switchoff made non-functional. Well it did come from e-waste, which is where it'll go back to. I've got an otherwise usable phone with the same problem.

This prompted a quick panic order of a Waveshare SIM7600G-H dongle from PiHut. There's a certain clunkiness to it as it's intended for industrial/hobbyist use rather than consumers but that at least means no weird gimped branded up firmware and at least some technical information on their Wiki.

Getting it working was definitely not a consumer job, sending AT commands over a USB serial port and then having to reconfigure Network Manager in Raspbian to not set the DNS servers: another frustrating half day rabbithole but with it configured it connects quickly and reliably. The external antenna probably helps.

As it's also possible to use this via an onboard UART I may see if I can use this from embedded hardware like an ESP32 but that's a project for another time.

Sticking it in a box

The new dongle and external antenna meant there was no way the original enclosure where I repurposed an external mains socket box was going to work any more.

So I settled on using a 9l "Really Useful Box" and 3D printed a mounting plate for it all. There's also a fascia with a status LED, a button to shutdown/restart it and some places to cable-tie the cables in place to stop them getting yanked out of the internals. The box isn't properly waterproof long term but will stand use outdoors for the couple of days at a time that we need it.

All the external leads are hugely long. It's powered from a 12v lead-acid battery which needs tucking away somewhere safe and the PMR used to transmit needs some height to help with coverage and ends up tied to a pole high up.

Sometimes the wrong thing is the right thing

Once I'd reached this point of it working reliably and was thinking about how we'd use it in the game it popped into my head we could use What3Words to send the player group directions.

I'm no fan of this attempt to do corporate capture of something there should be an open standard for (there is one but it is a tad clunky) and the failings of their word choice algorithm for safety critical situations have been explored extensively by people smarter than me. However in this case, smacking the W3W app onto the tablets the players were already carrying and then sending locations into the chat as a clickable link that opened the app was a fair choice and we'd used it a little in the past.

Until the event I didn't even get to test it, and when we started using it the "/send" option where MU|TH|UR didn't read out the words was needed because otherwise it was a tide of unintelligible blah when we forgot.

Much as I have reservations about W3W it worked mostly OK for this, only once sending them in completely the wrong direction which was probably a GM mistake, and I think we'll be using this again next year.

Want to build your own?


I've now backed this all up and once I've had time to write an "installer" of sorts I'll update the previous instructions on GitHub.

Looks like love at first sight to me

Recently we finished up our four-episode LARP series, High Frontier: Gods and Monsters, which has been stuck in my consciousness ever since mid-2019. The pandemic delayed the first episode but we've run one episode a year since 2022 and it felt like I always had something for it on my to-do list.

Despite being set in our variant of the Alien/Prometheus universe we had not so far featured any Xenomorphs in the game and that was about to change.

An obvious way to signal this in advance is to feature the iconic visual of a Facehugger in a huge glass tube. I've been meaning to make one of these for years and had an earlier version that never really worked I junked.

Buying a large enough clear tube for the task was something I looked at over time but anything the right size was simply outside our prop budget. Knowing we really wanted this in the game I decided to bend a sheet of 3mm acrylic. How hard could it be?

Turns out it was quite hard.

I picked up a 1800x900mm 3mm acrylic sheet and used this halved as my basis to scale everything else, allowing me to make two tubes.

Not being an RPF level prop maker all my stuff just needs to look "about right". I always prioritise it being repeatably makeable and able to stand transport and handling by random people in the LARP.

You can bend acrylic with heat and last time I need to do larger pieces for ORAC I put them in an oven, which worked fantastically. Short of asking a local bakery nobody has an oven that's going to take square sheets this large. Which meant progressive use of a hot air gun was about the only option open to me.

Having done the calculation on the size of tube this would make it turned out I had a large cardboard tube close so I clamped the acrylic to this and repeatedly formed the sheets over this in a process that ended up taking a couple of days.

Meanwhile I found some reference photos of the original props and started doing a rough replica in CAD for 3D printing. There's a reason I own a large format bed slinger 3D printer, it's slow unfashionable and fairly low quality but it allows me to print larger items like this.

Some time back I had found a 3D poseable printable model of a Facehugger model and had printed all the parts for a couple as I'd planned to make two tubes. These ended up being really quite difficult to assemble even when following the printing instructions. The joints are super tight and even with careful printing on my newer printer and some sanding of the 'knuckles' they were prone to snapping when forced together. In the end I think I printed enough to make three and managed to get two completed ones.

I'd designed the top/bottom sections that hold the tube with a small groove in that should hold the acrylic into its tube shape and make the whole thing kind of seamless so as I got the first pieces off the printer I started to assemble things. Here I realised my mistake, I could see the tube wasn't perfect but 'almost round' and hoped constraining it into the printed pieces would even things out. Getting frustrated I tried to force it in and snapped a large corner chunk off, acrylic is quite brittle.

So we were down to one tube and I spent yet more hours trying to get that acrylic tube properly round.

The two Facehuggers got a rudimentary paint job. I'm a fan of heavy coats of generic DIY emulsion paint and varnish to cover layer lines on organic shapes and it worked out OK. The second Facehugger would still end up getting used laid out on a table.

The top and bottom sections got proper priming and sanding as they needed to look like metal close up.

When I came to fit the remaining tube, despite spending a long time bending it I still struggled to get it to fit, even with constraining it with straps and now realise I should have put a bevel in at least the inside of the slot it's supposed to fit otherwise it's just too hard to do singlehanded. With the LARP only a week away I didn't have time for a second costly mistake so I just taped the tube outside the top/bottom sections and up the back to cover the now large gap. I know it's not right but in the final analysis the players just saw a cool large prop so it did the job.

People with a decent memory of the original will see the control panel piece in the top section never got modelled and printed. I hit "perfect is the enemy of good" quite quickly once we were close to the event so I simply left it out. Now we're past it and I've got an interesting if huge prop to display in my house I think I'll go back and finish it up. I may even try to remove the tape and fit the acrylic properly, perhaps re-printing the round sections with a larger, tapered groove.

3D printed Data Slate props

For a long while I've been using old Nexus 9 tablets to act as 'cyberdecks' in our Cyberpunk LARP, but I was recently asked to dress them for a 40K themed one this summer.

The old 3D printed cases were getting long in the tooth and were clearly just unpainted poor quality 3D prints. So I started completely from scratch for this, only re-using my CAD model of what I needed to hold the tablet securely and operate the power and volume buttons on the side.

One of the major things I wanted to get away from was the obviously rectangular shape of the tablet screen. It's a common sci-fi trope for screens to be weird shapes and to emulate this I modelled a surround with truncated corners and cutouts for the cameras and speakers.

This looks great so long as the tablet is asleep, but once it wakes up the real shape of the screen is obvious. There's only so much I can do here and while I could have covered some of the usable area Android apps tend to quite rightly assume the whole screen is accessible.

On the old tablet holders I had added some old bag carrying straps, which are very practical but untidy looking so I added a very chonky carrying handle as part of the case.

This makes the whole thing physically large, which has the added advantage of making these hard to hide or just stuff in a bag. It's a not uncommon problem in LARP that acquisitive players will squirrel something away in their bag and it's never seen again unless they want to leverage it somehow. These were to have PDFs on them that were plot-relevant and we wanted that information very clearly available.

Annoyingly there's no open source 'kiosk mode' application for Android that I could find but to make sure the PDFs were visible whenever somebody woke the tablet I used the "Librera FD" viewer and the basic screen pinning functionality in Android to keep it maximised.

When asked to make these I wasn't sure how long the documents would be so I decided to add physical controls for paging through and searching documents. There's a scroll wheel, two buttons to page up and down plus a keyboard for text entry. This re-uses an X-Box 360 chatpad as making your own small keyboard keycaps that don't look terrible is very awkward and fiddly. There's also a piezo sounder to do keyboard/button bleeps.

This section is the part I'm least pleased with: the chatpad is too small and the buttons I ordered were too long to allow me to inset it like I did with the tablet section.

The design is ugly because I was rushing and I will most likely re-do this part before they are used again. I may even go as far as making a custom keyboard using tactile switches that fills more of the area.

These physical controls are driven by ESP32-S2 dev boards acting as USB OTG HID devices. I ran into a bit of a struggle with the code for this. Every time the tablet went to sleep, it would disconnect the USB devices and refuse to reconnect. I think this is related to this reported bug but was in a hurry to get this done so just made the ESP32-S2 restart whenever the tablet went to sleep. There is a little latency on waking it up but not a great deal. I would like to add more functionality to this setup, including my LoRa mesh network messaging stuff, so I need to overcome this problem. The 'cheat' would be to connect the ESP32 over BLE but given I have a direct physical connection to the tablet this sort of offends me and I'd need to swap to an ESP32-S3.

In the end though, this all worked out well, I got four of these made in different colours so they could be told apart and the paint weathering on the main body looks good. I didn't have time to weather the control sections so they just got some scratches but if I'm going to re-do them that's fine. I may also try to make some left handed variants and some without the big handle.

These will definitely be getting a load of use. Put Termux on them and they are almost 'real computers' and while the performance is poor in modern web applications we always curate what we let our players access. I've got a drawer full of Nexus 9s so printing and painting a few more of these over the next few months will get me a nice stash of usable props.



3D printing Lasertag lens units

For over a year I've been faffing with my own Lasertag PCB design but keep dropping the project when something else needs doing.

The PCB design seems OK but with a couple of poor decisions I'd fix were I to order more. The 'beta' software works so I fitted them in two of my own Lasertag weapons and one worked great but the other not so much. I think it's got two current limiting resistors because I didn't realise there was one in the existing lens unit already.

What I don't know was what the real potential of the board was with the component choices I'd made.

Having a board design sort of goes hand in hand with needing lens units to match and I want to do what Phil from UKLTA has done: design a re-usable 3D printed lens unit that can be included in larger things, or printed out to attach directly to conversions. This is especially true if I want to maybe make some 3D printed 40K themed weapons for our upcoming 40K LARP

I ordered some 25mm acrylic lenses a few weeks back and I've had a go at designing an adjustable 3D printed lens unit that uses them but what I really needed was a way to range test away from Lasertag events that didn't involve the Police being called on me. Being based in the UK this is a real concern. So last week I made up a 'gun on a stick' which looks nothing like a weapon apart from the attached sight.

Today I've done some testing at the Hackspace on the field and it's "good enough for The Grange" with no trouble hitting a target across the width field at ~140m.

Unfortunately this isn't really a good test as I arrived later than planned and the photos don't really show how much the light was going. I need to test again on a bright sunny day. Home is just a short walk from Wanstead Flats which is a huge area of common ground so I'll have to make a trip there when the sun is shining.

Good progress though.

Hackspace access control

I'm a trustee at East Essex Hackspace which is currently discussing buying a fibre laser and it's rekindled the desire for 'toolbots' to control access to things. Originally I was looking at this over a year ago but got busy with other things so shelved it and then the need suddenly seemed less urgent.

One of our challenges is that when we opened we used some Wiegand RFID readers for our door entry system and fed the UIDs they gave into our membership database. Later on we found out that these UIDs weren't the same as the UIDs other things reported. I did some fiddling around and realised a simple XOR and byte reshuffle that fixed this so we were back in business until I built something using this and found it wasn't right for some issued cards. 

Then the access control project got shelved.

Having dug out my access control mockup again I armed myself with a pile of cards that I know don't map IDs how I thought and quickly realised if they have a 7-byte UID then the byte order reshuffle is different than for a 4-byte UID. So we're potentially back in business.

For the hardware I've taken a bit of an executive decision on the basis that whoever does the work gets to say how it's done, otherwise endless bikeshedding occurs. The hardware will be based on an Olimex ESP32-EVB which is an ESP32 dev board with Ethernet, onboard relays and a bunch of hardware we probably don't need. They're reliably available and properly certified.

To add the RFID reader I've designed a little 'shield' that plugs into the UEXT connector on the EVB which I'll solder some cheap MRC522 boards to.

It also breaks out some GPIO and has LEDs and somewhere to connect a sounder. I'm not even sure if we'll use a sounder, but I just wanted to get the board ordered.

Work on the software has been ongoing for ages but I've started poking at it again and one of the other Trustees already did a bunch of stuff in our membership database so I'm hoping this project can get done without too much pain.

Each tool will have different ways of limiting its use but my expectation most will already have an interlock or emergency stop that can be connected to one of the onboard relays of the EVB. I'd not expect these devices to control the main power feed to the tool unless it's a very small one.

Hoverboard comms library

I'm back making silly moving things using hoverboard hub motors and re-flashed hoverboard controllers.

For months on end I've been vaguely putting off working on the big 6-wheel platform I started because I needed to write a library for the comms protocol so I wasn't committing the sin of copy & pasting great swathes of code to run the three separate controllers.

Now I've finally sat down and got round to it so the excuses for not progressing the big rover project are evaporating. I only started thinking about this two years ago.

MU|TH|UR setup script

I have now (mostly) documented/automated how to create a text-to-speech bot as recently used at our High Frontier LARP.

Instructions are here.