Categories
Tabletop Roleplaying Games

Fury Road: A Fate Accelerated Adventure, Part One

Inspired by other FATE “Example of Plays”, especially Station53’s “Avengers Accelerated“, I wanted to create my own Fate Accelerated version of a famous movie. After some deliberation, I decided to partly retell George Miller’s Mad Max: Fury Road. It’s action-driven nature and small cast lends itself to this style. Since I was not sure which scene I should retell, I just start at the beginning. Let’s see where that leads us.

Meet the Characters

The game is set by George, our game master, fittingly abbreviated as GM. Max is played by Tom, who actually took over the character from another player, but decided to give it his own twist. Charlie plays Imperator Furiosa. And finally, Nick plays Nux, our plucky War Boy. While the players have decided to play in a post-apocalyptic world, unusually for Fate they created their characters in isolation, so they don’t know exactly what their relation is going to be.

When we first meet our jolly gang, George and Tom are already seated at the gaming table, while Charlie and Nick are still in the kitchen, preparing dinner. But George wants to start off the session with Tom’s character anyway.

Scene 1: The Desert

Tom starts the scene with three Fate Points (his Refresh), while George starts with only one (the number of players in the scene.)

GM: Why don’t you tell me a bit about yourself, Max?

Max: Sure. My name is Max. I used to be a cop in the outback, before things went sour. I have quite obviously let myself go. My hair is unkempt and knotty and I wear dirty black leather. Currently, I am standing in the desert, next to my car, The Last of the V8 Interceptors. I stare out into nothingness, listening to the voices in my head.

Behind me, a two-headed gecko looks around and scuttles closer. When it’s next to my foot, I stomp on it. Finally, some food!

Tom glances towards the kitchen, the smell of food being prepared wafting over.

GM: I know you’re just narrating, but let’s call that an Overcome action to warm up the dice a little. Say against a difficulty of Fair.

Tom rolls  and adds his Quick of +3 for a total of +4, which is higher than the required +2. Success.

Max: Easy. I crush the gecko under my foot and swallow it whole.

GM: Ugh. Anyway, while you are still chewing, you hear the sound of engines in the distance. What will you do?

Max: I grab all my stuff, throw it into the V8 and take off in a cloud of dust.

GM: Just as the dust settles, we see a gang of several cars and a few motorcycles follow you. Actually, I’d like to offer you a compel. You have been on the road for a long time. The Last of the V8 Interceptors isn’t in as good a shape as it used to be. If you accept the compel, the gang will catch up with you and take out the car without a Contest.

Max: You know what? I feel I am going to need all the Fate Points I can get during this scenario. I accept the compel and I’m eager to see what happens.

GM: The gang catches up to your car quickly and take it out with one of their grenade sticks. It rolls over multiple times. You crawl out of your car, while the ghosts in your head accuse you of not saving them.

George hands Tom a Fate Point. He now has four.

GM: The gang quickly surround you and your car, pointing their weapons at you. What do you do?

Max: I don’t think I will be able to defend myself and will let myself be taken prisoner. Let Charlie and Nick free me when they join us. After all, what’s better for bonding than that, right?

In a real game, I wouldn’t expect Tom to give up this easily. Especially with a fist full of Fate Points.

GM: You might be in for a surprise there. Anyway, the scavengers drag you out of your ruined car, tie you up behind one of their rides, load up the car and you are on your way to their home base.

After a long trek, partly running, partly being dragged behind their cars, you see your target looming on the horizon: A trio of rock spires rising from the desert. Welcome to The Citadel.

Scene 2: The Citadel

George writes “The Citadel” on an index card. Below it he notes: Twisty Tunnels. George’s Fate Points would reset, but since he didn’t use any in the last scene, and we still have only one player, it stays at 1.

Max: Isn’t the citadel one of the aspects of Charlie’s character? In that case I guess she will need quite some convincing to rescue me from her own people.

GM: Well spotted! In any case, you are led by the War Boys that captured you through a maze of tunnels to a small room. This is the first time you get a good look at them. They all look similar: in their teens or early twenties, pale white skin, and no body hair. Their eyes are painted dark, possibly with motor oil. They only wear trousers.

