sessions.all

Posted on Thu 21 May 2020 • Tagged with sessions

I’m rarely enthusiastic about long-term projects and so, when I dived head-first into the Sessions project for creating immersive interactive stories with some friends I was fire and flame but found it to be a a chore very soon, especially with all the reformatting and editing required to publish them on my blog.

When S asked me if we could revisit this system with more dedication and less pressure behind the both of us to continue all the time and perhaps less editing, I was interested. S asked me if I could reveal the mechanics I had used, given I had hidden stats, stat checks and most of the character sheet to force the player to be creative and rely on exploration instead of experience.

This post tries to explain the mechanics using snippets from sessions.KY and sessions.XN.

Basic Settings

At the beginning, I asked 3 questions and after receiving the answers, prompted for confirmation. Video game players are used to this - it’s basically choosing game modes, of a sort.

Choosing Difficulty

The first question I asked was the preferred level of difficulty.

Please choose your level of difficulty:

  • Take me for walk in the park
  • Give me a challenge
  • Grind my bones and drink my blood.

This choice defined two different parameters:

How peaceful I would write the setting. Are there conflicts in the world? Is it safe to walk outside during night-time? Are there guards patrolling? Things like crime rate and political climate were to be influenced by this.

How much the character would struggle. For a story to be interesting, the characters need to undergo hardships. Reading or playing a power fantasy is nice, but really engrossing stories take you through ups and downs on the journey. Things to be influenced were examples like presense of prejudice against the player, presense of a class-based society, relation of the player’s powers to the general level of strength or magic ability in the world as well as stat growth in relation to actual achieved success.

Choosing Absurdity

The second question I asked was the level of absurdity.

Please choose your level of absurdity:

  • This is pretty reasonable
  • WTF?
  • Maybe you should not have eaten those mushrooms

This choice defined how much I tried to stick to existing fantasy conventions and how much I was willing to bend rules of reality to make the fantasy setting convenient. Would there be machinery and magic in combination? Are there fantastic semi-human races? Would magical items and abilities be something common or rare? Would using said abilities have side-effects or would they be cost free? All these things defined the perceived power - but moreover they would hugely affect the believabilty of the story. Not every reader is able to deal with the same setting and maintain their suspension of disbelief.

Choosing a Gender

The last question influenced a very rudimentary part of how I’d approach the writing of the story - how other characters would perceive the player.

Is your persona:

  • A man
  • A woman
  • A person of mysterious and indistinct gender (Write my story so that it stays a mystery and NPCs are unsure)
  • Does it matter, really? I find it offensive you would even ask that. (Write the story so that it’s gender neutral and NPCs don’t care)

You might wonder, why ask this and is this inclusive? My answer is: It’s easier to tailor the reaction of the world’s characters to the player if you can establish some conventions of how different societies react to different genders.

Is it inclusive? Frankly, I don’t know. I tried to cater to someone who doesn’t want to say a man or a woman in two different ways and am absolutely open to suggestions in that regard - after all, sexuality is not in the questionaire.

The third choice was the choice for gender-neutral characters in Fallen London for a long time before the developers rewrote this part of the texts. However, part of the community really enjoyed being unidentifyable and it has been brought back.

Bonus: Scenario

During the second attempt at starting a session, I also gave the player the option to quick-start their adventure by giving me a scenario template. I tried this to offer the player the chance to pick their story setting in case they are fond of a special type of story.

Would you like to specify a theme or go with the narrator’s choice?
Standing on a grassland path with a large, ginormous city on the far horizon, but something feels wrong.

Confirmation

Lastly, I put the choices into a neat sentence, making for a one-liner representative of the chosen adventure.

sessions.KY:

Please confirm: You will awake as a man seeking a challenge in a world of unbelievable absurd wonders, magic and fantastical creatures.

sessions.XN:

Please confirm: You will awake as a man seeking a challenge in a mostly believable world who starts his adventure with a metropolis in sight and a feeling of uneasy in his heart.

Making this the final choice was done on purpose to give the game a feeling of “logging in” to the world. It is from this stated point that the adventure starts.

Gameplay Loop

From there on, I’d write a few sentences to establish the area, the people in it, objects of interest, locations and other details that are necessary to breath life into narration. There would likely also be a tiny bit of action going on, perhaps the player would spot a merchant passing by or some other thing of note would happen to catch the player’s interest.

They might also be confronted with a question, like how they feel, how they want to react, what they want to do or where they would like to travel.

All stories use “credits” as a unit for money. While this isn’t strictly speaking the best for immersion, it provides two things:

  1. The system will be consistent even if the narrator hosts several games.
  2. The system suggests that all rounds are instances of the same meta game.

Changes in location would be announced via special messages that could be interpreted as chapters or loading screens if the player felt like. I enjoyed adding those to stick closer to a video game concept.

You are now in Romanique, Outskirts.

Starting Gear

Every player would start out with one unique item that would be able to strongly define how their character interacted with the world. I would also always remind the player this is a game, even if it doesn’t feel so to the person they were playing, by attaching a very specific message to the item.

You did well in the last round, so here’s a little gift. ~ a friend

The effects of the item might be noticable immediately or the friend would provide additional guidance for how to use it.

In sessions.KY, said item was a business suit that completely circumvented all charisma checks and would make the player an expert at charming people. They would appear as an extremely charismatic person while wearing it, regardless of the player’s actual charisma.


while checking, you notice you are wearing a business suit

The guard seems overly friendly. When you reach into the pockets of your suit, you find a little card.
You did well in the last round, so here’s a little gift. Make sure it’s always well ironed and snazzy. ~ a friend
“You’re very much welcome. A pleasure to talk to you, sir”, the guardsman shouts after you as you leave.

In sessions.XN, said item was a book that converted memories into stat boosts. Writing about your adventure in the book would remove those memories from your mind but reward you with stat boosts that relate to the actual events experienced.

There’s a book lying next to you in the grass. It looks like it has been placed there very carefully.

There’s a dedication in the book.
You did well in the last round, so here’s a little gift. Make sure you fill it with notes of your adventures. ~ a friend

Aside from the dedication, the book is completely blank. Apart from the mysterious dedication at the start, the book is empty. Its pages are of great quality paper and the binding is beautiful mahogany coloured leather. It’s supposed to be tied shut by a leather string. There’s a linen bookmark with golden stitching on it, should you require it. The whole thing is likely handmade.

The ink dries instantly, something as simple as a name and a date looking like a work of art inside the gorgeous book. Something urges you to write more.

The book seems satisfied for now.

Lastly, in the unpublished sessions.SK, said item was a pair of glasses that was able to provide insight into the game world to a disturbingly deep level.

As you get up, you notice that the only thing that’s really clean on you is the pair of elegant reading glasses. A label is wrapped around one part of the frame. There seems to be some writing on it.

read the label
You did well in the last round, so here’s a little gift. Make sure it’s always clean. ~ a friend
The clocktower is clearly too far away, but as you look through your glasses, there’s tiny white writing on them, telling you the current time. It’s 11:35.

Maybe the glasses could help you again?
i put the glasses back on
Water contaminated. Infection chance: 2%

Character Stats

A player character had several stats whose initial values were hidden from the player but they could be guessed to a fairly precise amount by trying different things and reading my answers.

Stat checks required a certain level of a specific stat to be passed, where luck would always be factored into the decision. Additionally, based on a system I had seen in the Hand of Fate series of games, all success was further divided into “minor success” and “major success”.

A major success triggered if the stat check was in favor of the player by more than 5 points and resulted in an additional beneficial effect.

  • Starting values for stats are in the appendix
  • Action requirements are in the appendix

Please note that most of these stats were not designed up front but made up during writing and therefore do not represent a detailed sheet of an individual character (e.g. Dexterity might be a candidate to think about but did not come up in the stories written so far).

Fitness

Fitness determines endurance when running, general condition of the player’s body, ability to stay alert for a longer period of time and might influence more involved activities like parkour, climbing or physical and magical sparring.

Strength

