Tainted Grail - The Fall of Avalon

The game is a quite good RPG. It borrows heavily from Skyrim, Gothic, Morrowind and a bit of the Witcher and Elden Ring, but the mix is quite good.
You start as somebody possessed by King Artus, who wants to regain dominion over Avalon. The island has been taken over by the Red Blight, and the Knights of Kamelot are reigning from afar, not necessarily well. It is a grimdark setting but manages to be not entirely bleak.
Graphics
I'm playing this on an old(ish) PC with an Nvidia RTX 1080, with graphics at 1080p and "low" setting. The graphics are still OK. The world feels very handcrafted, and for example some of the ruins feel hand-placed but without much transition from the landscape to the ruin blocks. It strongly reminds me of Gothic in that regard. The general idea of the landscape reminds me of Elden Ring, except that the landscape is more gray and not in the glorious colors of Elden Ring.

World
The world is compressed, but still feels believable (for a fantasy RPG open world world). It is not littered with Ubisoft-style
fetch quests and collectibles, and soulless question marks with nothing to explore there. There are some side things to do,
like collecting cooking recipes, collecting ingredients for magic potions, some mild crafting, but it is all for making you a
better fighter, or keeping you alive. The crafting feels very close to Skyrim.
The characters inhabiting the world are grimdark, mostly, but there are also some weird characters and even mild attempts
at comedy. They are not as present as Jaskier in The Witcher, but not having everybody be within the grimdark framework
makes for good entertainment.

Gameplay
The game loop consists of exploring the world, mildly guided by quests, and then selling the loot at merchants, and maybe
crafting new stuff. The skills / leveling are taken from Morrowind, where doing any activity improves your ability in it. So,
cooking a meal slightly improves your general cooking ability. Running around a lot improves your running ability. And
conjuring monsters improves your general magic ability.
The fighting feels very much like Skyrim, having bow and arrows, magic and close combat. The fighting forces you
to switch weapons more often than Skyrim did, but that adds to the variety.

