QZ qz thoughts
a blog from Eli the Bearded

Sitemap Plugin

About a month ago I posted about finding a lot of Blosxom plugins on github. I've been looking at some them. There are a family of them, one original and a few modifications to the original, for enabling comments. I have not gotten those to work: best I've gotten is I can leave comments, but not see them on pages. I may end up writing my own, so that it follows my idea of what is needed for comments.

But also in that batch of plugins was one for Google Sitemap. The documentation is non-existant in the repo. Searching the web I did find blog posts from the author, in Japanese. From those I gather the version in the github repo is the old, memory intensive way to build a sitemap. I didn't find the new improved version.

I decided to make do. The gsitemap plugin is dead simple. It just sets a few variables to use in templates, and then when the sitemap flavor is desired, disables pagination. The rest of the magic happens in the flavour templates.

As part of making do, I'm not going to reference or link to the URL that generates the output (if you are reading and want to use this for your own site, the gsitemap plugin in the original configuration would generate it for https://example.com/blosxom/index.xml, assuming /blosxom/ is the root of your Blosxom blog).

Instead I've reconfigured the templates to generate a fragment of a sitemap XML file, changed the flavour to sitemap from xml, and have scripted up a sitemap builder for the whole qaz.wtf site that curls the proper URL and includes() the xml fragment. Blosxom then can remain the source of truth for blog permalinks while find and some per-directory configuration can build URLs for other parts of the site.

I decided I should run that script from SAVE-DATES.sh under the theory that any time I save post timestamps is a likely time I want to rebuild the sitemap. This works for qaz.wtf because the blog is the only thing updating more frequently than monthly, and I typically run SAVE-DATES.sh shortly after posting an entry.

This is all prompted by looking (again) at just how much bot traffic the site gets. I figure a sitemap will stop well-behaved bots from crawling as much or as frequently. And for non-well-behaved bots, I've belt and suspendered things by adding entries to robots.txt and more user-agents to my browser_block plugin.

Similarly in the name of improving search engine interaction, I've got a new (trivial) plugin called extrameta that gets used by other plugins, namely the newly modified tags plugin and pagination plugin to add a <meta name="robots" content="noindex"> header (in a naive way) to search result pages, to avoid duplicated content.

Tiring, err, Tiling work

Before Covid-19 reared it's head, my wife took out a lease on what we're calling the shop-factory. For the past decade she has made money selling patterns and teaching people knitting and sewing. The space is a former cleaners. With some cleaning, and a few repairs, it was mostly suitable. Except the bathroom. That needed a lot of work.

Most of the business has been sewing patterns in the last three years. Giant pieces of osper that need to be folded to fit in a 6"x8" and booklets with instructions to be printed, folded, and stapled. Then put in a folder and taped shut for ssle.

The idea is the shop-factory would be a place to manage her business from — instead of using a room of our house — and also be a place she could teach classes. A big table for folding patterns. A row of small tables for sewing machines for students. Shelves to hold all the business consumables. A bathroom students to use, with space to change. A large mirror for seeing how garments, once made, look.

Covid-19 has put a damper on treaching classes, for sure. And shelter-in-place has interrupted preparing the space. We took the sink and vinyl floor out of the bathroom in March and then it was nothing happening for so long. Finally, Memorial Day weekend we made progress. Started with taking the toilet out. Then putting down a moisture barrier. Then tiling. Then grouting. Finally cleaning up.

Tiring work.

toilet removed
tiling begun
grouting finished
nippers and waste

Game Tools

Here, some discussion of two game tool programs I have in game-tools on github.


In the mid-1990s, I knew an admin of the Tsunami MUD and played the game a bit. Fast-forward a decade and I decided to give it a try again. At (then) about fifteen years old (now closer to thirty), it was one of the older MUDs around, which meant it had a very long time to expand. There were vast areas of the game to explore, and I set out to see as much as I could.