Strength determines impact of strikes, force available during combat and ability to carry heavy items. I tried to apply this as literal as possible, with the value also affecting ability to wear heavy armor. Note that this explicitly did not affect carried inventory - my intention was to use actual bag sizes for this (e.g. a messenger bag).

Imagination

Magical capability is reprensented by this. It’s both a measure of how big a single feat one can achieve with their current abilties as well as how many tiny convenient spells one might be able to cast. Even a medium rating in this can be a great boon for a creative player.

Reaction

Reaction is as much about reflexes as it is about being quick-witted. Thwarting pick-pockets, weaving through traffic, dodging arrows and catching a ball are typical actions for which a reaction check would be used. It is not a 1:1 mapping of what Dexterity is often used for in systems like this one.

Charisma

Charisma is the ability to influence people and to passively make people like you. It’s applied when you first meet a new person and potentially on every significant conversation with them. It can determine how they think about you and how willing they are to help you, regardless of your previous actions towards them. It would also be used during attempts to seduce them.

Perception

Perception influences the ability to pick up cues in conversations, to see tiny details in scenes like a detective would, to memorize events in more greater clarity and generally see things that other people are too busy or pre-occupied to notice. It could influence a certain affinity for the occult.

Luck

Every stat check would factor in the character’s luck. The formula for using luck was: value(checked_stat) + random(0, luck). The result of this would be the success or failure of a stat check.

STATS: luck 2, strength 5, required_strength 7
CHECK: value(strength) + random(0, luck) >= required_strength

EXAMPLE: roll 2 => the condition is fulfilled
5 + 2 >= 7
RESULT: True

Percentage-based Checks

For percentage based checks, your luck will always be taken into account. Take the following example from the unpublished sessions.SK.

SCENARIO: Water contaminated. Infection chance 2%.

CHECK: random(0,100) + random(0, luck) >= 3
EXAMPLE: 86 + 2 >= 3
RESULT: True

Appendix A: Initial Stats

Please note that this is a summary of stats used so far and not a design for a complete system.

Stat Start value Notes
Charisma 5
Fitness 8
Imagination 4 First level will be gained during initial experimentation
Luck 2
Perception 5
Reaction ? This was determined based on the backstory of the character
Strength 5 Usage restricted until first use of Fitness

Appendix B: Skill Table

For the context of this section, “skill”, “spell class” and “ability” are equivalent. They represent a type of action, the requirement of which can be seen in the table. Sections labelled N/A were not investigated during sessions because pre-requisites had been deemed missing.

Skill Required Stat Value Unlockable via Notes
Charm average person Charisma 10 Base None
Conjure flame Imagination N/A Fire Creation None
Conjure iron item Imagination 50 Base None
Conjure wooden item Imagination 20 Base None
Decipher simple runes Imagination 2 Base None
Detect harmless deceit Perception 10 Base None
Detect life Imagination 5 Base Would scale up radius, additional findings
Detect low charm Perception 5 Base None
Detect white lie Perception 6 Base None
Determine water quality N/A N/A Survival Instincts None
Driving a motorcycle in heavy traffic Reaction 20 Story specific
Driving inside the city, medium traffic at night Reaction 26 Story specific daytime * 2
Driving inside the city, medium traffic Reaction 13 Story specific
Jogging Fitness 5 Base None
Manipulate air Imagination N/A Air manipulation None
Manipulate wooden item Imagination 15 Base None
Move tiny object Imagination N/A Telekinesis None
Read animal mind Imagination N/A Animal Empathy None

Improving Junit-style reporting in PHP CodeSniffer Pipelines

Posted on Sat 16 May 2020 • Tagged with Work, TimeTac

Recently I was shown that in a GitLab-based pipeline I had designed and implemented, the results were presented poorly. Here is an example of how this looked like.

# example output from failing pipeline