You are gagged and tied with some metal chains, held by a few of the War Boys. In fact, let’s make this an aspect, Gagged and Chained. They start cutting your hair, which is collected by a young, pre-teen War Boy. For what purpose, you don’t know.

A bearded man wearing some kind of of magnifying goggles approaches you, carrying what you recognize is a tattoo machine.

George pauses for a moment, giving Tom a chance to react. When he doesn’t, the GM continues:

GM: The man starts tattooing your back. You don’t know that now, but he tattoos your health status, including your blood group. “0-negative, universal donor”, it says.

One of the War Boys is holding a branding iron into a fire. It’s glowing hot red when he removes it and you recognize that it bears the logo of a skull in a steering wheel, crowned by fire. The seal of The Citadel.

Max: Okay, enough is enough! Cutting the hair, okay. I needed a hair cut anyway. The tattooing, I can live with. Tattoos are cool. But branding? That’s too much. I try to break my restraints. Forcefully, I guess.

GM: This will not be easy. Even if the War Boys have loosened their grip a bit, they still hold on fairly tight. I’d call that a difficulty of Great for the Overcome action.

Tom rolls and adds his Forceful of +2 for a total of 0. That’s not enough to beat a difficulty of Great (+4) by far. Tom hands George two of his Fate Tokens. He is already down to 2.

Max: I guess, I’m The Road Warrior. As such I’m not giving up without a fight. Also, as a Former Outback Cop, I know a thing or two about restraints.

George nods and takes the tokens. This brings Tom to a total of +4.

Max: A tie. I definitely want to succeed at a minor cost here. What do you say if we replace the aspect Gagged and Chained with a new aspect Chained Hands. I’m mostly free, but my hands are still bound.

GM: Sounds good. So, you jerk on your chains, loosening the grip of one of the War Boys. Hitting him in the face, you jump up. Your hands are still bound, but the War Boys gripping the restraints around your ankles have let go. What do you do?

Max: Fighting them seems like a losing proposition. I dive into one of the tunnels and try to make my escape.

GM: It sounds as if we have a contest at our hands. I can smell the food from the kitchen, so let’s just use two victories to keep this brief. The War Boys try to catch you again. I assume your goal is to escape?

Tom nods.

GM: I also think I need some stats for the War Boys now.

George takes another index card and writes “War Boys” on it. Below it he notes We serve Immortan Joe, “Skilled (+2) at: Athletics, Driving” and “Bad (-2) at: One-on-one combat”.

GM: You run blindly through a few winding passages. The tunnels are small with walls made from some kind of sandstone and pipes running along the ceiling. Finally you run into a room, where you see a familiar sight: a few mechanics are working on a car, but not any car: your car. The engine has been lifted from the bonnet, so it won’t drive anywhere soon. It also blocks your path. How to you tackle this obstacle?

Max: I jump and slide over the roof of the car. That’s using the Quick approach, I guess.

Tom rolls and adds his Quick of +3.

Max: That’s a total of +1. Let’s see how the War Boys are doing.

George rolls .

GM: Since they are skilled at Athletics, they get a bonus of +2, for a total of +3. Do you let them win the first round?

Max: We can’t have that. Let’s at least make it a tie. Of course Max knows his car well and this is not the first time he has jumped over it. I’ll invoke Max’s Last of the V8 Interceptors, for a total of +3.

Max hands George his penultimate Fate Token.

GM: You slide over the Interceptor’s roof quite elegantly, considering that you are handcuffed. The War Boys tumble over it much less elegantly, but are still hot on your tails.

But since we now have a tie, something unexpected happens. Let me think for a bit.

At that moment, the players hear a faucet being turned on in the kitchen. This gives George an idea. He writes The Floor is Water on an index card.

GM: You escape the workshop into another narrow passage. The passage opens up into a small room. Sunlight streams in through a grate in the ceiling, illuminating the room. You can see green plants outside, with a few vines dangling into the room. To your surprise, the floor consists of a basin that’s filled waist-high with water. Just as you hear the War Boys running behind you, you see more War Boys streaming into the room from the opposite side. What do you do?

Tom thinks for a moment.

Tom: I’ll grab the vines and try to climb up to the grate.

Tom rolls and adds +2 from his Forceful approach for a total of +3.

GM: You make it to the grate successfully and are now hanging on for dear life. The War Boys are frantically trying to grab you and pull you down again.

George rolls for a total of +2.

GM: I’ll invoke your Voices from the Past aspect for an additional +2. Suddenly, you have visions of a little girl asking “Max, is that you?” You are distracted for a moment and a War Boy manages to grab your leg. Do you have any responses?

Max: No, I’ll let them have this one.

George hands Tom his only Fate Point for the hostile invocation.

GM: Remember that you’ll only get this extra Fate Point in the next scene.

You can’t hold on and fall into the water. A short brawl ensues, but you again manage to escape the War Boys into another hallway.

The War Boys now have one victory and need only one more victory to win the contest.

Tom: I know.

George discards the index card with The Floor is Water written on it.

Tom: I keep on running as fast as I can, trying to ignore the voices that claim that I let them die.

GM: You run down the corridors, bursting through multiple doors, until you finally see a door through which you can see sunlight. But when you finally burst through it, you find yourself high up on a ledge, the ground far, far below you. You manage to stop just in time before going over it.

And this reveals another aspect of The Citadel.

George writes Towering Rock Spires on the “The Citadel” index card.

GM: You see no obvious way out. What do you do?

Tom: Well, since the Citadel is built on these towering rock spires that you just established, there must be a way to transport goods up here. In fact, there is this crane hook that I could just reach by jumping.

Tom hands George his last Fate Point for invoking the Towering Rock Spires aspect to establish an important fact in the world.

GM: Nice!

Tom: Considering the enemies are right behind me, I can’t back up and take a running start, so a Forceful jump it is.

Tom first rolls , bringing his total to 0, then he rolls his eyes.

Tom: Not great, but let’s see what the War Boys roll.

GM: The War Boys try to grab you as you jump to the hook.

George rolls for a total of +2.

GM: They roll enough. You make an impressive jump onto the hook and catch it with the chains around your wrist. One War Boy tries to jump after you and tumbles down the cliff. But the others are more cautious. As you swing back from the momentum, they grab you with hooks and sticks and pull you back into the passage. You are back in captivity.

As the scene ends, you can add the one Fate Point you gained through the hostile invocation to you pool.

Tom: Which bring my pool back to exactly one. Anyway, it sounds dinner is ready. I’m eager to eat and then to finally meet the other characters!

Categories
Python

python-dectest — Improved unittest.TestCase

I have released the first version of dectest for Python (Github), an improved version of unittest.TestCase. It is a drop-in replacement with two improvements:

  • decorators for tests, setup, and teardown methods. This is not only more explicit than the “magic” names of unittest, it also allows multiple setup and teardown methods per class.
  • patch() helper method that calls unittest.mock.patch(), but stops the patch during teardown.
Categories
Python

Python asserts and json-get with type hints

I released new versions of python-asserts  (0.8.2) and python-json-get (1.1.0) that include type hints, so that typecheckers like mypy will now be able to type check calls to those libraries. json-get uses asserts for its tests and it’s now possible to type check it without --ignore-missing-imports.

In addition, json-get now has a json_get_default() function that returns a default value instead of raising an exception if a path is not found.

Categories
Computing

Friendly Printers

At the offices of one of my customers, the printers are extra-friendly. Whenever I arrive or leave, they all greet me with a small concert.

I suspect that connecting or disconnecting USB devices from my laptop (such as the mouse dongle), CUPS is sending a broadcast over the network, querying printers of their status. This seems to wake up all Epson printers and force them to do a small self-check. This certainly needs more research.

Categories
Life

A Blast from the Past

I guess someone needs to update their download pages:

Categories
Databases Python

dbupgrade – A Database Migration Tool – published

Yesterday I published dbupgrade, a simple database migration tool, written in Python. It allows you to put database migration files (simple SQL files with a special header) into a directory and upgrade your database schema. While this is a new project, it was extracted from an internal library I’ve been using for years and should work fairly reliably for MySQL/MariaDB and Postgres databases.

dbupgrade is available at github and at pypi or via pip: pip install dbupgrade.

Categories
Software Development

Chipcard Woes