Over the course of several months, I visited huge swaths of the game, and got myself on the explorer leaderboard, where I was one of the lowest level characters there. (Accounts automatically delete after time time if you don't log in, so I can't know if others had done better than me before then, and you won't be able to find me there now.) Eventually I started to run into time-to-new-area payoff diminishing returns and stopped playing.

While I was playing I drew myself a lot of maps. At first these were on paper, but eventually I developed an ASCII art short hand. This let me have text files I could grep for noteworthy items or places. From there, I wrote a tool that could take my ASCII art maps and convert them into nice printable maps. asciimapper worked by converting my ASCII art into config files for ifm the "Interactive Fiction Mapper", which was designed for Infocom and similar games. The crossover to MUD maps was trivial. Some of the maps I printed and would hand annotate for further details, but most I kept only in ASCII file form.

I have all my ASCII art maps for Tsunami somewhere, I could probably dig them out and put them on the web. I haven't played in at least a decade now, though, and there's more than zero chance some of them are obsolete. Some became inaccuate while I was playing. In particular I recall the entrance to Toyland moving, to be friendlier to low level players.

I've been thinking about asciimapper again as I play "Andor's Trail"; (previously dicussed about a month ago here). In "Andor's Trail", there are perhaps 520ish visitable areas, most of which show up on the World Map, but about 20% are indoors, underground, or otherwise not visible there. How to get to those plus the inventories of stores in particular spots has been something I've been mulling over. The ASCII art needed for the World Map would be doable, but something of a challenge.

The maps are text form already though, just not very clear text form. Here's an excerpt from AndorsTrail/res/xml/woodsettlement0.tmx, an XML file apparently created by Tiled:

 <objectgroup name="Mapevents">
  <object name="east" type="mapchange" x="928" y="224" width="32" height="64">
    <property name="map" value="roadbeforecrossroads2"/>
    <property name="place" value="west"/>
  <object name="woodhouse1" type="mapchange" x="608" y="288" width="32" height="32">
    <property name="map" value="woodhouse1"/>
    <property name="place" value="south"/>
  <object name="woodhouse2" type="mapchange" x="640" y="128" width="32" height="32">
    <property name="map" value="woodhouse2"/>
    <property name="place" value="south"/>
  <object name="woodhouse0" type="mapchange" x="224" y="256" width="32" height="32">
    <property name="map" value="woodhouse0"/>
    <property name="place" value="south"/>
  <object name="sign_wdsetl0" type="sign" x="800" y="256" width="32" height="32"/>
  <object name="sign_wdsetl0_grave1" type="sign" x="128" y="160" width="32" height="32"/>
  <object name="sign_wdsetl0_grave2" type="sign" x="128" y="224" width="32" height="32"/>

You can easily see how the map pieces connect together, including ones like woodhouse0, woodhouse1, and woodhouse2 that don't show up on the World Map. In woodhouse2.tmx we find Lowyna:

<objectgroup name="Spawn">
  <object height="96" name="smuggler1" type="spawn" width="96" x="32" y="96"/>
  <object height="128" name="smuggler2" type="spawn" width="96" x="128" y="96"/>
  <object height="32" name="lowyna" type="spawn" width="96" x="288" y="96"/>

Which with a little bit of work we can connect that the shop "droplist", in this case in AndorsTrail/res/raw/droplists_v070_shops.json, to get items she stocks.

A map.tmx to IFM format converter might be handy, but I haven't put any serious thought into it.


I have thought about game play efficiency with "Andor's Trail". In particular while playing I thought it would be useful to have a way to see how fast I'm earning in-game rewards like XP, game currency, item drops, and how fast I'm using consumables while doing so. I imagined a tool that I could tell what I have at a particular time and it would work out how much that changes over time.

Those imaginings lead to stat-timer, a CLI with a very old school interogation interface. You can use the command line to give it starting stats or just start it and it will ask for stats. Then you can update as many or as few stats as you want each round and it gives updates. The design requires that you name stats for the initial state, and then if in same order, you can omit names. Thus the most important things being measured should be first, and least important last. Or least changing last.

In practice this means I've been putting XP first, then common area item drop and/or gold, then health potion count, and then rare drops, and finally — sometimes — constants I want for annotations. As I play, I update XP frequently and other columns less frequently. To update just the first two columns is a matter of just entering the first two numbers. To update first and third requires labeling the number for the third column. After each entry it gives a snapshot of how things are doing on a per-second basis. When done, I can <ctrl-d> out or put a ! at the end of the numbers to indicate final update. It then gives a final update with total changes, per-hour and per-second rate of changes. This makes it easier to compare play style one to play style two even if they are on different days and for different lengths of play.

If I update it further, things I've been thinking about for improving it include: a curses interface with data at particular screen locations, sophisticated "pause timer while entering data", realtime per-second updates, and perhaps a more sophisticated state model for the command line, for better continuation after an intertuption.


My desk at $WORK is small, with a large monitor taking up a lot of the space. And it is a motorized sit/stand desk with no real options for drawers or shelves. But I want to keep some small amounts of desk things in drawers. So I designed a small set to fit the space.

Short enough to fit under the monitor, with something on top of it, legs tall enough to have computer cables run underneath it, big enough to hold a note pad and paper clips, made of thin wood to not take up more space than necessary.

I made the drawers out of wood I had on hand. The drawers are a little crude. I mitered the edges of four sides and the bottom and glued them together with some square profile pieces reinforcing all of the joins. In retrospect I should have used triangle profile and neater joins for the reinforcing bits. I glued some button plugs on for pulls.

Those completed, I purchased some 3mm thick plywood for the case. Then Covid-19 hit.

My monitor is still on my desk at work, but I'm never in the office anymore. My home desk has ample shelves around it, and room to attach a drawer to the underside, if I wanted.

So the project went on hold.

But recently I returned to it.

chiseling a dado

For the sides, I measured, scored with a box cutter, then chiseled out dados for each of the horizontal pieces (top, middle, bottom). The chisel is a tungsten carbide one I made myself following how-to-guides by Patrick Sullivan on youtube.

loose fit together

I started with the bottom shelf, then loose fit the pieces together, put a drawer on it and measured for the middle, then did it again for the top. Here's the project at that stage.

clamped for glue

For the glue-up, I clamped a piece of scrap to my work table, then clamped the box between more scrap to that piece. Towards the end of the project I decided it would look good to have cork sides, for a micro pin board. I glued those on similarly.


Here it is completed, on my home desk. At home, I run the cables out of the left side of the computer, at $WORK, the right. Just what's better for the power location. It fits a post-it pad and some dice on top. The smallest pins I could find are map tacks, but they are still a bit long for the shallow cork. I waxed the bottoms and sides of the drawers for smoother operation. Otherwise, the wood is unfinished.