Story
There are various factions and various side quests that are well-written. There is a lot of (English) voiced dialogue,
which can get tedious at times, but on the other hand, it is spoken well and the voices feel in-character. Even the
side quests have a lot of spoken dialogue and I haven't found a quest without talking yet.
Conclusion
Overall, the game is interesting and touches the right buttons for me. It's
enjoyable to just go through the scenery, finding new caves to explore or
citizens to speak with. I am currently in the first act of the game and already
am overpowered (summoner magicians usually are), but that's fine.
Last Monday I did the Perl Developer Release of Perl 5.43.7. As usual, I worked from the Release Managers Guide . Everything worked well, even if everything was cutting it a bit close. My video setup on the desktop was not suited for streaming anymore, so I had to do a stream consisting only of the console window and me talking over it, and no floating head of me available.
What worked well
The Twitch chat was the most active that I witnessed when streaming a Perl release. We chatted about organizing Perl conferences and also the Perl release process. One realization for me was that the RMG process is mostly there to exercise the Perl build machinery and testing that the generated tarball does not have deficiencies. This means that testing that Perl can build through Configure is important, but testing different Perl configurations like ithreads or userelocatableinc is not that important.
The dashboard for tracking my progress through the release worked well up to the release. I had modified it in the weeks leading up to the release to not only show the human step description but also to show the command line steps that should be undertaken, where applicable. I see this as a first step in automating these steps where possible and sensible.
What didn't work out
The dashboard can use some improvements:
The script did not cope well with the events after the release when the repo version number was bumped from 5.43.7 to 5.43.8. This part needs to be investigated but is easy to replicate by simply launching the dashboard with a version number before the current version number.
The script could highlight the current position in the sequence better. For console output this would likely mean inverting the line where the next applicable step is, but this means moving the output from Text::Table to a custom table generation or post-patching the string from Text::Table with the appropriate console commands.
The script should generate HTML and terminal output at the same time. Having output visible in a browser feels less retro but makes things like publishing the progress elsewhere easier.
The script should have a feature to simply output the next step. This could be integrated into the shell prompt to give a guided message in the console window. Maybe the console output and the HTML output should be done as files when in "interactive" mode?
Improvements to the Perl Release Process
More parallelism - the current release manager guide uses make test in many places. This runs the test suite in serial mode, which takes on my machine about 10 minutes. Running the test suite in parallel takes about 4-5 minutes. This is implemented using the make test_harness command. Whether Perl should move the default of parallel testing to make testfrom make test_harness is debatable. Most likely everybody who cares about speed already runs the test suite in parallel.
Remove sequences of shell commands - comparing the file names between the previous and current Perl version is done using a sequence of shell commands involving sort, diff`. I have a patch that adds a small tool to do that within Perl (mostly powered by Algorithm::Diff ).
From time to time, I look back and take tally of what programs and modules
I released in the past. This is one of these posts.
This module is a clone of the Mixmark turndown library,
which converts HTML into Markdown.
my $markdown = html2markdown('<h1>Hello World</h1>');
# Hello World
The module is highly convenient for my
note-taking tool, which lets
me edit notes as contentEditable HTML to enable formatting and pasting
of images etc. .
Other times, I want to do quick text editing, and using Markdown is far more
convenient than editing HTML on my mobile phone. As I store the documents not
as HTML but Markdown, converting from HTML/contentEditable to Markdown is
helpful here.
The nice thing about this module is that I chose to reuse the test suite of
the turndown Javascript library and styled the code similarly to the
Javascript example. That made porting some changes in the Javascript library
to Perl very easy, even if I don't strive for 1:1 identity.
Date::Find - extract dates from filenames
Together with the app move-year, this is a nifty tool to watch my download
directory and move bank statement .pdf files into the corresponding
directories organized by year. Often these files are named in weird ways
like statement-03.01.2025.pdf or accountstatement-2025-january.pdf, but I
want them in a directory bankstatements/2025/ . Date::Find looks at the
filenames and finds the year (and month, and day). The app then creates the
appropriate year (or month, or day) directory and moves the file there.
As my note-taking tool fetches link previews, I want to be a bit more cautious
as to what URLs I freely fetch. This adapts
Net::DNS::Paranoid and the
ruleset to also work for Mojolicious.
What I did not release
That link preview/card generation thing - postponed
Mojolicious::Plugin::UrlWithout
A small HTML page helper that returns an URL without a given key/value combination:
my $url = "/filter?label=foo&label=bar";
my $other = url_without( "/filter", label => 'foo' );
# /filter?label=bar
This module sounded like a really good idea, so I wrote it. The use case was a
search/filter page, where you can toggle different labels by clicking on them.
The labels were realized as <a href=... elements. Then I realized I don't
need it at all, if I switch my HTML to a form with GET and use HTMX to
automatically update the filter:
<form method="GET" action="/filter" hx-get="/filter" hx-trigger="change from:input changed">
<label for="label-foo">foo</label><input type="checkbox" checked name="label" value="foo" />
<label for="label-bar">bar</label><input type="checkbox" checked name="label" value="bar" />
<button type="submit" class="nojs">Apply</button>
</form>
Patches I contributed
I contributed a small change to the
DBD::SQLite catalog functions so it
now also knows about generated columns in a table. Funnily, the old SQLite
function was named table_info, and the function including the generated
columns is named table_xinfo . I guess once there is another type of
information to return, they will need to add table_yinfo, or move to the
Microsoft-stlyle of having table_info_ex(), with another parameter listing
the information actually wanted by the caller.
Patches that were not applied (yet)
Together with Mojo::UserAgent::Paranoid, I also
added IPv6 support to Net::DNS::Paranoid,
but my changes have not yet been reviewed or accepted.
I use that patched module locally, and there it works well.
This is my yearly look at Android Desktop Mode.
The idea is to use my phone, docked to a screen, keyboard and mouse as a remote desktop platform. The goal is to run a remote desktop through RDP,
Citrix Workspace, or another such app, and use MS Teams and other stuff
supplied by that remote machine/VM. That way, I would not need a laptop since my phone has enough power to do the RDP thing.
Phone version
Pixel 9 XL
GrapheneOS 20251225
Android 16
Setup 1 ("Amazon Basics")
Phone connected to Amazon Basics USB-C docking station with HDMI display
Screen gets recognized and added (1600x900 or 1920x1080 resolution), a taskbar shows up at bottom, but no tasks other than Camera can be launched from it. After the screen lock activates, the taskbar is gone. Mouse works, keyboard not tested (?!). Taking a screenshot of the Android Desktop is not possible.
Setup 2 ("HP")
Phone connected to HP USB-C docking station with HDMI display.
What works in Android 16
HP: Desktop appears on HDMI screen, mouse and keyboard work. Taskbar at the bottom of the HDMI screen. Remote desktop works and displays. Phone-local apps and the remote desktop can live on the phone desktop and can be resized without problem.
What doesn't work in Android 16
HP: Screen resolution is weird. Smaller screen space, but pixel count seems to be full-width and then scaled down to smaller screen space.
Fennec HTML zoom is very weird and seems to orient itself on the phone-screen measurements, not on the HDMI screen measurements. Further debugging is needed.
External camera and microphone don't seem to work with the Citrix Workspace app.
I built my first MOC using Lego-compatible Building Bricks (German: "Klemmbausteine"). I saw the inspiration and main baseline in a photo by a colleague on LinkedIn
where they had built a model of our skyscraper office building. Having not played with Lego bricks for a long time, I gave in and tried to build something similar
to the photo.
But first, the result:

For some reason, I did not remember the premier modeler, LDraw, so I went with the 3D builder offered by Mecabricks.
The builder works fairly well, but you cannot save/export your model without signing up.
After being satisfied with my rebuilding after the photo, I manually created the CSV import for upload with MOC brick store. The upload failed to match
discontinued parts with their replacements or unavailable colors, so I had to do some manual replacements in my CSV import. The import also did not allow for easy checking of which parts were unavailable,
so I had to do the complete order manually, working from my CSV file instead of uploading the CSV file. The shipping was roughly as expensive as the blocks, but that's expected for something coming from China.
This ended up with me mis-ordering one brick type. Luckily I ordered one more than needed from every brick type so I still could make things work in the end and I am happy with the final product:
