<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Starforge</title>
    <description>
      Project Shinar updates, Unreal tutorials, and random thoughts
    </description>
    <link>https://starforge.co.uk</link>
    <atom:link href="https://starforge.co.uk/feed_rss_updated.xml" rel="self" type="application/rss+xml"/>
    <language>en</language>
    <pubDate>2026-05-20T15:18:42Z</pubDate>
    <lastBuildDate>2026-05-20T15:18:42Z</lastBuildDate>
    <ttl>1440</ttl>
    <image>
      <url>https://starforge.co.uk/assets/logo.png</url>
      <title>Starforge</title>
      <link>https://starforge.co.uk</link>
    </image>
<item>
  <title>About</title>
  <description><![CDATA[
# About
## Me

I am Chris (although you may know me as my alter-ego, Jeremiah Fieldhaven).
I've been developing software since the 1980s, and at this point it's not
so much something I do as something I am. As my day job has drifted inexorably
along 
]]></description>
  <content:encoded><![CDATA[
<h1>About</h1>
<h2 id='head1'>Me</h2>
<p>I am Chris (although you may know me as my alter-ego, Jeremiah Fieldhaven).
I've been developing software since the 1980s, and at this point it's not
so much something I do as something I am. As my day job has drifted inexorably
along the path to Management, I've found I really need to make time to write
code and build things in my spare time to save my sanity.</p>
<p>I'm currently using Unreal Engine 5 to build a 3D puzzle game called Project
Shinar, a game inspired by an old Amiga game called Tower of Babel with
visuals reminiscent of the neon-glowing polygons of TRON.</p>
<p>I'm generally terrible at keeping websites updated, so we'll see how this goes...</p>
<h2 id='head2'>Contacts</h2>
<p>You can find me on <a  target="_blank"  href="https://mastodon.gamedev.place/@JeremiahFieldhaven">Mastodon</a>
or I can be emailed at <a href="mailto:chris@starforge.co.uk"><a href="mailto:chris@starforge.co.uk">chris@starforge.co.uk</a></a></p>
<h2 id='head3'>Why &quot;Jeremiah Fieldhaven&quot;?</h2>
<p>Essentially, it started off as a bit of silliness. I had been playing <a  target="_blank"  href="https://www.failbettergames.com/games/sunless-sea">Sunless Sea</a>
and there was a place on my map not far from Wolfstack Docks called &quot;Fieldhaven's Rest&quot;.
At the same time, I decided I wanted to start over in <a  target="_blank"  href="https://www.elitedangerous.com/">Elite Dangerous</a>
with a new commander, so I was looking for a name. I decided it would be Very Silly
to have a spaceship commander with a Victorean-era sounding name flying around in
the 3300s world of Elite, so I set about coming up with a suitably ridiculous name.
With &quot;Fieldhaven&quot; in my head as a surname for this commander, I chose a likely
looking forename from a list of 1800s names. And thus <a  target="_blank"  href="https://www.edsm.net/en/user/profile/id/26401/cmdr/Jeremiah+Fieldhaven">Jeremiah Fieldhaven</a>
came into existence. I connected with other Elite Dangerous players on Twitter and
Discord with the same name, and the rest is history really.</p>
]]></content:encoded>
  <link>https://starforge.co.uk/about/</link>
  <pubDate>2026-05-20T15:18:36Z</pubDate>
  <guid isPermaLink="true">https://starforge.co.uk/about/</guid>
  <enclosure url="https://starforge.co.uk/assets/og/site.jpg" type="image/jpeg" length="921807"/>
</item>
<item>
  <title>AI/LLMs</title>
  <description><![CDATA[
# Where I am on "AI"

There have been many drafts of this page, but I find myself unable to really
communicate my stance without falling back on profanity.

So.

Fuck the LLMs like ChatGPT, Claude, Copilot, and the rest. Fuck the complete
gobshite 
]]></description>
  <content:encoded><![CDATA[
<h1>Where I am on &quot;AI&quot;</h1>
<p>There have been many drafts of this page, but I find myself unable to really
communicate my stance without falling back on profanity.</p>
<p>So.</p>
<p>Fuck the LLMs like ChatGPT, Claude, Copilot, and the rest. Fuck the complete
gobshite pissweasel fascist techbros behind this absolute mess. And especially
fuck them for adulterated the term &quot;AI&quot; so that legitimate techniques are
tarred with the same brush as their massively wasteful LLM chatbots.</p>
<p>The whole enterprise of the LLM chatbot companies is based on theft, deception,
wholesale violations of legal and social contracts, DDoS attacks on websites,
and massive harms to the environment, society, individual cognitive function, and
the future of multiple industries due to deskilling and disruption of
entry-level training.</p>
<p>I have to protect my servers against the attacks from their crawlers,
spending time, effort, and resources to handle the bloody things while I watch
the increasingly inflated bubble hurtle towards its inevitable crash as the
true costs involved and the utter lack of any path to profitability becomes
impossible for the investors to ignore.</p>
<p>I can not, and will not, support any part of it and if you use their shit kindly
do us both a favour and sod off.</p>
<p>I will not set aside my moral and ethical objections to a technology out of
convenience to replace cognitive exercise with a gambling-addiction-adjacent
make-up-statistically-probable-bullshit machine churning out mediocre crap
and peddled by a cabal of suppurating fistulas.</p>
<p>Or, put another way: I do not use generative AI for any part of my site, games,
or other programs.</p>
]]></content:encoded>
  <link>https://starforge.co.uk/ai/</link>
  <pubDate>2026-05-20T15:18:36Z</pubDate>
  <guid isPermaLink="true">https://starforge.co.uk/ai/</guid>
  <enclosure url="https://starforge.co.uk/assets/og/site.jpg" type="image/jpeg" length="921807"/>