One of my customers, a large dental practice, had a problem from time to time when reading Krankenversicherungskarten (German health insurance card, KVK). The insurance number got all garbled up, which led to problems when reading the patient’s insurance data into the health care application. After their sysadmin and I analysed the situation it seemed that the application reading the data from the card and writing it to a file in a custom format was to blame. This program (KVKTool) was included with the Cherry card reader and had been modified by another consultant to write the read data to a file rather than displaying it on the screen.

This C++ program was a huge stinking pile. All card reading was done in a method called CKVKToolDlg::Onreadcard. The name CKVKToolDlg hints at it: This is the class responsible for showing the dialog. (Yes, it had been left in the program by the previous consultant. Only the dlg.DoModal() call had been commented out.) The method was a gigantic 837 lines long and features all kinds of goodies such as lots of copied-and-pasted code that had been modified in some instance to fix bugs, but not in others.

After a long refactoring session (which turned into a rewrite), I was able to spot the problem: a wrong workaround to bugs in a sizable amount of KVKs. Normally, the data on KVKs is structured into fields in an arbitrary order. These fields consist of a one-byte tag to identify the field, a one-byte length marker, and then n bytes of data, where nis the length. All KVK fields are identified by tags between 0x80 and 0x92. But all KVK fields are wrapped by a super-field called the “Versichten-Template” (insurant template, VT) with tag 0x60. Thus, data on a typical (non-buggy) KVK card would start like this:

0x60 0x89 0x85 0x09 0x53 0x65 0x62 0x61 …
VT tag VT len First name tag First name length Seba …

Now, buggy cards seem to insert a stray 0x81 byte after the 0x60 tag:

0x60 0x81 0x89 0x85 0x09 0x53 0x65 0x62 0x61 …
VT tag ??? VT len First name tag First name length Seba …

This code in the KVKTool was supposed to handle this problem:

// skip tag 60 and length
int i=2;

// some cards seem to have a damaged tag 0x89 after 0x81
if (responsearray[1] == 0x81)
    i++;

(Snipped the huge indentation.)

responsearray is a buffer that contains the KVK data and i is an index into that buffer. This code works fine in most circumstances. It works around cards with the stray byte. But there is one situation where it utterly fails: On correct cards where the Versichten-Template is exactly 129 bytes long. In this case, the first tag is skipped entirely, which usually is the insurant’s number. Since it was not, junk (random memory content) was written to the file in place of the insurant’s number. Not good, but hopefully fixed now.

Categories
Debian

VirtualBox on i386 with amd64 Kernel

I have recently started to use an amd64 kernel on my i386 Debian unstable system. Unfortunately, VirtualBox OSE does not work with that setup. When I try to start a virtual machine, it fails with an oblique error message:

RTR3Init failed with rc=-1912 (rc=-1912)

The VirtualBox kernel modules do not fit to this version of VirtualBox. The installation of VirtualBox was apparently not successful. Executing

‘/etc/init.d/vboxdrv setup’

should fix that problem. Make sure that you don’t mix the OSE version and the PUEL version of VirtualBox.

Debian bug #456391 explains the problem. In that report Michael Meskes alludes to running VirtualBox in an amd64 chroot jail, so I tried this myself. It works flawlessly, once I got it setup. Here is what I did (as root):

robinson:~# mkdir /srv/amd64
robinson:~# cdebootstrap --arch amd64 sid /srv/amd64 http://ftp.debian.org/debian/
[...]
robinson:~# chroot /srv/amd64
robinson:/# apt-get update
[...]
robinson:/# apt-get upgrade
[...]
robinson:/# apt-get install virtualbox-ose # add more packages here if needed
[...]
robinson:/# adduser --uid 1000 --no-create-home --disabled-password --disabled-login srittau
[...]
robinson:/# 

These commands install the base system and create a user account. Now I created a script called /usr/local/bin/amd64.sh:

#!/bin/sh

CHROOT=/srv/amd64

if test ! -e $CHROOT/dev/.udev; then
    mount -t none /dev $CHROOT/dev/ -o bind
fi
if test `ls $CHROOT/proc | wc -l` = "0"; then
    mount -t proc none $CHROOT/proc