Running before_script and script
 $ mkdir -p test-reports
 $ phpcs --version
 PHP_CodeSniffer version 3.5.4 (stable) by Squiz (http://www.squiz.net)
 $ phpcs --basepath="$PWD" --parallel=$(nproc --all) --report=junit --report-file=test-reports/php-codesniffer.xml "$PWD"
 Time: 21.21 secs; Memory: 7.25MB
Running after_script
Uploading artifacts for failed job
 Uploading artifacts...
 test-reports/*.xml: found 1 matching files         
 [...]
 ERROR: Job failed: exit code 1

From this output, it was clear that the job failed, but there was no immediate hint why it failed. That’s because we were writing the report as XML to the specified file - and only there. Here’s how the pipeline definition for this step looked like.

# fragment from .gitlab-ci.yml

PHP Coding Standard:
  stage: fast checks
  image: timetac/ci:php5.6
  script:
    - mkdir -p test-reports
    - phpcs --version
    - phpcs
      --basepath="$PWD"
      --parallel=$(nproc --all)
      --report=junit
      --report-file=test-reports/php-codesniffer.xml "$PWD"
  artifacts:
    reports:
      junit: test-reports/*.xml
  tags:
    - docker
    - timetac

Improving Display of Details on stdout

After some research I found that phpcs, the tool we’re using to enforce our PHP coding standard is capable of generating multiple reports in one run. I slightly modified the pipeline instructions:

# changes to .gitlab-ci.yml

-      --report=junit
-      --report-file=test-reports/php-codesniffer.xml "$PWD"
+      --report-full
+      --report-junit=test-reports/php-codesniffer.xml "$PWD"

I instructed phpcs to generate both reports and then made the check fail on purpose to see example output:

# example output from pipeline with adjusted report display

Running before_script and script
 $ mkdir -p test-reports
 $ phpcs --version
 PHP_CodeSniffer version 3.5.4 (stable) by Squiz (http://www.squiz.net)
 $ phpcs --basepath="$PWD" --parallel=$(nproc --all) --report-full --report-junit=test-reports/php-codesniffer.xml "$PWD"
 FILE: cli-config.php
 ----------------------------------------------------------------------
 FOUND 1 ERROR AFFECTING 1 LINE
 ----------------------------------------------------------------------
  18 | ERROR | [x] Concat operator must not be surrounded by spaces
 ----------------------------------------------------------------------
 PHPCBF CAN FIX THE 1 MARKED SNIFF VIOLATIONS AUTOMATICALLY
 ----------------------------------------------------------------------
 Time: 14.85 secs; Memory: 7MB

While waiting for the results of this run, I made some screenshots how our development team can find the parsed Junit results in GitLab’s web interface. They are surfaced in the Tests tab of a Pipeline (in addition to being displayed directly in Merge Requests if you happen to use GitLab for both Continuous Integration and Development).

Screenshot of the Tests tab missing classname and barely readable test name

Improving Display of Results in GitLab

However, as evident in the screenshot, the results weren’t presented as nicely as they could be. This sent me quite far down the PHP rabbit hole. After some research I understood that the collected XML file was missing the classname attribute. I checked the issue link to see that GitLab instead of customizing their parsing fixed the issue upstream instead, which is commendable.

References:

Well, let’s also do that. On the other hand, who knows how long it takes for a PR to be accepted and merged? Perhaps a custom report is an option while I wait for upstream to accept possible contributions.

I pinged one of the developers of phpcs via Twitter and got a reply from a project contributor, that yes, it is possible to generate a custom report. This was not evident in its documentation. To use a custom report type, you need to ask for a relative path, an absolute path or a Fully Qualified Function (FQN) in the --report parameter.

Example:

# call to phpcs requesting a custom report type

phpcs \
  --basepath="$PWD" \
  --parallel=$(nproc --all) \
  --report="$HOME/Repositories/PHP_CodeSniffer/src/Reports/Junit.php" \
  --report-file=testreport.xml \
  "$PWD"

It is also possible to request this inside the .phpcs.xml configuration for your project.

<!-- fragment requesting a custom report of type "WPQA" -->

<arg name="report" value="WPQA"/>

References:

The next step in my adventure was to investigate how the Junit report was generated at the moment and hoping it can be understood easily. Simple enough, I found Junit.php which looked straightforward on the first glance.

On a more closer inspection I found some things I was dumbfounded by.

Making indention consistent

The first thing that struck me as odd was that in generateFileReport() the XML is produced by building it step by step via XMLWriter and its methods while in generate() the beginning of the document is written out via echo calls that contain the actual XML-formatted string. I initially investigated this because I was wondering why the final XML report uses correct indentation for the first elements and then seems off for the bulk of the file.

// original snippet generating report.xml

<?php // This opening tag is only for syntax highlighting with pygments
echo '<?xml version="1.0" encoding="UTF-8"?>'.PHP_EOL;
echo '<testsuites name="PHP_CodeSniffer '.Config::VERSION.'" errors="0" tests="'.$tests.'" failures="'.$failures.'">'.PHP_EOL;
echo $cachedData;
echo '</testsuites>'.PHP_EOL;
<!-- inconsistently indented fragment of report.xml -->

<?xml version="1.0" encoding="UTF-8"?>
<testsuites name="PHP_CodeSniffer 3.5.4" errors="0" tests="104" failures="1">
<testsuite name="tests/unit/MiscUtilTest.php" errors="0" tests="1" failures="0">
    <testcase name="tests/unit/MiscUtilTest.php"/>
</testsuite>

In trying to make this uniformly written using calls intended for writing XML, I learned that between XMLWriter, SimpleXML, XMLReader and DOM, it can be tricky to find the correct solution for your problem. In my specific case, the only solution that worked for accepting and later properly formatting partial, invalid XML fragments was DOM. However, this attempt at making the final result prettier comes with downsides in readability.

// new snippet generating report.xml

<?php // This opening tag is only for syntax highlighting with pygments
$dom = new \DOMDocument();
$dom->formatOutput       = true;
$dom->encoding           = "UTF-8";
$dom->preserveWhiteSpace = false;

$testsuites = $dom->createElement("testsuites");
$testsuites->setAttribute("name", 'PHP_CodeSniffer '.Config::VERSION);
$testsuites->setAttribute("errors", 0);
$testsuites->setAttribute("tests", $tests);
$testsuites->setAttribute("failures", $failures);

$fragment = $dom->createDocumentFragment();

/*
 * Using XML that is partially formatted in appendXML() results in
 * dom->formatOutput ignoring the fragment during formatting.
 */

$fragment->appendXML($cachedData);

$testsuites->appendChild($fragment);
$dom->appendChild($testsuites);

// Saving and loading the string forces pretty formatting.
$tmp = $dom->saveXML();
$dom->loadXML($tmp);
echo $dom->saveXML();
<!-- consistently indented fragment of report.xml -->

<?xml version="1.0" encoding="UTF-8"?>
<testsuites name="PHP_CodeSniffer 3.5.4" errors="0" tests="104" failures="1">
  <testsuite name="tests/unit/MiscUtilTest.php" errors="0" tests="1" failures="0">
    <testcase name="tests/unit/MiscUtilTest.php"/>
  </testsuite>

The upside of this approach was that I was able to keep generateFileReport() exactly as it is. Since I could not figure out what the point to having partial results as a string that differs for every report type is, I was happy to not have to change this function. A nice side effect of consistent indention is code folding working with more editors.

Implementing missing attributes

The second issue I was facing is that for GitLab to display the test results properly, several attributes were missing and some were formatted in a way that were less useful than they could be. Since GitLab are typically quite thorough at requiring tests for how their software should behave, it was helpful to look at the rspec for this behavior to find which XML attributes are supported.

References:

# snippet from GitLab's Junit rspec

expect(test_case.classname).to eq('Calculator')
expect(test_case.name).to eq('sumTest1')
expect(test_case.execution_time).to eq(0.01)
expect(test_case.status).to eq(status)
expect(test_case.system_output).to eq(output)

Given the above list, classname was missing. When checking the Junit fixtures found in GitLab’s code, it seemed file was also missing. I went to verify this theory by breaking some files in the scanned code base on purpose.

# call to phpcs after putting coding standard violations into 2 files

phpcs --basepath="$PWD" --parallel=$(nproc --all) --report-full "$PWD"
FILE: tests/unit/DeploymentCommandsTest.php
------------------------------------------------------------------------------
FOUND 2 ERRORS AFFECTING 1 LINE
------------------------------------------------------------------------------
 44 | ERROR | [x] Space after opening parenthesis of function call prohibited
 44 | ERROR | [x] Space after opening parenthesis of function call prohibited
------------------------------------------------------------------------------
PHPCBF CAN FIX THE 2 MARKED SNIFF VIOLATIONS AUTOMATICALLY
------------------------------------------------------------------------------


FILE: cli-config.php
------------------------------------------------------------------------------
FOUND 3 ERRORS AFFECTING 3 LINES
------------------------------------------------------------------------------
 18 | ERROR | [x] Concat operator must not be surrounded by spaces
 19 | ERROR | [x] Concat operator must not be surrounded by spaces
 77 | ERROR | [x] Space after opening parenthesis of function call prohibited
------------------------------------------------------------------------------
PHPCBF CAN FIX THE 3 MARKED SNIFF VIOLATIONS AUTOMATICALLY
------------------------------------------------------------------------------

The generated report.xml was missing the attributes that could make our lives easier.

<!-- fragment of report.xml after inserting coding standard violations -->

<?xml version="1.0" encoding="UTF-8"?>
<testsuites name="PHP_CodeSniffer 3.5.4" errors="0" tests="107" failures="5">
  <!-- ... -->
  <testsuite name="tests/unit/DeploymentCommandsTest.php" errors="0" tests="2" failures="2">
    <testcase name="PSR2.Methods.FunctionCallSignature.SpaceAfterOpenBracket at tests/unit/DeploymentCommandsTest.php (44:35)">
      <failure type="error" message="Space after opening parenthesis of function call prohibited"/>
    </testcase>
    <testcase name="PEAR.Functions.FunctionCallSignature.SpaceAfterOpenBracket at tests/unit/DeploymentCommandsTest.php (44:35)">
      <failure type="error" message="Space after opening parenthesis of function call prohibited"/>
    </testcase>
  <!-- ... -->
  <testsuite name="cli-config.php" errors="0" tests="3" failures="3">
    <testcase name="Squiz.Strings.ConcatenationSpacing.PaddingFound at cli-config.php (18:17)">
      <failure type="error" message="Concat operator must not be surrounded by spaces"/>
    </testcase>
    <testcase name="Squiz.Strings.ConcatenationSpacing.PaddingFound at cli-config.php (19:16)">
      <failure type="error" message="Concat operator must not be surrounded by spaces"/>
    </testcase>
    <testcase name="PSR2.Methods.FunctionCallSignature.SpaceAfterOpenBracket at cli-config.php (77:50)">
      <failure type="error" message="Space after opening parenthesis of function call prohibited"/>
    </testcase>
  </testsuite>

As expected, there was neither file nor classname. Furthermore, the line and column indicator should likely be moved to message in failure for easier remediation. Taking the first failure as an example, it should probably look like this:

<testcase name="PSR2.Methods.FunctionCallSignature.SpaceAfterOpenBracket" classname="DeployCommandsTest" file="tests/unit/DeploymentCommandsTest.php">
    <failure type="error" message="Space after opening parenthesis of function call prohibited (line 44, column 35)"/>
</testcase>

The next block is what the final XML structure looks like, after some iterations. I wanted to completely remove the line:column part from name but realized that some consumers of the report might not be able to cope well with testcase elements that have both the same classname and name. I used the Pull Request to eslint as template for how to implement the additional attributes.

<testcase classname="DeploymentCommandsTest" file="tests/unit/DeploymentCommandsTest.php" name="PSR2.Methods.FunctionCallSignature.SpaceAfterOpenBracket (44:35)">
  <failure type="error" message="Space after opening parenthesis of function call prohibited (line 44, column 35)"/>
</testcase>

Here’s what the difference looks like when viewed in GitLab. Screenshot of the Tests tab with classnames, almost readable test names as well as line and column numbers in the error message

Given that, I have adjusted Junit.php and sent a Pull Request to phpcs.

Make it work right now

While I wait for this part to be merged, I’ve manually patched it into the phpcs installation we use during testing by overwriting the file.

# fragment of .gitlab-ci.yml
  script:
    # manually copy custom report. It's not possible to print a custom report to a file
    # AND a builtin one to stdout in the same run.
    # remove after https://github.com/squizlabs/PHP_CodeSniffer/pull/2964 is released
    - cp resources/scripts/ci/Junit.php /opt/vendor/squizlabs/php_codesniffer/src/Reports/Junit.php
    - phpcs --version
    - phpcs
      --basepath="$PWD"
      --parallel=$(nproc --all)
      --report-full
      --report-junit=test-reports/php-codesniffer.xml "$PWD"

Dismantling a Leviathan is a series about improving tests and automated quality tools on a large existing codebase.


Improving Junit-style reporting in PHP CodeSniffer Pipelines is part 1 of Dismantling a Leviathan:

  1. Improving Junit-style reporting in PHP CodeSniffer Pipelines

Smalltalk with the Neighbours

Posted on Sun 10 May 2020 • Tagged with Graz

Today, a very large bug jumped in when I opened my right window. I was displeased and moved to the left window to have a conversation that I felt was long overdue.

Smaller Spider: The human is coming. Quick, look non-threatening!

Me: Yo, spider-san. We need to have a talk.
Large Spider: I can’t understand you very well, maybe open the window?
Me: Yeah, no, I’m not falling for that.
Spider: heh, worth a try.
Me: I thought we had an agreement?
The spider takes a long drag on its cigarette.
Spider: That agreement being?
Me: I leave you, your net and your coworkers in peace while you keep the bugs out.
Spider: Did we, huh?
The spider looks out towards the river.
Me: Pretty sure we did.
Spider: Listen, kid. You’re in no position to make demands here. I know you’re scared of me. Get lost.
Me: That may be so, spider-san. But I assure you that the vacuum cleaner is not scared of you.
Vacuum cleaner: Leave me out of this.
Me: Shut up or you go back to the dark closet immediately, without food.
The vacuum cleaner stares accusingly. It remains silent but I hear faint music from its earphones. The track is End of an Empire - Comaduster Remix. The vacuum cleaner often feels like it is subtle, but really, it’s not.
Spider: You just MURDERED one of my friends, Alex. I have seen it happening.
Me: Jep. Because they crossed the line. I have explicitly said on many occasions that entering the apartment is a death sentence for your kind. Hanging over my head while I was playing video games was a very bad move.
The spider takes another drag on its cigarette and is quiet for some time.
Spider: We’ll talk about this again, human.
Me: Say, where do you stay in winter?
Spider: Attic.
The spider responds too quickly for my taste but I don’t have any evidence of the opposite.
Me: Is that so?
All the spider does is wait in stony silence. I make a point of ignoring the spider outside the window and leave.


Smalltalk with the Neighbours is part 3 of From the inner city:

  1. The A1 Internet Odyssey
  2. Nighttime excursions
  3. Smalltalk with the Neighbours

sessions.XN 1

Posted on Sun 03 November 2019 • Tagged with sessions

Here’s the first session of my second player.


Please choose your level of difficulty:

  • Take me for walk in the park
  • Give me a challenge
  • Grind my bones and drink my blood.

Let’s start with a challenge.

Please choose your level of absurdity:

  • This is pretty reasonable
  • WTF?
  • Maybe you should not have eaten those mushrooms

What… How do you define “WTF” absurdity compared to “pretty reasonable”?

[silence]

Let’s keep it pretty reasonable.

Is your persona:

  • A man
  • A woman
  • A person of mysterious and indistinct gender (Write my story so that it stays a mystery and NPCs are unsure)
  • Does it matter, really? I find it offensive you would even ask that. (Write the story so that it’s gender neutral and NPCs don’t care)

A man

Would you like to specify a theme or go with the narrator’s choice?

Standing on a grassland path with a large, ginormous city on the far horizon, but something feels wrong.

Please confirm: You will awake as a man seeking a challenge in a mostly believable world who starts his adventure with a metropolis in sight and a feeling of uneasy in his heart.

Sounds good

You open your eyes and look straight ahead. You must’ve fallen asleep sitting against this medium size rock. Far on the horizon you can see Romanique, the city you have heard so many stories about. A city that never sleeps. A city in which all men and women are equal. A city like no other. A place of discoveries and innovation. Your clothes are slightly stained from the grass you are sitting in. There’s a book lying next to you in the grass. It looks like it has been placed there very carefully.

I pick up the book and open it slightly confused after just waking up.

There’s a dedication in the book.

You did well in the last round, so here’s a little gift. Make sure you fill it with notes of your adventures. ~ a friend

Strange. I look at it for a moment, flip through the other pages, then stuff the book in my backpack and get on my motorbike.

Aside from the dedication, the book is completely blank. You do not have a backpack, so you put the book into the tiny storage compartment of your motorbike - the one directly beneath the handlebar - and climb on.

Just big enough to fit the book in sideways, that’s convenient. Now I better put the pedal to the metal if I want to reach the security check by the evening.

You start the bike and drive towards the city. Maybe you should experiment a bit? What can you do? How fast does this go? After a moment you remember that the bike has a radio that transmits its music to the rider wirelessly.

I check my fuel gauge. It’s still 80% so I decide to swirl down this small path back onto the main road, and once there, I go as fast as I, can zooming past the other people - dangerously weaving in-between, hyped by the music to reach my goal.

The radio plays a mix of Stars and Flowers by Keiichi Okabe & Kuniyuki Takahashi.

Reaction check. required: 20. current: 47. luck: +0. major success. On the main road you are blazing ahead of everyone else, while some other drivers are giving you the finger. You arrive at your destination - city portal NNW - before it’s dark. You used 2% of the fuel.

Ooh, I better hurry inside, past the city portal.

Guardsmen at the city portal block your way and you slow down, reluctantly, and eventually stop. “Do you have anything to declare?”, the man wearing a red uniform asks you.

Nothing unusual, sir. A few books, a camera with accessories and some clothes. Oh, and a bike, sir, in case you hadn’t noticed.

“Surely you jest. Nobody here has seen a book for decades.” He shakes his head in disbelief. “Please stop wasting my time. You may pass.” The guards let you pass through the city portal. You are now in Romanique, Outskirts.

Hmm, I rush off and head straight for Crystal Beach on the far end of the city. Underway to there I’m still thinking about what that guard said. “Nobody has seen a book? Surely he must be joking right? What the hell was he thinking, my home is filled with books from wall to wall, after all my wife loved only two things in life, the sunset at the beach and her job as a librarian.”

Reaction check. required: 13. current: 47. luck: +2. major success. You arrive at the beach just in time to admire the sunset after parking the bike without any traffic incidents. You are now in Romanique, Crystal Beach.

I pull my camera out, put the stand down in the beautiful shimmering sand and dial down the exposure. Snap. I look at it. “That’s one of the most gorgeous views I’ve ever seen, damn it was really worth coming out here during spring, and I even managed to snap the picture today. I was sure it would take me at least another week.” I start laughing out loud staring at the picture on the display, and eventually sit down in the sand to enjoy the last rays of sunlight sinking down.

“Wanna buy some walnuts? Almonds? Cashews? Got all the nutty things you can imagine, lad. Bottled water too.”, a big man pushing a ridiculously colorful cart in front of him yells. You are startled. Romanced by the view you were close to drifting off again - something that happens often lately.

Ooh, how much are the walnuts, sir?

“20 credits. no discounts.”

Hey, that’s quite cheap, sure. Give me that bag in the corner there.

You pay the man, receive your snack and watch him push his cart off.

After eating most of the walnuts, I close the bag and put it in my pocket, heading back to my bike.

You’re tackled from the back by a child. Reaction check. required: 35. current: 47. luck: +1. major success. You catch the tiny criminal that was about to nab your nuts and your purse.

“Bwahaha, want a walnut kid? Don’t try to steal my purse while you’re at it though, this evening is too beautiful for that.” And with that I toss him the bag, I wasn’t going to finish it anyways.

The kid stares at you in disbelief for a moment and then scuttles off, his reptilian tail flying as he hurries out of sight. It’s getting dark.

I watch him run out of sight, then walk the last few paces back to my bike, unlock it from the lamppost I chained it to just as the light flickers on.. Guess i should go looking for a place to spend the night. And with that i head into the city.

You head into the city. Reaction check. required: 26. current: 47. luck: +2. major success. You arrive in the city center, near the University Grande Halle, the Recipio Grande Halle and stop on Grande Halle Patio to consider your next actions. You arrive there speedily, using barely any fuel and with little difficulties despite the sun having set. Of course, the street lights help. You are now in Romanique, Center.

I’ll look around for a nice place to stay in, on the slightly more expensive side with promises of a good breakfast. Credits aren’t too big of a deal since I’ve been saving over a decade for this adventure anyways.

There’s a good hotel a few hundred meters down the road. There’s also a decadently expensive place you passed on the way here.

I’ll drive to the good hotel, park and lock up and go inside.

A woman standing at the reception who was looking at the back panel with the keys on a wall turns her owl head almost 180° to look a you. “Welcome to Eden Center, dear guest. Do you have a reservation?”

“No, i was looking if i could still get a room until the end of the week, with breakfast included.”

She turns around to face you properly. “Give me a moment to check.” She types a few keys on her computer and adjusts her glasses. “I don’t think we have…” Charisma check. required: 10. current: 5. luck: +1. failed. “…no, really, there’s no empty room for you, but maybe there might be something we can do about that if you’re really in a pinch. Otherwise I’m extremely sorry to have to refer you to another hotel.”

“Oh that’s fine, got any recommendations for hotels around the area miss?”

“Well, there’s the Nightingale Inn, that’s about 1 km towards the Crystal Beach. There’s also the motel a few blocks away. And of course, there’s the Grande Halle Palace but you don’t strike me as the type to waste your money on extravagance.” Perception check. required: 5. current: 5. luck: 0. minor success. You don’t like the emphasis she places on the motel. It’s getting very late. You should rest soon.

“Aah, thanks then I’ll go and check with the Nightingale Inn, good evening… eeh.. night.” I travel to the Nightingale Inn.

The clerk at the Nightingale Inn barely looks up from the video game he’s engrossed in.

“Hello! Sorry to ask so late but do you have any free rooms left?”

The clerk grumbles “Reservation?” but it is barely understandable.

“I eeh, no I don’t have a reservation.”

The clerk sighs and unwillingly puts his game away to check the computer for open spots. He replies: “We still … room, yes. How long… intend to stay?”. Perception check. required: 6. current: 5. luck: +1. minor success. He’s mumbling because he’s hiding something in his mouth.

“4 nights if possible please”. I smile.

“… credits. cash. up front.” You don’t understand the actual amount, only that it starts with “3”.

“I’m sorry, can you repeat that?” In the meantime I get my actual wallet out from the inner pocket of my jacket and check how much cash I have.

The clerk rolls his eyes and speaks again, just a hint more clearly this time. “3200 credits.” When you fiddle with your jacket he notices the stitched part of it where you had the logo removed. He eyes you suspiciously. “…you trouble?”

“Nah mate, that was a mistake from a long time ago, as long as I get a nice breakfast in the morning you won’t have trouble with me. I laugh.

“…not be trouble. Owner said make trouble disappear.” This time he spoke clearly on purpose. Perception check. required: 10. current: 5. luck: 0. failed. But you could not make out what he’s hiding in his mouth. What he said was not exactly a subtle threat. He puts a small input terminal for you to fill the form on the counter. You are starting to lose his interest.

I quickly fill it in reassuring him I’m fine, and pay.

He hands you a key with the number 5 on its keyring and goes back to his video game. Looks like you’ll have to find the room yourself. There’s a hallway and there are spiral stairs.

Well it’s just number 5 right? It can’t be that far I walk down the hallway.

The hallway ends in a dining room. Everything is neatly arranged for the next morning already.

Whoops, at least I already found where the dining room is, better go check upstairs for number 5. I head upstairs to the first floor, looking around.

Upstairs you immediately find number 5 as it’s the door that’s visible at the end of the corridor from the stairs. You unlock the door and enter. It smells a bit of cleaning solution. Everything is very clean and again, the items are neatly arranged. There’s a white gift box with a golden ribbon around it on the bed.

I unpack my stuff and then look inside the white box.

There’s an elegant wooden pen in it and a card. The card says

I thought you might end up here eventually. This will make your beginning a bit easier. ~ a friend

What the heck, this is getting creepy. Oh well at least I don’t have to worry about how I’m gonna write in the book anymore. With that thought, I grab the book, sit down in a chair and flick through it looking at it and the pen in detail.

Apart from the mysterious dedication at the start, the book is empty. Its pages are of great quality paper and the binding is beautiful mahogany coloured leather. It’s supposed to be tied shut by a leather string. There’s a linen bookmark with golden stitching on it, should you require it. The whole thing is likely handmade.

I take the pen and try writing in it, just a small footnote with my name and the date to see how it writes.

The ink dries instantly, something as simple as a name and a date looking like a work of art inside the gorgeous book. Something urges you to write more.

I’ll write a few paragraphs about my journey so far, the names of the few beaches so far, and the Crystal Beach from today. After that i put the book away, and walk up to the mirror in the bathroom, inspecting myself to check that I don’t look filthy or anything, and practice having a conversation with myself in the mirror for a bit, before taking a shower.

The book seems satisfied for now. The mirror politely asks you not to over-exaggerate your mimics while you’re trying to convince someone you’re an honest person and respectfully suggests taking a shower.

You’re all clean after your shower. It’s the dead of the night.

Happy with everything I got done today I head to bed, but first I make sure to put the book in my bag on the chair, far away from my bed.


sessions.KY 1

Posted on Sun 27 October 2019 • Tagged with sessions

Lately I’ve been thinking about holding some ad-hoc role playing sessions again and this was an attempt to get the thought going. Quite some concepts are rather unrefined at this point and I’ll continue to make things up as I go. However, some mechanics have already started to form and work fairly well.

In this I try to encourage some experimentation by having the player start with nearly no resources and no prior knowledge about the world or its inhabitants. They are not familiar with its systems and moreover, they are not aware of what actions they can perform or how their body reacts at the start. Players are expected to keep their own characters sheets in order to keep tabs on what is achievable for them as I am thinking about implementing negative consequences. For example, in this session, a Google Sheet was used.


Please choose your level of difficulty:

  • Take me for walk in the park
  • Give me a challenge
  • Grind my bones and drink my blood.

2

Please choose your level of absurdity:

  • This is pretty reasonable
  • WTF?
  • Maybe you should not have eaten those mushrooms

3

Is your persona:

  • A man
  • A woman
  • A person of mysterious and indistinct gender (Write my story so that it stays a mystery and NPCs are unsure)
  • Does it matter, really? I find it offensive you would even ask that. (Write the story so that it’s gender neutral and NPCs don’t care)

1

Please confirm: You will awake as a man seeking a challenge in a world of unbelievable absurd wonders, magic and fantastical creatures.

Yes

“Sir? Sir? Please wake up, you cannot sleep in Lord Melisano’s gardens. I must ask you to leave”, the guardsman tells you. You sleepily open your eyes and notice you have been dozing on a perfectly groomed lawn under an equally perfectly cut apple tree. In a slight distance you see a fence. You feel a bit uncomfortable in your clothes and while checking, you notice you are wearing a business suit.

What’s your reaction?

I blink and look up at the guard. “I’m sorry, I was so tired I just… dozed off.” Wondering how I ended up here I get up, looking around briefly. Figuring it’s probably a dream I ponder what to do. He asked me to leave, I probably should. “I apologize once more. This should not have happened. I will take my leave now.” I head toward the fence, figuring that’s probably the way out of the gardens.

The guard sighs and answers “Yeah, I know the feeling of being dead tired. I can relate. Sir, I will escort you to the front gate. Please make sure Lord Melisano never hears of you entering his property without permission.” He steps into your way and gentle nudges you into the other direction from where you were heading. The guard seems overly friendly. When you reach into the pockets of your suit, you find a little card.

You did well in the last round, so here’s a little gift. Make sure it’s always well ironed and snazzy. ~ a friend

It would probably be wise to follow the guardsman. But maybe you have other intentions?

I nod politely at the guardsman and follow him to the front gate. The card I put back into my pocket. “Thank you,” I say to the guard as I pass him at the front gate. Once outside of Lord Melisano’s gardens I take a look around to see where I can go from the gate.

“You’re very much welcome. A pleasure to talk to you, sir”, the guardsman shouts after you as you leave. There’s a signpost at the fork of the road. One direction says “harbor”, the other “botanical library”. In the distance you can spot a tower. Everything else is either hilly farm land or lush forest. From what you remember from botany and geography, you’re likely in temperate climate.

“Have a good day!” I start heading toward the botanical library. As I walk down the road headed there I take the card out again and flip it over to see if there’s anything else on there. If not, I put it back in my pocket. During my walk to the library I subtly check out how my body functions. I tense some of my muscles to get a sense of what I’m capable of doing. Weird dream this. It feels so real… Hmm, if it’s a lucid one I should be able to… I hold my hand in front of me and try will a sword into existence.

The card has the format of a business card but there are no logos on it, and neither is a company name. The elaborate design involving black, sweeping lines along the borders of the card as well as the quality of the paper suggest it is expensive.

Your muscles… Strength check. current: 2, required: 5, luck: +2. failed. …hurt. They feel like the haven’t been used in ages. You try to conjure up a sword. Imagination check. current:4, required: 50, luck: +1. failed. It’s not working. You can feel you’re on the right path, but maybe you require instructions?

You hear a faint voice chuckling.

I come to a stop and turn my head in the direction the sound came from, a slight frown on my brow. “Hmm?”

Nobody is there.

“Who’ s there?” I call out, looking around more carefully.

Even upon closer inspection, careful observation of the nothing, thoughts about nihilism and intense deliberation of the nothingness, the void and its meaning, in the end it is still nothing. Nobody is there.

You gain Imagination +1.

I ponder the situation a bit longer, but then decide to move on. As I continue walking I try my hand at various other things: conjure up a small knife instead, create a flame in my hand, stare at a bird and try to read its mind, push a pebble away with my mind, and focus on ‘feeling’ the area around me to see if I am capable of perceiving more than my normal senses.

  • You try to conjure up a knife. Imagination check. current:5, required: 50, luck: +0. failed. Nothing happens.
  • You try to create a flame. Required ability not learned. Nothing happens.
  • You try to read the bird’s mind. Required ability not learned. Nothing happens.
  • You try to push a pebble with your mind. Required ability not learned. Nothing happens.
  • You try to focus on feeling your surrounding area. Imagination check. current: 5, required: 5, luck: +1. minor success. You can sense that there are living beings nearby. You do not know how many, what kind or how far away they are.

Okay, so that’s at least something I can do… I look around for a place where I can sit down for a moment. Something like a bench or a log maybe.

There are no logs or benches on the long paths through the grain fields. You find a medium sized rock though, that will do in a pinch. You sit down. You nod. Good rock. Maybe you should try rolling it.

Before doing rock (‘n) rolling I sit down on the rock and once more try my hand at conjuring something, figuring conjuring up something that isn’t a weapon might be easier. Okay… something easy and small… With nothing else coming to mind I try to conjure up a toothpick.

You try to conjure a toothpick. Imagination check. current:5, required:20, luck:+2. failed. Nothing happens.

It feels like the toothpick is not as far out of reach as the sword or knife, but still well above what I’m capable of right now, and so I give up on conjuring right now. I look around and pick up a small twig I see lying around. Focusing my thoughts I try to bend it with my mind and turn it into a round shape.

You try to manipulate the twig. Imagination check. current:5, required:15, luck:0. failed. Nothing happens. You notice a difference in difficulty despite the failed attempt.

I place the twig on the ground in front of me. Moving the pebble had not worked, but I now try to move the air surrounding the twig and push it that way.

You try to move air. Required ability not learned. Nothing happens.

Okay, let’s focus on the single thing that actually did work. I close my eyes and focus on feeling the life around me, both plants and animals. After a while I try to shift my focus on specific life forms, if I’m able to pick out anything. If I’m not able to pick out anything with my eyes closed I’ll open my eyes and try to find something, on which I will then focus the ability to sense its life force.

You don’t see anything moving around you apart from the grain gently swaying in the wind. There’s a cool breeze. Your suit is not made for harsh weather. At this point you’re not sure what you feel, aside from something alive being there.

I get up from the rock and get moving again, toward the botanical library I was originally headed for.

You walk the road for a while. After an hour or so, you come to another fork in the road. One path goes to the library. The sign for the other path is completely faded from wear. Someone has hung a nice black leather messenger bag on the signpost. The wind is cooling down. The sun will likely set soon.

I look down the road where the faded sign’s pointing, to see if there’s a building within view. I then try to get a sneak peek of what’s inside the messenger bag.

You spot ruins of what might’ve been an outpost made of big stone blocks long ago in the past. The messenger bag contains a neatly wrapped bread, a piece of hard cheese, a full flagon and another card.

I thought you might venture into this direction. This will make your beginning a bit easier. You’re welcome to keep the bag as well. ~ a friend

I take the messenger bag and break off some of the bread, which I start eating. Library isn’t gonna be open at night, I guess. Need a place to sleep… Let’s check out those ruins. I head over to the ruins and check those out from up close, trying to work out if I could use the ruins as shelter for the night.

The ruins are nothing more than some remainders of walls. Relics of once great buildings, now just crumbled remains. There’s the occasional stone arch, but nothing in the vicinity looks like it could provider shelter in case of rain or wind. As you inspect the ruins closer, you find withered writing on the wall. Symbols are engraved on the arch. And if your mind isn’t tricking you… Imagination check. current:5, required:2, luck:0. minor success. which it isn’t, then the ruins are a perfect triangle when seen from the sky.

I give the ruins a thumb-up, then turn around and head toward the library after all. Nowhere else to go, I suppose. While walking some more bread is consumed, as well as some cheese. I take some sips from the flagon to taste what’s inside.

The flagon is filled with nicely chilled chocolate milk. After some more time of walking, you can spot a building far off. Even though its green walls make it a bit harder to spot in this light, especially amidst the trees surrounding it, the place must be massive in size.

When I feel like I’ve had a decent fill I put everything away in the bag. The moment I see the building I start an easy paced jog toward it, keeping the messenger bag tightly against my body by lifting it a little with one arm. As soon as I start to feel somewhat tired or sweaty I will resume moving toward the library at a walking pace.

Fitness check. current:8, required:5, luck:+2. major success. You arrive at the library speedily, without breaking any sweat. Your suit pants suffer further wear from the earthy ground. Your run left you feeling great and your muscles are starting to come back to life.

Strength restriction lifted, value restored to original value: 5

As I arrive I head straight over to the door and see if the place is still open. If it is, I enter.

You arrive at an elaborate wrought iron fence. There is no guard at the open portal, so you simply pass through. There is also nobody guarding the large wooden gate, but that is closed. Light can be seen through the windows and underneath the door. The wooden gate is locked and doesn’t move an inch when you try pulling and pushing.

I knock on the gate and call out: “Hello?”

A sleepy girl in her teens sticks her blond head out of the slightly opened gate. “Who’s there?” She has a half circle in blue tattooed around one of her eyes. You might’ve woken her.

“I’m terribly sorry for waking you up, but I am without a place to spend the night.” I make an apologetic expression. “I was hoping to find one. Do you happen to know where I could go?”

She looks you up (to your apologetic expression) and down (to your dirty clothes and shoes). Charisma check. circumvented. “Good sir, please wait for a moment while I wake a librarian. I’m sure we’ll find you a place to stay. It’d be a pleasure, in fact.”

I nod understandingly as I smile softly. “Will do. My apologies for the inconvenience.”

After a few minutes (which most certainly feel like an eternity. or two) the door opens. The girl is clad in a grey robe and so is the middle-aged woman next to her. She, too, is wearing the same tattoo on her face. Her robe has additional silver decorations at the end of her sleeves, perhaps to signify her importance. A book is embroidered on the robe just where her heart would be. “Greetings. I hear you require shelter?”

“That I do,” I reply while giving the older woman an apologetic smile as well. “My sincere apologies for the inconvenient time at which I show up at your doorstep.”

The older woman looks at your apologetic smile. Charisma check. circumvented. “No, good, sir, it’s no matter. You’re welcome as a guest in the Botanical Library. Please, follow me, we’ll find you a chamber. I cannot promise that it will be the finest we have - you might have to make do with a room in the acolytes’ wing. It will most definitely be more comfortably than sleeping outside though.” She gives you a warm smile and leads the way.

The teen stays behind at the door. You take the opportunity to check out your surroundings while you walk. It is indeed a Botanical Library. In the most literal sense of the term. There are both bookshelves as well as planters everywhere you look, even in the walkways connecting different buildings inside the complex.

My own smile brightens a bit as the woman returns it warmly. “Thank you, miss. I am very grateful for that.” I follow the woman to the room where I’m allowed to spend the night, checking out the various sections of the library we pass while keeping an eye open for things that might be of interest to me. Maybe there’s a section that can help me with this magic thing… Or to help me figure out where I actually am… The latter’s probably more important right now given I need to be able to get around in this world, find an actual place to stay long term. This place is bound to have info about the local area.

Despite trying your best, you cannot figure out how the books are ordered and what kind of knowledge is available.

The room is plain. There is a bed, a desk, a chair and a commode. There’s also a chest. No, not a treasure chest. The desk has some ink stains, so clearly has seen use recently. Of course, there’s also a stack of books. It’s propped on the windowsill.

“Thank you,” I say as I put my messenger bag down next to the bed, “and once more, my apologies for the inconvenient time at which I arrived.” “If I need a toilet, where can I find one?” I ask before the woman leaves. Once she’s gone I check out the books on the windowsill out of a sense of curiosity.


Grazer Linuxtage 2019

Posted on Sat 13 July 2019 • Tagged with Work, Graz, Timetac

This post is late, but I’m going through my backlog and trying to get some things out, so that’s that. Furthermore it is potentially inaccurate given that I cannot find my notes form the event.

First, I need to apologize. I mistakenly assumed that one of the key people involved in the Grazer Linuxtage who’s working for the FH Joanneum, its previous location, was leaving. I arrived at that conclusion by the fact that the Linuxtage changed their location from the FH to the Technical University Graz as well as a job posting for the same position the person is working in. So that’s that. I was wrong. Linuxtage changed location due to space constraints. The community had simply grown beyond the space the FH could easily provide.

For me, 2019 was the first year in which I joined both days of the conference in April: Friday for the workshops and Saturday for the talks. It was both interesting and exhausting. In my case, exhausting enough that I didn’t want to attend another event several days long just the weekend after - so I ended up not attending PyDays in Vienna despite my original plans to do so. I’m sure my friend D was a bit disappointed I didn’t attend his talk there.

Friday

On Friday I worked on various projects until about noon when I had planned to leave with G for the Linuxtage. However, him being stuck in a never-ending meeting meant I was going alone after all. Unfortunately that meant that I was also late due to waiting a little longer and in consequence the allotted time for lunch was gone.

Automate server configuration with Ansible

I arrived at the TU Graz after a few minutes and went straight to the first workshop - Automate server configuration with Ansible by Vid Jelen. This was the talk I wish I had had before I was thrown into learning the concepts of Ansible with an existing, complex codebase provided by a partner company of Timetac. It went over the basics really well and the presenter was prepared, handing out USB drives with example code snippets and tasks for the participants. I would’ve liked him to also host those in a public repository so I would not have to plug an untrusted device into my company machine. This resulted in me taking a lot of notes instead of working along, which was fine as well. Notes, which I might add I can no longer find.

Overall the workshop was very informative and showed me some things that I had overlooked by jumping into the deep end. I think I took some notes here about little tricks that I wanted to incorporate into the codebase at work, but alas, without my notes that’s going to be a bit hard.

Funnily enough my successor from ICG at TU Graz joined the same talk. I think that’s a good sign that we made the right choice given M showed interest in educating himself past the required tasks.

Beginner Introduction to Python Unit Testing - Write your first test!

One area in DevOps I’m personally interested in is automated testing. I have written both unit tests and integration tests for several projects now and am always curious about how to better structure my tests. This second workshop was therefore a good choice to expand my knowledge. Beginner Introduction to Python Unit Testing - Write your first test! by Peter Kofler was a good introduction to unit testing in general but I underestimated my experience in the field and was not challenged, blazing through most of the tasks due to them being structured fairly simple. I should’ve listened to G who pointed out that this might be the case.

I have to further point out that in contrast to the presenter, I personally prefer pytest as a testing framework and test runner when working with Python due to how they make writing tests extremely easy using assert statements.

Saturday

Saturday focuses on talks and lectures instead of workshops and typically has a lot more on the schedule in many different tracks. The intended audience of these reaches from linux hobbyist to system administrator and back.

I happened to meet a few acquaintances as I do every year at Linuxtage, simply because there are some local Linux veterans that will not miss these meetings. I mostly know these through my previous work at the TU Graz. I typically end up chatting with them for quite some time and end up not attending at least one talk.

WSL, PowerShell & Chocolatey: Ein Hauch von Linux

I started the day with WSL, PowerShell & Chocolatey: Ein Hauch von Linux by Manfred Wallner, whom I know from university. I occasionally have to work with some Windows machines at work, so chocolatey to achieve some level of sanity while installing software is as essential as the homebrew project on macOS. I am still not convinced that I would want to use PowerShell over Python for writing scripts. Manfred’s argument was for PowerShell over Bash, but I already avoid writing anything longer than five lines in Bash if possible.

Windows Subsystem for Linux will be even more essential in the future for my work, when Docker Desktop switches from Hyper-V to WSL2 for their Windows support.

Best Practices in der IT-Administration, Version 2019

Sometimes, you have these rare moments in which you get confirmation that many of your ideas and principles are correct, state of the art and best practise. For me, that was Best Practices in der IT-Administration, Version 2019 by Michael Prokop. He went over a checklist of things you should be asking your IT department to see if your business is prepared for the worst. Backups, Configuration Management and keeping detailed logs (not log files, but rather per customer journals) were only some points of his list for how modern IT administration should work. I admire the consideration and preparation as well as years of experience that went into compiling these principles.

Container - Alles sicher oder was?

Container - Alles sicher oder was? by Michael Maurer was supposed to give you a more detailed insight into how containers and their security can affect your deployment. In reality, the talk wasn’t terribly helpful - it mainly pointed out the usage of SAST and DAST tools to run against containers. When pressed, the presenter said that their workplace uses no such tools which undermined their entire point.

Now, while I don’t like pointing fingers, after 2018, this was the second year in which I attended presentations given by employees of Netconomy, a local shop from Graz. Of the two talks and one workshop I’ve been to, both talks were… not good. Frankly, having had a job interview at their place I don’t understand why. I’ve talked to these guys and they really seem to know what they are doing. Their presentations on Linuxtage 2018 and 2019 were completely superficial and provided little more help than “you might want to do X” instead of giving insight how security can be affected by essential things like monitoring, alerting, automated scanning and much more. Either they have strong restrictions on what they are allowed to show off at events or they need to prepare their topics for another audience - namely tech workers already familiar with the ideas they are presenting.

To end on a good note, the workshop done by their WebOps person (see the corresponding section on Friday) was awesome and I’d happily go to another presentation given by him!

Terraform - Ein Einblick der Möglichkeiten von Infrastructure-as-a-Code

In Terraform - Ein Einblick der Möglichkeiten von Infrastructure-as-a-Code by Dr. Sebastian Oehlke tried to show the participants how some experiments using Terraform as infrastructure as code tool could look like. He acknowledged that his examples weren’t taken from reality and walked us through the setups of several example networks. Personally, I don’t see the appeal of the tool given that Ansible modules for the same tasks exist and Ansible is generally the tool which can solve more problems due to its versatility. The presenter argued for better visibility of the changes and initial state than with Ansible.

Next Level Ansible

Next Level Ansible by Manuel Bonk was the logical followup to the Ansible workshop on the first day and I remember taking quite some notes during this talk. Specifically I wanted to look into Ansible’s support of Junit as well as the serial option for doing slower host-by-host deployments. Giving this talk a good structure was hard due to its nature as collection of various bits and general hints, and it showed. The content itself was well prepared - it was mainly the thread holding the topics together that wasn’t always there.

The talk also went over ansible-vault and Jinja2 templates, both of which are in use at Timetac.


Scenes of music: Fable 2 music box

Posted on Sat 13 April 2019 • Tagged with Scenes of music

Song: Fable 2 Music Box (this links loops, the theme itself is very short)

Now, I picture you. Going into the attic and looking for a huge, immensely dusty suitcase, or rather a treasure chest with several locks on them. It also has a sign on it, neatly made but with a text akin to “If you’re not Sara, don’t even bother. The locks are magically enhanced”. Then you gently wipe away a layer of dust and pat the chest. So many memories in there. You’re slightly unsure if you should even open it.

First you open the outermost lock. That one is fairly simple and somewhat high-tech. It’s unlocked by your fingerprint.
The second lock is a bit more involved. You take the standard, comparatively boring key from your every day keychain and unlock it.
The third lock is a striking crimson and so magical, it has comedic value. You prick yourself in the finger with a needle in order to drop a single droplet of blood on it.
The fourth lock is unlocked with a teeny-tiny key that you keep on your bracelet. Even if the keychain is lost, the bracelet never leaves your arm.
The last lock is special. It’s not actually visible, but the chest won’t open if you don’t unlock it. You focus, smile and think, yes, you are sure you want to access the memories.

The chest opens. More dust is spreading and you hear a slight squeak from the gears that have become just a tad rusty. And then, the memories flood back. A slight golden shine comes out of the box and the impossibly romantic sound of a musical box is playing.


I wrote this for a friend on a whim while chatting. I picked the music to the scene this time instead of the other way around since she inquired what music the music box would be playing.


I enjoy Cooking with Friends. Truly.

Posted on Sat 13 April 2019 • Tagged with Memories

Yesterday has seen the 10th episode of Cooking with Friends. It was an event I’m proud to have held. With me were L, a first timer here at Cooking with Friends, and W, a seasoned veteran of culinary delights. Both assured me they had a great evening and the food which we prepared together was awesome. For this occasion I made something special: Soutzoukakia, a meatball dish from Greece.

I have imported this recipe from a vacation on Crete, Greece, when I had the chance to take cooking classes in the tiny hotel I was staying in. The friendly chef entertained all my question and showed me several recipes, the details of some are lost to time and some others in the combined mess of my hand-writing and confused note-taking that occurs when learning several dishes at the same time and working with limited amount of paper.

I’ll be frank with you: I had doubts about this episode of Cooking with Friends. I seem to have picked a bad date for the invitation. After 3 days of waiting I only had a handful of replies to the invite and one confirmation. In contrast to that, all slots for the event in November were gone within less than 24 hours. I even debated if cancelling the event to avoid a bad experience for my newcomer would be preferable.

In the end I got a second positive reply and we held the event. Great food was made, no accidents happened, I’ve made some notes for refinement of the dishes (technically a lie, I’ll make some notes after publishing this, probably) and we’ve sat together until the early night, playing Carcassonne, a board game. I admit not liking many board games, but this one, which is about clever thinking and construction instead of racing or battling others, fits my taste.

In the end I’m just rambling but I wanted to note how much these little social events tend to improve my mood. They do wonders for my mental health. This week has been harsh before, I had at least two days on which I felt awful and noticed some setbacks at work more than I should have but most of that has been blown away by the happiness I get from successfully holding such an evening. I needed to share that this is something that makes me happy, despite the work and effort that goes into it. Or maybe because of it. I couldn’t say.

Should you be on the guest list and be reading this: I’m extraordinarily glad to host you. Thank you.


Scenes of music: Broken Crown

Posted on Wed 20 February 2019 • Tagged with Scenes of music

Song: Broken Crown

They sneak up on her when she leaves the tavern. Several of them, all brandishing swords, sabers, daggers or spears. She smiles softly. There’s only ten of them. And she’d actually been hoping for a real challenge. Ridiculous. They approach. Slowly at first but more confident when she doesn’t run or scream. She adjusts her wide hat. The feather on it is slightly waving in the evening breeze.

She takes the rapier from her belt and raises it. The bandits are hesitant. They have not expected resistance. Her flamboyant appearance and the gilded rapier have thrown them off. They expected a traveling noble on a stupid quest for adventure. She takes two steps forward to approach the first bandit and her smile widens.

He raises his sword to stop her. Too late, much too late. In the time it took him to decide his next action her rapier has sliced through his jugular after she closed the distance with a leap forward nobody expected. Blood rushes out of the wound while he collapses. Some of it splatters onto her elaborate leather armor but the stains are almost invisible on its red color. The other bandits are furious. They attack ferociously. So the dance begins.

With flowing, almost dance-like movements she waves between her attackers, elegantly taking out one after the other without ever being touched by them. A slit throat here, a stabbed heart there, a hand clean cut off - the bandits are going down fast. To finish the last three she jumps out of range and shocks the first with a sudden burst of electricity, then sends sharp, cutting winds towards the second one, sending him flying. The last one is burned so quickly by an intense heat without flame that only ashes remain. She is skilled and her swagger was not a sign of arrogance - it was pure confidence in her well-honed skills as a duelist.

They picked the wrong woman to rob.


The song had me immediately thinking of a Western theme but I wanted something fancier than cowboys while still following the theme of confrontation. I liked the swagger of the Red Mage class (RDM) from Final Fantasy XIV (FF) and thought to use this as a template for the character. After some research and questions to people I play with, I adjusted the combat scene to its current version. In contrast to FF it is more based on melee and less on magic; this is how I envisioned the scene in my head - it does not have to be a close representation of how the class plays.

Thanks to Zurin Arctus and Aruktai for their input on RDM style and gameplay.

Requested by Deithwen Addan.


Scenes of music: Greensleeves

Posted on Wed 20 February 2019 • Tagged with Scenes of music

Song: Greensleeves

The old adventurer tells the tale of his life to his friends and family one last time. He tells of his youth, of his prime, of his exploits and how his life has treated him until now, at high age. He has invited everyone to one last feast to celebrate because he feels he does not have much time left. They hang to his every word, for while he was only ever mediocre in combat, there was no finer storyteller in his time.

He speaks of years long past, of serving kings and queens. He tells of journeys across foreign lands, of conquests. He explains tense situations he barely survived and has his former companions speak about their common adventures. His life has been a long life and certainly a good life. A life whose stories are worth remembering; that is what he hopes to achieve with this last coming together - that his stories will be remembered even if he himself fades away.

He is a romantic if I’ve ever seen one.
I am captivated by his words and vow to carry his stories onward.


It took me only half the song to find a theme for it. The melody, despite being somewhat different from what I remember - I read this song is frequently used with a part for personal interpretation - and its varying tempo as well as tone sets up a story of multiple parts.

Requested by Kishuri Yllis.