</item>
<item>
  <title>Home</title>
  <description><![CDATA[
# Welcome

After having my old site sit dormant for the best part of five years, I think it's probably
finally time to try something a bit different. For a start, I've ditched Wordpress; in part
because of the unending tantrums of Matt "Drama" 
]]></description>
  <content:encoded><![CDATA[
<h1>Welcome</h1>
<p>After having my old site sit dormant for the best part of five years, I think it's probably
finally time to try something a bit different. For a start, I've ditched Wordpress; in part
because of the unending tantrums of Matt &quot;Drama&quot; Mullenweg, but mainly because Wordpress is
just overkill for what I need (as well as being constantly attacked.)</p>
<p>This new site is generated using <a  target="_blank"  href="https://git.starforge.co.uk/chris/Homer">Homer</a>, a minimalist
static site generator I wrote after issues with MkDocs. I need to write up a description of
the site generator process, and why it was created soon.</p>
<h2 id='head1'>Latest updates</h2>
<ul>
<li>2026-05-03: Another new site - now made using my own site generator.</li>
<li>2026-04-03: Updated the <a href="https://starforge.co.uk/links/">Links</a> page</li>
<li>2026-02-21: Added a page discussing <a href="https://starforge.co.uk/projectgregorian/">Project Gregorian</a></li>
<li>2025-08-23: Added a new <a href="https://starforge.co.uk/unreal/">Unreal</a> page and <a href="https://starforge.co.uk/unreal/UComboBoxKey-Images/">Using images in UComboBoxKey</a></li>
<li>2025-03-23: Added a section <a href="https://www.starforge.co.uk/leng/">just for AI Crawlers</a>. Note: This is a tarpit, enter at your peril.</li>
<li>2025-01-26: Added a brief <a href="https://starforge.co.uk/projectshinar/history/">history of Project Shinar</a> and its inspiration.</li>
<li>2025-01-20: New site!</li>
</ul>
]]></content:encoded>
  <link>https://starforge.co.uk/</link>
  <pubDate>2026-05-20T15:18:36Z</pubDate>
  <guid isPermaLink="true">https://starforge.co.uk/</guid>
  <enclosure url="https://starforge.co.uk/assets/og/site.jpg" type="image/jpeg" length="921807"/>
</item>
<item>
  <title>Links</title>
  <description><![CDATA[
Links to other sites on the interwebs
]]></description>
  <content:encoded><![CDATA[
<p>Finding stuff on the internet in the <a  target="_blank"  href="https://en.wikipedia.org/wiki/Discordian_calendar">Year of Our Lady of Discord</a> 3191 is nigh impossible, so here are
some links to cool people you should check out.</p>
<h2 id='head1'>Buttons</h2>
<p>Apparently 88x31 buttons are making a comeback<sup id="fnref:1"><a class="footnote-ref" href="#fn:1">1</a></sup>, so here's a few! If you want your button
to appear here, contact me on Mastodon or via email with your URL and button image.</p>
<p><a  target="_blank"  href="https://dhippo.net/"><img src="https://starforge.co.uk/assets/88x31/dhippo.png" style="width: 88px; height: 31px"></a>
<a  target="_blank"  href="https://enikofox.com/"><img src="https://starforge.co.uk/assets/88x31/eniko.png" style="width: 88px; height: 31px"></a>
<a  target="_blank"  href="https://mw.revasser.net/"><img src="https://starforge.co.uk/assets/88x31/morroque.png" style="width: 88px; height: 31px"></a>
<a  target="_blank"  href="https://punchingrobots.com/"><img src="https://starforge.co.uk/assets/88x31/punchingrobots.webp" style="width: 88px; height: 31px"></a>
<a  target="_blank"  href="https://punchthemoon.com/"><img src="https://starforge.co.uk/assets/88x31/punchthemoon.gif" style="width: 88px; height: 31px"></a>
<a  target="_blank"  href="https://www.rainbowcemetery.com/"><img src="https://starforge.co.uk/assets/88x31/rcbutton.png" style="width: 88px; height: 31px"></a>
<a  target="_blank"  href="https://shinmera.com/"><img src="https://starforge.co.uk/assets/88x31/shinmera.gif" style="width: 88px; height: 31px"></a>
<a  target="_blank"  href="https://shirakumo.org/"><img src="https://starforge.co.uk/assets/88x31/shirakumo.gif" style="width: 88px; height: 31px"></a>
<a  target="_blank"  href="https://sysl.ca/"><img src="https://starforge.co.uk/assets/88x31/sysl.gif" style="width: 88px; height: 31px"></a>
<a  target="_blank"  href="https://virtualmoose.org/"><img src="https://starforge.co.uk/assets/88x31/virtualmoose.webp" style="width: 88px; height: 31px"></a>
<a  target="_blank"  href="https://abandon.ie/posts/"><img src="https://starforge.co.uk/assets/88x31/abban-webring.webp" style="width: 88px; height: 31px"></a>
<a  target="_blank"  href="https://tobekko.fi/"><img src="https://starforge.co.uk/assets/88x31/tobekko.png" style="width: 88px; height: 31px"></a>
<a  target="_blank"  href="http://www.hempuli.com"><img src="https://starforge.co.uk/assets/88x31/hempuli.png" style="width: 88px; height: 31px"></a></p>
<p>If you want to use a 88x31 button to link to this site, here's one:</p>
<img src="https://starforge.co.uk/assets/88x31/88x31logo.png" style="width: 88px; height: 31px">
<h2 id='head2'>Webring</h2>
<p>[    <a href="https://www.rainbowcemetery.com/devring">GAMEDEV   WEBRING</a>    ]<br>[<a href="https://www.rainbowcemetery.com/devring/prev.php?id=0">&lt;PREV</a> <a href="https://www.rainbowcemetery.com/devring/rand.php?id=0">RAND</a> <a href="https://www.rainbowcemetery.com/devring/list.php?id=0">LIST</a> <a href="https://www.rainbowcemetery.com/devring/next.php?id=0">NEXT&gt;</a> ]</p>
<h2 id='head3'>Other links</h2>
<p>These are in no particular order, just links to sites I highly recommend:</p>
<ul>
<li><a  target="_blank"  href="https://www.hempuli.com/">https://www.hempuli.com/</a> - Hempuli, of Baba Is You fame.</li>
<li><a  target="_blank"  href="https://bumbershootsoft.wordpress.com/">https://bumbershootsoft.wordpress.com/</a> - Michael Martin's software experiments, retro projects.</li>
<li><a  target="_blank"  href="https://www.teamonstergames.com/">https://www.teamonstergames.com/</a> - Games by Jeff Murray.</li>
<li><a  target="_blank"  href="https://www.stevestreeting.com/">https://www.stevestreeting.com/</a> - Unreal and general gamedev tips from Steve Streeting, creator of <a href="https://www.ogre3d.org/">Ogre</a>, <a href="https://sourcetreeapp.com/">Sourcetree</a> and others.</li>
<li><a  target="_blank"  href="https://grumpygamer.com/">https://grumpygamer.com/</a> - Ron Gilbert (Monkey Island, etc).</li>
<li><a  target="_blank"  href="https://nivrig.com/">https://nivrig.com/</a> - Games by John Girvin.</li>
<li><a  target="_blank"  href="https://runevision.com/">https://runevision.com/</a> - Really interesting discussions of procgen tech, game design, and more.</li>
<li><a  target="_blank"  href="https://www.ascorbius.com/">https://www.ascorbius.com/</a> - Elite Dangerous story videos and general muppetry from an awesome chap.</li>
<li><a  target="_blank"  href="https://glassbottomgames.com/">https://glassbottomgames.com/</a> - SkateBIRD and more.</li>
<li><a  target="_blank"  href="https://www.stevehammond.org/">https://www.stevehammond.org/</a> - Formerly of DMA design, writing and UFOs.</li>
<li><a  target="_blank"  href="https://www.heartofneon.com/">https://www.heartofneon.com/</a> - Started off as a Llamasoft documentary, now covers indie devs too.</li>
<li><a  target="_blank"  href="https://kenney.nl/">https://kenney.nl/</a> - Really fun low-poly asset packs.</li>
<li><a  target="_blank"  href="https://kaylousberg.com/">https://kaylousberg.com/</a> - More low-poly asset packs.</li>
<li><a  target="_blank"  href="https://www.neilhenning.dev/">https://www.neilhenning.dev/</a> - Verse developer at Epic.</li>
<li><a  target="_blank"  href="https://whatever.scalzi.com/">https://whatever.scalzi.com/</a> - Author, and generally decent human.</li>
<li><a  target="_blank"  href="https://www.nathansavant.com/">https://www.nathansavant.com/</a> - Narrative and game design.</li>
<li><a  target="_blank"  href="https://www.tomcooksound.co.uk/">https://www.tomcooksound.co.uk/</a> - Songwriter, artist, and pillar of the Elite Dangerous community.</li>
<li><a  target="_blank"  href="http://thalass.freeshell.org/">http://thalass.freeshell.org/</a> - Thalass' projects.</li>
</ul>
]]></content:encoded>
  <link>https://starforge.co.uk/links/</link>
  <pubDate>2026-05-20T15:18:36Z</pubDate>
  <guid isPermaLink="true">https://starforge.co.uk/links/</guid>
  <enclosure url="https://starforge.co.uk/assets/og/links.png" type="image/png" length="921807"/>