fi
if test `ls $CHROOT/sys | wc -l` = "0"; then
    mount -t sysfs none $CHROOT/sys
fi
if test `ls $CHROOT/home | wc -l` = "0"; then
    mount --bind /home $CHROOT/home
fi
chroot $CHROOT sh -c "su - srittau"

Running sudo amd64.sh will now enter the chroot environment as user srittau where I can start virtualbox normally.

Categories
Life

Helmar Fanselau dies aged 56

I just learned that one of my former teacher, Helmar Fanselau, died on January 13th, aged 56. He was a strange man. Many students liked him because of his antics and strange sense for humor. Others did not like him for his harsh and unforgiving marks in his subjects, Latin and History. I think he was always fair, though, even if that worked to my disadvantage, because he actually liked me, but I got bad marks nevertheless. I still fondly remember him balancing rulers on his nose and for his ability to speak several different German dialects. His “weather show” featured them all in a stand-up comedy-like routine.

He always was a controversial person, though. I just found an article I wrote back in ’96 or ’97 about a school mess held by him during which the school parson actually put out the candles in protest.

There were always various rumours about Mr. Fanselau floating around in the school. For example, he was well known for eating from student’s lunch boxes. So, the story goes, a student prepared a special sandwich with tooth paste and put it on the teacher’s desk. Mr. Fanselau entered, saw the sandwich and ate it. When I questioned him about the story, Mr. Fanselau confirmed it, but was quick to add: “Well, I didn’t eat the whole sandwich.”

Finally, the way I found out about Mr. Fanselau’s death is as bizarre as was his personality: A rogue edit on Wikipedia. Goodbye, Helmar!

Categories
Games

Upper Deck Entertainment vs. Konami

This is my take on the conflict between Konami and Upper Deck Entertainment (UDE) that is currently upsetting the Yu-Gi-Oh! Trading Card Game community. While I don’t play Yu-Gi-Oh! myself, as a Magic: The Gathering judge I have a certain interest in what happens in the industry overall. Oh, and I like soap operas. All information presented is scrounged from various sources around the net, including press releases by the companies, statements from employees, and court documents (or copies thereof provided in forums). Mixed in is my own opinion and assumptions, so don’t take anything in this article for granted.

This is what I think happened so far:

Konami is the producer of the Yu-Gi-Oh! Trading Card Game and owner of the rights to it. Upper Deck Entertainment is the distributor of the game in Europe and the US. UDE also handled Organized Play (OP) for the game in these territories. The distribution contract ended at the end of 2007, but there was a mutual agreement (either verbal or in the form of a Letter of Intent) between both companies that the contract was to be renewed for 2008 through 2010. There was no formal contract, though, so the companies just kept on going. (And I thought those were serious businesses …)

UDE was unhappy with the way Konami handled the game and how they were supported by Konami. So they took more and more liberties with how they ran the game. This reached a climax when in the summer of 2008 UDE manufactured copies (or “counterfeits” as Konami calls them) of special Yu-Gi-Oh! promotional cards and provided them to Vintage Sports Cards, who packaged them with three boosters and sold those packs in Toys-R-Us stores. Konami found out about the counterfeits and sued Vintage Sports Cards. When they found out that UDE had provided the cards, they allegedly asked UDE for clarification. When were giving insufficient information and threatened Konami with a breach of contract suit, Konami amended their suit at the end of 2008 to include UDE as a defendant. But before they could do so, UDE counter-sued on December, 12th 2008.

This led to the well-known exchange of press releases. (December, 11th 2008, Konami: “We’re taking over the distribution of Yu-Gi-Oh!“; December, 16th 2008, UDE: “Not true!“; December, 17th 2008, Konami: Yes, true!) At December 22th UDE wins an injunction against Konami in Europe that voids the cancellation of the contract. And a few days later the same happens in the US.

So, this year both companies are flexing their muscles and the background of the story became known. The main lawsuits are still pending, so it will stay interesting. In the long term it’s obvious that UDE will lose any distribution rights to the Yu-Gi-Oh! TCG, so all their bets are now on various World of Warcraft products. I am not sure what that means for Upperdeck’s OP department. I know that I will keep a watchful eye on further developments.