</item>
<item>
  <title>Project Gregorian</title>
  <description><![CDATA[
# Project Gregorian[^1]

## A bit of background

Every year for the past decade or so my wife and I have bought a fractal
art calendar to hang on the wall between our desks. We both like fractals
and thought the work of this particular artist was 
]]></description>
  <content:encoded><![CDATA[
<h1>Project Gregorian<sup id="fnref:1"><a class="footnote-ref" href="#fn:1">1</a></sup></h1>
<h2 id='head1'>A bit of background</h2>
<p>Every year for the past decade or so my wife and I have bought a fractal
art calendar to hang on the wall between our desks. We both like fractals
and thought the work of this particular artist was really excellent. The
calendars were were well made, showed the days in a way we liked, and
generally ticked most of the boxes for us for a wall calendar.</p>
<p>In October 2025 my wife discovered that the creator of the calendars had
stopped making them, so we had to decide what to do for a wall calendar in
2026: should we try to find a different fractal calendar, or go for
something else entirely?</p>
<p>As we were sat talking about this with our monitors in view, I pointed out that
the form factor of the calendar was fairly close to a 24 inch screen in
portrait orientation. We could scan the images from previous calendars, or we
could use any of the nearly 70,000 photographs<sup id="fnref:2"><a class="footnote-ref" href="#fn:2">2</a></sup> we've taken over the past
couple of decades, and display them above a generated calendar. We need not
even be constrained by the limitations of paper at that point!</p>
<h2 id='head2'>The requirements</h2>
<p>Eventually we settled on a few key things any dynamically generated calendar
<em>needed</em> to do, with any features on top of these being nice to have:</p>
<ul>
<li>The week needed to start on Sunday.</li>
<li>Instead of showing one month at a time, the calendar should show a 5 week
rolling view: the previous week, the current week, and the next three weeks.<sup id="fnref:3"><a class="footnote-ref" href="#fn:3">3</a></sup></li>
<li>The display should show the month and year information, and handle the case
where the rolling display spans multiple months or the start/end of years.</li>
<li>The calendar should be able to fit the colour scheme we want for the room.</li>
<li>The display should have an image at the top, and the calendar below it, as
you would expect for a wall calendar.</li>
<li>There should be some way to move the calendar display forward and backward
to show past or future weeks.</li>
</ul>
<p>You can see more details of the features the system provides in the
<a  target="_blank"  href="https://git.starforge.co.uk/chris/ProjectGregorian/src/branch/main/README.md">readme file</a>
in the project repository.</p>
<h2 id='head3'>How the devil to build this</h2>
<p>Having opened my big mouth, I now had to work out how to make this work. It
obviously had a bunch of extra things to decide on that the bare requirements
didn't even really touch on, things like</p>
<ul>
<li>Desktop program, or web application?</li>
<li>How to get events into the calendar? Import from an ical feed? Or multiple
ical feeds? Or allow events to be defined in the system? All the above?</li>
<li>How to get pictures in, how to choose which picture to show at any given
day or time, and what dimensions to use for the pictures?</li>
<li>How to actually display it on a screen?</li>
<li>How to do the controls?</li>
<li>Many, many other sentences ending in '?' that I will spare you!</li>
</ul>
<p>The first constraint to help narrow down the implementation space was that it
had to fit onto a 24 inch screen in portrait mode, so 1080x1920 was the target
for the display. I didn't want to try to drive the screen off any of the
computers on the desks, and I have several spare Raspberry Pi 3B+s lying around
from old projects, so it made sense to have a Raspberry Pi connected to the
screen and have it show the calendar.</p>
<p>This helped to add another constraint! My past experience with Raspberry Pis
has made me very wary of running anything important on them because they seem
to be <em>harsh</em> on microSD cards. I've had decent quality microSD cards go dead
in less than a year when used in a Pi, so I didn't want to put the actual
calendar software <em>on</em> the Raspberry Pi, just in case it shat itself and lost
any data between backups. I decided the most straightforward approach would be
to write the calendar system as a web application running off my server, and
have the Raspberry Pi connect to the WiFi and start a web browser in kiosk
mode showing the calendar page. That way the system would be part of the
normal backups on the server, and nothing would be lost if the SD card went
off to silicon heaven.<sup id="fnref:4"><a class="footnote-ref" href="#fn:4">4</a></sup></p>
<p>Using a Raspberry Pi also opened up the option of using the GPIO pins to
provide a means of controlling the display. One of the standard
<a  target="_blank"  href="https://github.com/raspberrypi/firmware/blob/master/boot/overlays/README">device tree overlays</a>
available on the Raspberry Pi is the <code>gpio-key</code> overlay, and if you connect a
push-button switch between an appropriate GPIO pin and 0v, you can have the
gpio-key overlay emit an input event when that button is pressed (the overlay
also handles <a  target="_blank"  href="https://en.wikipedia.org/wiki/Switch#Debouncing">debouncing</a> the
switch, which makes life even easier!) Multiple GPIO-connected buttons can be
added, allowing a range of input events to be triggered in response to
button presses.</p>
<h2 id='head4'>To the code mines!</h2>
<p>As previously noted, the &quot;volunteering to make this thing&quot; happened <em>in October</em>.
What I didn't say is that it was <strong>the last week of October</strong>. Which meant I had
two months to get it into a usable state for the start of the year. So I decided
to fall back on building it in a language I know well (Perl<sup id="fnref:5"><a class="footnote-ref" href="#fn:5">5</a></sup>), in a framework
I've used for years, cribbing a lot of supporting code from another one of my
projects to get things going faster.</p>
<p>I'll skip the gory details of the implementation - if you are interested, you
can find the code and instructions for installing it <a  target="_blank"  href="https://git.starforge.co.uk/chris/ProjectGregorian">in the Project Gregorian repository</a><sup id="fnref:6"><a class="footnote-ref" href="#fn:6">6</a></sup>.
A few pointers if you really want to explore the code for Eris knows what reason:</p>
<ul>
<li>The calendar page itself is generated by the <a  target="_blank"  href="https://git.starforge.co.uk/chris/ProjectGregorian/src/branch/main/views/WallCalendar/Calendar.pm">WallCalendar::Calendar</a>
class. The entrypoint in that file is the <code>page_display</code> function
at the end, which calls <code>_dispatch_ui</code> to generate the HTML content
or <code>_dispatch_api</code> to handle API calls from the javascript.</li>
<li>Other classes in the <a  target="_blank"  href="https://git.starforge.co.uk/chris/ProjectGregorian/src/branch/main/views/WallCalendar">views</a>
directory generate other pages - the images manager, login form,
and settings page. The entrypoint in each is the <code>page_display</code>
function, which then calls the UI or API dispatcher for that class.</li>
<li>Classes inside the <a  target="_blank"  href="https://git.starforge.co.uk/chris/ProjectGregorian/src/branch/main/modules">modules</a>
directory are system and support code, with model code for the
calendar data and image handling inside <a  target="_blank"  href="https://git.starforge.co.uk/chris/ProjectGregorian/src/branch/main/modules/WallCalendar/Database">modules/WallCalendar/Database</a></li>
</ul>
<p>Some things I will note about the implementation process, though:</p>
<ul>
<li>I decided early on that I wouldn't allow the creation or editing of events
through the site, and I would rely on importing events from established
calendar tools using ical feeds. Building an event management UI looked like
being a complete pain in the arse, and it would have taken me a lot of time
(I didn't have) to get even close to key feature parity with existing
calendar tools. That said, the database schema <em>is</em> set up in a way that could
allow for an in-system event management UI in the future if I ever lose my
godsdamned mind.</li>
<li>Building this thing had me get way more familiar with <a  target="_blank"  href="https://www.rfc-editor.org/rfc/rfc5545">RFC 5545</a>
and siblings than I ever thought I would be, and in the process I discovered
some things I've never seen calendar tools do that the spec supports
(particularly around repeat events). I was honestly impressed with how much
thought had gone into it, even if section 3.3.10 will haunt my nightmares
for a long time to come.</li>
<li>Relatedly, I also discovered that different calendar tools interpret parts of
the spec in subtly different ways, which was... unsurprising.</li>
<li>This whole project takes an arguably terrible approach to dealing with time
zones and DST<sup id="fnref:7"><a class="footnote-ref" href="#fn:7">7</a></sup>. In that it largely ignores them as much as possible. Essentially
it treats events as happening in 'local time', and the only real shenanigans
with time zones happen when establishing when &quot;now&quot; is. I <em>think</em> it will work
in practice as long as you're not dealing with events defined in multiple
time zones, but I'm not certain, and it makes my head hurt summat proper.</li>
</ul>
<h2 id='head5'>The hardware side</h2>
<p>The hardware side of this project was much more straightforward - there are
essentially three major components:</p>
<ul>
<li>The screen. Any 24 inch screen would work really, larger ones could work but
the system assumes a 1080x1920 display so it <em>might</em> not look right without
tweaks<sup id="fnref:8"><a class="footnote-ref" href="#fn:8">8</a></sup>. We got a fairly basic Philips 24E1N1100A for it.</li>
<li>The Raspberry Pi. Pretty much any of them should do the job, although any
before a 3B+ might struggle, and the 4 or later may need active cooling. In
fact any system that has wired or wireless network support, can run a web
browser (ideally Firefox-derived), and outputs its display over something
the monitor supports should do the job, I just happened to have a RasPi 3B+
lying around.</li>
<li>The control buttons. I'll describe this in more detail shortly, but this is
essentially a very simple circuit on a piece of <a  target="_blank"  href="https://en.wikipedia.org/wiki/Stripboard">stripboard</a>
with wires going to a set of GPIO pins on the RasPi, housed in a 3D printed
box.</li>
</ul>
<p>As it turned out, the choice of screen was quite lucky: there is just enough
space in the cable entry area at the back of the monitor to fit the RasPi,
and the space is deep enough that the RasPi can sit inside the standard case
and be stuck to the monitor to hold it in place.</p>
<p><img src="https://starforge.co.uk/assets/images/gregorian/screen_back_1.jpg" alt="Screen Back 1"   style="display: inline-block; width: 45%; padding: 0.5rem;" />
<img src="https://starforge.co.uk/assets/images/gregorian/screen_back_2.jpg" alt="Screen Back 2"   style="display: inline-block; width: 45%; padding: 0.5rem;" /></p>
<h3 id='head6'>The control buttons</h3>
<p>As mentioned above, if you set up a push button switch between a GPIO pin on
the RasPi and the 0v line, you can use the <code>gpio-key</code> overlay to emit a
key event when the button is pressed. There are lots of ways to do fancy
things with this, but for this situation all it really needs is 7 push
switches wired up to GPIO pins:</p>
<p><img src="https://starforge.co.uk/assets/images/gregorian/wallcalendar_circuit.png" alt="Circuit diagram"  title="A circuit diagram showing 7 push buttons, with one side individually connected to GPIO pins, and the other sides all commoned to GPIO pin 34 (0v/ground)" /></p>
<p>The stripboard implementation of the circuit is a bit messy - definitely
not my cleanest work. I used a pair of old USB cables to connect to the
RasPi, and I was not entirely consistent in the selection of colours for
the cables for each switch, so a fair bit of double-checking connections
with a multi-meter was needed. To help keep the wires in place, and to
provide a bit of strain relief, I used some strong black thread wrapped
over the wires and through the stripboard.</p>
<p><img src="https://starforge.co.uk/assets/images/gregorian/button_bar_1.jpg" alt="Stripboard 1"   style="display: inline-block; width: 45%; padding: 0.5rem;" />
<img src="https://starforge.co.uk/assets/images/gregorian/button_bar_2.jpg" alt="Stripboard 2"   style="display: inline-block; width: 45%; padding: 0.5rem;" /></p>
<p>Once connected onto the GPIO pins for the RasPi, the <a  target="_blank"  href="https://git.starforge.co.uk/chris/ProjectGregorian/src/branch/main/supportfiles/raspi/config.txt#L42-L55">config.txt</a>
with gpio-key overlay lines added was all that was needed to make the
buttons work.</p>
<p>The button bar itself would look a bit ugly just hanging out there naked,
so I designed an enclosure for it and asked a relative who has a 3D printer
to print the box for me:</p>
<p><img src="https://starforge.co.uk/assets/images/gregorian/button_box_1.jpg" alt="Box 1"   style="display: inline-block; width: 45%; padding: 0.5rem;" />
<img src="https://starforge.co.uk/assets/images/gregorian/button_box_2.jpg" alt="Box 2"   style="display: inline-block; width: 45%; padding: 0.5rem;" /></p>
<p>It fits around the stripboard circuit and holds it in place, and the printed
buttons give a bit more area to press than the small push buttons alone.</p>
<p>Fitting the bar below the screen was a bit trickier - I needed some way to
mount it, and the screen bezel is too thin at the bottom. Luckily I had
a piece of acrylic left over from another project <sup id="fnref:9"><a class="footnote-ref" href="#fn:9">9</a></sup> that was almost the
right size, minus a few cut-out pieces that I could work around, so by
sandwiching the acrylic between the screen and the wall mounting plate,
I could use double-sided tape to stick the button bar below the screen!</p>
<h3 id='head7'>The rest</h3>
<p>A few other things were needed to make the whole thing work:</p>
<ul>
<li>First the RasPi needs to be configured to boot into X11 rather than
wayland (so unclutter will work)</li>
<li><a  target="_blank"  href="https://wiki.debian.org/unclutter">unclutter</a> needs to be installed to hide the mouse pointer</li>
<li>screen blanking and xscreensaver need to be turned off</li>
<li>a <a  target="_blank"  href="https://git.starforge.co.uk/chris/ProjectGregorian/src/branch/main/supportfiles/raspi/firefox.desktop">firefox.desktop</a> file
has to be added to ~/.config/autostart/ on the RasPi to load the browser after
the desktop has loaded.</li>
</ul>
<p>With those in place, whenever the Pi is powered up it will boot to a desktop,
start the browser, and load the calendar automagically.</p>
<p><img src="https://starforge.co.uk/assets/images/gregorian/assembled_1.jpg" alt="Assembled 1"   style="display: inline-block; width: 45%; padding: 0.5rem;" />
<img src="https://starforge.co.uk/assets/images/gregorian/assembled_2.jpg" alt="Assembled 2"   style="display: inline-block; width: 45%; padding: 0.5rem;" /></p>
<h2 id='head8'>Some closing thoughts</h2>
<p>This was definitely an interesting project to take on, and so far it has been
working out well: it's something we both look at many times a day, and the
rolling nature of the display really helps prevent surprises at month starts.</p>
<p>I would be utterly lying if I tried to claim that there had been no problems
with the system, but for something that I put together the majority of in a
handful of weeks (with only parts of weekends and some evenings to work on it)
I am really happy with how it has turned out. There are definitely some places
in the code I could improve or clean up a bit, but really that's true of any
project.</p>
<p>The worst part - and the part that has led to the most bugs, headscratching,
and profuse swearing - has been the process of importing calendar events from
ical feeds. It has definitely given me a very profound appreciation for the
complexities of calendar handling and I would not be at all surprised if the
importer is something I end up having to tweak or fix more than anything else
in the code over the coming months.</p>
]]></content:encoded>
  <link>https://starforge.co.uk/projectgregorian/</link>
  <pubDate>2026-05-20T15:18:36Z</pubDate>
  <guid isPermaLink="true">https://starforge.co.uk/projectgregorian/</guid>
  <enclosure url="https://starforge.co.uk/assets/og/site.jpg" type="image/jpeg" length="921807"/>
</item>
<item>
  <title>Unreal</title>
  <description><![CDATA[
# Unreal bits and pieces

Over time I'm slowly collecting a few Unreal bits and pieces, techniques,
and not-entirely-tutorials here in the hope they may be useful to others
doing battle with the behemoth known as Unreal Engine.

I should note that 
]]></description>
  <content:encoded><![CDATA[
<h1>Unreal bits and pieces</h1>
<p>Over time I'm slowly collecting a few Unreal bits and pieces, techniques,
and not-entirely-tutorials here in the hope they may be useful to others
doing battle with the behemoth known as Unreal Engine.</p>
<p>I should note that the pages linked from here are discussions of Things I
Have Figured Out, either by chanting the appropriate arcane profanities
while reading the source, or piecing things together from scatted forum
posts and hastily-scrawled, blood-stained notes scattered prominently on
desks in abandoned offices<sup id="fnref:1"><a class="footnote-ref" href="#fn:1">1</a></sup>. They may not represent the correct - or
even necessarily remotely sane - way to do things, but they seem to work
for me.</p>
<p><a href="https://starforge.co.uk/unreal/UComboBoxKey-Images/">Using images in UComboBoxKey</a></p>
<h2 id='head1'>About the Blueprints</h2>
<img src="https://starforge.co.uk/assets/images/unreal/Blueprint1.png" style="width: 100%; height: auto;" />
In case you look at any of the blueprint images within these pages and exclaim
"Gosh! These blueprints do not look like an unfortunately indiscriminate and
explosive industrial accident in a spaghetti factory! How has that happened?!"
may I direct your attention to the most splendiferous [Electronic Nodes](https://www.fab.com/listings/d6148766-27b1-47db-a730-832c53b7a895){ target="_blank" }
plugin on Fab. I have it configured to do Subway wire style, right wire
alignment, no wire priority, and 0 round radius. I think it is fair to say
that plugin has done a lot to preserve the tattered remnants of my sanity
while using the various blueprint editors. I can not recommend it enough.
]]></content:encoded>
  <link>https://starforge.co.uk/unreal/</link>
  <pubDate>2026-05-20T15:18:36Z</pubDate>
  <guid isPermaLink="true">https://starforge.co.uk/unreal/</guid>
  <enclosure url="https://starforge.co.uk/assets/og/site.jpg" type="image/jpeg" length="921807"/>
</item>
<item>
  <title>Project Shinar</title>
  <description><![CDATA[
# Project Shinar: A Bit of History

## The original inspiration

Cast your mind back if you will, dear reader, to the heady days of 1991[^1].
The Soviet Union collapsed, the first Gulf War ended, the World Wide Web
was released outside CERN to 
]]></description>
  <content:encoded><![CDATA[
<h1>Project Shinar: A Bit of History</h1>
<h2 id='head1'>The original inspiration</h2>
<p>Cast your mind back if you will, dear reader, to the heady days of 1991<sup id="fnref:1"><a class="footnote-ref" href="#fn:1">1</a></sup>.
The Soviet Union collapsed, the first Gulf War ended, the World Wide Web
was released outside CERN to other research institutions, and the first website
ever was published. Amidst all of these and many other huge events, one
event in particular had an impact on my young self that may be responsible
for where I am today: this was the year my brothers and I got an <a  target="_blank"  href="https://en.wikipedia.org/wiki/Amiga_500">Amiga 500</a>
for Christmas.</p>
<p>We were pretty late to the Amiga really, but my family weren't exactly well
off and the Amiga wasn't cheap. It took some saving to buy the system. As a
family we'd gone to a small shop called Stewart Electronics on Penny Meadow
in Ashton-under-Lyne<sup id="fnref:2"><a class="footnote-ref" href="#fn:2">2</a></sup>, and we brought the new computer home on a rattly
old bus while we poured over the box. The set we got came with a bundle of
games<sup id="fnref:3"><a class="footnote-ref" href="#fn:3">3</a></sup>, and one of those games was Tower of Babel.</p>
<p>Tower of Babel had been released the year before for the Amiga, programmed by
Pete Cooke and published by Rainbird Software, a label of <a  target="_blank"  href="https://en.wikipedia.org/wiki/MicroProse">MicroProse</a>.
It was effectively a port of an Atari ST game, so it didn't really take
full advantage of the Amiga's capabilities - with the perspective provided
by many years of distance, it is pretty obvious that the sound effects are
basic and crude, the graphics are at best functional, and the framerate
on a stock A500 was... not great.</p>
<p>That said, coming from a <a  target="_blank"  href="https://en.wikipedia.org/wiki/ZX_Spectrum#ZX_Spectrum_128">ZX Spectrum 128</a>
it blew us away: the graphics, sound, and speed <em>were</em> way ahead of anything
we were used to. ToB was played a lot to begin with, in part because it was a fun puzzle
game, but perhaps more so because it included a level editor! We could build
our own levels and challenge each other to finish them - always a good source of
fun between brothers (or arguments anyway). Inevitably it fell by the wayside
as more games were acquired, but even now I still have a copy of ToB in my
WinUAE install.</p>
<h2 id='head2'>So, what was it then?</h2>
<p>The name comes from a somewhat strained attempt at providing the
background for the game: the construction of the Tower of Babel attracts the
attention of passing aliens who leave three robots to help the Shinarians
with their work on the Tower. Human nature being what it is, things go
pear-shaped, and the humans turn on the robots. The player controls the three
robots as they attempt to traverse levels (called 'towers') full of traps,
puzzles, and creatures so they can collect their power supplies and escape.</p>
<p><img src="https://starforge.co.uk/assets/images/shinar/tob_front1.png" alt="Screenshot"   width=320  />
<img src="https://starforge.co.uk/assets/images/shinar/tob_front2.png" alt="Screenshot"   width=320  /></p>
<p>Leaving dubious biblical references to one side, the game itself has you controlling
the imaginatively named &quot;Zapper&quot;, &quot;Pusher&quot;, and &quot;Grabber&quot; robots: Zapper has
a laser beam you use to blow things up, Pusher has a repeller beam to push
things away from it, while Grabber has a tractor beam to collect the
all-important power supplies and turn on a few different devices around the
towers.</p>
<p>Tower Of Babel's supplied 'towers' are split into 13 groups of 9 towers, each of
which puts you in control of one, two, or three robots. Each level has varying
objectives - you might need to collect a given number of the power supplies
and/or destroy a given number of objects, and there may be a time limit in
which you need to complete the objectives (for some reason that is never
explained.)</p>
<p>The levels themselves are formed from coloured squares in a chequerboard
pattern, up to 8x8 floor squares in horizontal size, and with up to four
floors. Travel between different floors is via grey 'lift' squares that
can go up or down at most one floor. When objects, including the robots,
move around the level they may only do so along the cardinal directions -
they can not move diagonally - and only one object may occupy a given
square at a time.</p>
<p><img src="https://starforge.co.uk/assets/images/shinar/tob_level1.png" alt="Screenshot"   width=320  />
<img src="https://starforge.co.uk/assets/images/shinar/tob_level2.png" alt="Screenshot"   width=320  />
<img src="https://starforge.co.uk/assets/images/shinar/tob_level3.png" alt="Screenshot"   width=320  />
<img src="https://starforge.co.uk/assets/images/shinar/tob_front3.png" alt="Screenshot"   width=320  /></p>
<h2 id='head3'>And so to Project Shinar</h2>
<p>I've done game dev, on and off, for almost as long as I have had access to a
computer<sup id="fnref:4"><a class="footnote-ref" href="#fn:4">4</a></sup>, but almost none of the things I've done have really come close
to a state where I'd release them<sup id="fnref:5"><a class="footnote-ref" href="#fn:5">5</a></sup>. I'd always either end up losing
interest or, more likely, end up going down rabbit holes trying to write my
own engine and end up never actually <em>making a game</em>. During 2017 I got it
into my head that I wanted to learn Unity and hopefully make something I'd
<em>actually release</em>. I started casting around for ideas for what to make, but
inspiration eluded me.</p>
<p>Then one day I was clearing out boxes in the attic<sup id="fnref:6"><a class="footnote-ref" href="#fn:6">6</a></sup> and came across <a  target="_blank"  href="https://archive.org/details/AstraPack_Tower_Of_Babel_Amiga/_Manual01_1200/">the manual</a> for
Tower of Babel in a box of old manuals and papers. This set me wondering, could
I use ToB as inspiration for a game to build while learning Unity? I didn't
want to straight up <em>clone</em> the game, but it did start a chain of design ideas
for ways to take the core ideas of the game - the three robots, having them
coordinate to solve puzzles in a 3D world - and see what could be done without
the restrictions of late 1980s/early 1990s technology.</p>
<p>It was late 2019 before I'd actually worked out what I wanted to do, and
really started learning Unity to make it work. A key piece of the puzzle came
when playing with possible designs for turrets in Lightwave when Winamp<sup id="fnref:7"><a class="footnote-ref" href="#fn:7">7</a></sup>
randomly chose the <a  target="_blank"  href="https://youtu.be/iOCKc917XdA?si=pjdvRslTB2wWsgGr">Overture</a>
track from the <a  target="_blank"  href="https://www.youtube.com/playlist?list=OLAK5uy_ncZEqIkjEY-qvlzl_5FVk3JUwGNGFxjwU">TRON: Legacy soundtrack</a><sup id="fnref:8"><a class="footnote-ref" href="#fn:8">8</a></sup>
and I suddenly realised: what if I took the core mechanics from Tower of Babel
and set it inside a TRON-like world inside a computer? Lots of ideas suddenly
started to slot into place</p>
<ul>
<li>The three robots are robotic agents being controlled by the player trying
to infiltrate a big computer system and extract data from it.</li>
<li>The TRON-inspired setting allows for manageable assets: fairly low poly
objects with relatively simple textures that add glowing edges, and no
need for organic-like objects (making those has always been my nemesis.)</li>
<li>The TRON-inspired setting also gives scope for naming things in a TRON-like
way: referencing computer parts, systems, or programs for areas the game
happens in, naming the robots after CPU assembler mnemonics (even M68k ones!),
and naming entities found in levels in a similar fashion.</li>
<li>Time limits for levels can be explained as runtime limits on the
program the robots are working in.</li>
<li>With the scope of more memory, CPU power, and graphics power, I can
allow larger levels, and more programming steps per robot.</li>
</ul>
<p>I threw away the turret design I had been working on, and started building
something that looked like it could exist in the TRON world, and quickly came
to the conclusion that this <em>would work</em></p>
<figure><p><img src="https://starforge.co.uk/assets/images/shinar/shinar_turret_2019.png" alt="Screenshot"   width=320  /></p><figcaption>The first turret object from 2019-12-17</figcaption></figure>
<p>Before long I had a list of features, NPCs, and level mechanics that took
ideas from Tower of Babel and enhanced them or added entirely new systems,
like  wall-mounted signal emitters that beams could activate to send signals,
and those signals could turn things on or off, open barriers, or even move
lifts.</p>
<p>Progress was still really slow, though - I had a lot of trouble focusing in
the latter part of 2019 and early 2020 <em>for some reason</em>. During the first
lockdown, <a  target="_blank"  href="https://www.ascorbius.com/">Ascorbius</a> started doing gamedev
livestreams and I regularly joined the chat for those. Those livestreams
and conversations really helped my enthusiasm, and I really got into the
development properly.</p>
<p>I'm going to fast-forward a bit here, because this is long and rambly enough
as it is.</p>
<p>By mid 2023 I had released several alpha versions of Project Shinar,
and by that point a fair bit of the game was working: levels could be
completed, a lot of entities had been made and worked, the built-in level
editor was functional, and I was starting work on the interface the player
would use to move between different zones in the computer.</p>
<p><a  target="_blank"  href="https://jeremiahfieldhaven.itch.io/project-shinar/devlog/588210/halting-development-in-unity">And then The Unity Debacle of Sept 2023 happened</a>.</p>
<p>To say I was put out would be something of an understatement. I could have
carried on with Unity, realistically I wasn't affected by their change, but
I'd be forever worried about them doing something else that would cause me
trouble, and continuing to support them in any way just felt wrong.</p>
<p>So I needed a new engine. And while I wasn't starting from scratch again -
I knew many of the assets could be used in any other engine - I knew I was
going to end up redoing several years of work.</p>
<p>By mid-October 2023, I'd settled on Unreal as the replacement. Another
page will probably be in the works about my experience moving from Unity
to Unreal...</p>
<figure><p><img src="https://starforge.co.uk/assets/images/shinar/shinar_work_2023.png" alt="Screenshot"   width=320  /></p><figcaption>The first screenshot I have from Unreal of work on the rebuild.</figcaption></figure>
]]></content:encoded>
  <link>https://starforge.co.uk/projectshinar/history/</link>
  <pubDate>2026-05-20T15:18:36Z</pubDate>
  <guid isPermaLink="true">https://starforge.co.uk/projectshinar/history/</guid>
  <enclosure url="https://starforge.co.uk/assets/og/site.jpg" type="image/jpeg" length="921807"/>
</item>
<item>
  <title>Showing images (and more) in a UComboBoxKey widget</title>
  <description><![CDATA[
A slightly hyperbolic overview of how to create a dropdown list of images that the user can select an image from.
]]></description>
  <content:encoded><![CDATA[
<h1>Showing images (and more) in a UComboBoxKey widget</h1>
<img style="float:right; padding: 0.5rem; width: 200px; height: auto" src="https://starforge.co.uk/assets/images/unreal/Combobox1.png" />
Imagine if you will that you are working away at constructing a widget
blueprint. You are carefully translating the immaculately sketched,
delicately executed statements of cutting-edge graphical paradigms,
and modern, dynamic layout that were grudgingly bestowed upon you by
your UI designer (during a brief interlude between animated debates
about the merits of curved buttons versus straight buttons, and the
role of the colour purple in signalling state.)
<p>If you do not have a UI designer, feel free to imagine yourself wearing a
black turtleneck and a condescending expression for the same effect.</p>
<p>ANYWAY, amidst the buttons, bars, and borders you discover there is a need to
present the user of your user interface with an interface that allows the
selection of an image from a list of images: a dropdown list of images if
you will. This is apparently not negotiable without interrupting a 3 hour
symposium that will inevitably descend into factional disagreements over
lists and checkboxes, so a dropdown it must be.</p>
<h2 id='head1'>UComboBoxString v UComboBoxKey</h2>
<p>The first thing you may notice, while gazing forlornly upon the Input category
of the widget palette, is that Tim Epic gives us not one but two types of
ComboBox. One has the mysterious and obtuse suffix <code>(String)</code> while the other
has <code>(Key)</code>, and the tooltips for the two are nearly the same. However, neither
seems to mention images at first glance. Despondent at this you might attempt
to glean advice from the documentation. There's nothing like good documentation,
and as all Unreal users can agree its documentation is nothing like good
documentation. In this case, it's as much use as a chocolate fireguard.</p>
<p>Eventually it may become clear that that the &quot;Use OnGenerateContentWidgetEvent
to return a custom built widget&quot; part of the <code>ComboBox (Key)</code> tooltip is a clue.
On plonking one down in your widget blueprint you will notice that there are
<em>two</em> events you can do things with: there's the <code>OnGenerateContentWidgetEvent</code>
alluded to in the tooltip and its companion <code>OnGenerateItemWidgetEvent</code>. Those
sound very much like things that expect you to create your own widgets to show
in the content area of the box, and for each item in the dropdown respectively.
This is because that's exactly what they are - although <strong>good luck getting
that from the docs</strong>. And you can make the widgets be <em>basically anything you
want</em>: everything from a simple Text box up to a panel containing multiple
widgets!</p>
<p>In short:</p>
<ul>
<li>Use <code>ComboBox (String)</code> if you just a dropdown that only contains strings (not even Text - just strings!)</li>
<li>Use <code>ComboBox (Key)</code> for dropdowns containing <em>anything else</em></li>
</ul>
<h2 id='head2'>An actual example</h2>
<p>If you've made it this far through the somewhat hyperbolic prose, you'll want
to see how to do this - and honestly, many of the other almost-explanations of
this I have managed to find for this go full-on Draw The Rest Of The Owl here
so without further tangents or hyperbole <sup id="fnref:1"><a class="footnote-ref" href="#fn:1">1</a></sup> I'll explain how I got the image
list dropdown shown in the screenshot above to work.</p>
<h3 id='head3'>The Options list</h3>
<p>Once you've added a <code>ComboBox (Key)</code> to your widget blueprint, style it as
needed - I won't go over this, because the style options are largely the common
ones you find for all the other widget types, and thankfully they're mostly
self-explanatory.</p>
<p>What might throw you is that the Content -&gt; Options list is just an array of
<code>Name</code>s, similar to the <code>ComboBox (String)</code>'s array of strings. This
is where you'll need to think a little laterally. What I did was create an
array of Texture2D object references to store the list of signal images<sup id="fnref:2"><a class="footnote-ref" href="#fn:2">2</a></sup><sup id="fnref:3"><a class="footnote-ref" href="#fn:3">3</a></sup></p>
<div style="text-align: center"><img style="height: 256px; width: auto" src="https://starforge.co.uk/assets/images/unreal/Combobox3.png" /></div>
<p>And then on constructing the widget blueprint that contains the Signals
dropdown I add entries to its options list, one for each array element:</p>
<div style="text-align: center"><img style="height: 128px; width: auto" src="https://starforge.co.uk/assets/images/unreal/Combobox2.png" /></div>
<p>So now there's a list of <code>Name</code>s that are really just indexes into an
array, and the corresponding array of images. Now we need to make images
appear.</p>
<h3 id='head4'>Showing the images</h3>
<p>The naive thing to do at this point is to click on the <code>On Generate Content Widget</code>
button, click on <code>+ Create Binding</code> and set up a function like this:</p>
<img style="height: auto; width: 100%" src="https://starforge.co.uk/assets/images/unreal/Combobox5.png" />
<p>the function creates a new <code>Image</code> object, converts the <code>Item</code> name to a
string, then an int, uses that to index into the <code>SignalImages</code> to get
the texture to show, sets the brush in the <code>Image</code> from that texture, and
returns the result. Set the <code>On Generate Item Widget</code> event to call the
same function and...</p>
<div style="text-align: center"><img style="height: 128px; width: auto" src="https://starforge.co.uk/assets/images/unreal/Combobox6.png" /></div>
<p>Well. It sort of works! The problem is obviously that the Image is being sized
to fill the container, but the image should be shown as a square, not stretched
to near-unreadability across a rectangle!</p>
<h3 id='head5'>Showing the images <em>properly</em></h3>
<p>But we can make <em>any</em> widget and show it in the combobox, which means there
are ways to avoid such a stretchy and distorted fate. Create a new widget
blueprint (I called mine WBP_Editor_SignalBox because that's where it is being
used: signal comboboxes in the editor) and do something like this:</p>
<div style="text-align: center"><img style="height: 256px; width: auto" src="https://starforge.co.uk/assets/images/unreal/Combobox7.png" /></div>
<p>That is, an appropriately sized image inside a Horizontal Box, set up to be
centre aligned horizontally and vertically. I also added a function to that
widget blueprint that let me set the texture drawn in the image<sup id="fnref:4"><a class="footnote-ref" href="#fn:4">4</a></sup></p>
<div style="text-align: center"><img style="height: 128px; width: auto" src="https://starforge.co.uk/assets/images/unreal/Combobox8.png" /></div>
<p>With that in place, the <code>OnGenerateContentWidget</code> function for the dropdown
can be updated to create an instance of the newly-defined widget blueprint:</p>
<img style="height: auto; width: 100%" src="https://starforge.co.uk/assets/images/unreal/Combobox9.png" />
<p>This does much the same as the previous one, except instead of an <code>Image</code> it
creates a new <code>WBP_Editor_SignalBox</code> and sets the texture shown in the image
via the <code>SetSignalImage</code> function. With that change made, success!</p>
<div style="text-align: center"><img style="height: 128px; width: auto" src="https://starforge.co.uk/assets/images/unreal/ComboboxA.png" /></div>
<h2 id='head6'>Some extra thoughts</h2>
<p>One thing to note is that you don't necessarily need to use an array of
textures here - you could have a more complex setup where you have an array
or map of structs with more data in there. I'm using an array of textures
because the situation is pretty simple. It would be fairly trivial to extend
this so that instead of just an image, there's an image and a Text box to
show a name next to the image. It's entirely possible I may end up doing
that in my level editor.</p>
<p>As you're providing a widget for each item and the contents of the dropdown
button, you could conceivably have different layouts for each, and even
have the dropdown list vary so that even rows get one type of widget, odd
ones a different type, just be careful to not go overboard otherwise you
might get even more condescending stares from the UI designer (real or
imaginary...)</p>
]]></content:encoded>
  <link>https://starforge.co.uk/unreal/UComboBoxKey-Images/</link>
  <pubDate>2026-05-20T15:18:36Z</pubDate>
  <guid isPermaLink="true">https://starforge.co.uk/unreal/UComboBoxKey-Images/</guid>
  <enclosure url="https://starforge.co.uk/assets/og/site.jpg" type="image/jpeg" length="921807"/>
</item>

  </channel>
</rss>