Solo RP, round 2, maybe a something

It’s about 10 in the morning and I just pulled into Elmwood. Word on the vine is that there’s something funny going on here but I can't seem to get any details. It’s too early for lunch so I might as well scout around a bit, see if I can get some information or, at the least, work on my sales quota.

Heading into town, I spot a house that’s obviously larger than the rest with ornate gables and a well kept lawn. Whoever owns that house has a pretty good chance of being well-connected in town and might have the money to buy a set of encyclopedias for their kids or grandkids.

Parking my car, I approach the house, knock on the front door and a few moments later am greeted by an older gentleman wearing an expensive looking suit that somehow reads as not entirely put on. His hair is scattered about like that photo of that Physicist in my encyclopedias. What’s his name… right, Einstein.

I introduce myself and get into my encyclopedia spiel, “Hello sir, if you don’t mind my taking a little bit of your time, my name is Arthur Johnson and I’m traveling this great country of ours sharing the gift of…”

“Let me stop you right there, son. If you’re here trying to sell me some story of how you found Jesus, I don’t have the time and you sure aren’t getting my money.

“No sir, I’m sharing the gift of knowledge. I have here, in my hands, Volume ‘H’ of the Encyclopedia Europa. I bring Volume ‘H’ because it includes History, both the history of our great nation and the world. Can I interest you in…”

“The history of the world is not written by men! We are merely in the interregnum between the powers before and the powers to come! I envy you, son, travelling these lands with your so-called history, oblivious to the true reality that lurks in every shadow and behind every corner. Oh that I might forget the things that I know or wake and discover it all a terrible dream.”

It’s clear that I’m not selling any encyclopedias today but there’s almost certainly something to the rumors that something’s off in Elmwood. Let’s see if I can get any more information out of this unkempt but well dressed gentleman.

Read more…

Untitled Solo RP project, Session 1 and the wrong scale

A couple nights ago, I started my first playtest session for my new, as yet untitled, solo rpg. By the end of the attempt, I hadn't managed much in the way of play but I had gotten some worldbuilding in and I had a rather good time. I learned some useful things about scale of game and where to start.

The goal at the outset was to make an initial city, set out a PC in the city, introduce an NPC, and have one interaction. Too ambitious, maybe, but being unambitious is a recipe for failure.

I had figured a city was a good starting layer but it ended up being too hard to fill out all of the details or figure out where to start. I managed to establish a concept of districts, so my plan for my next session is to work out a system for generating small towns and play a game that operates on the layer of a town or a series of towns. Once I've tested that a bit, I'll step up to the city layer and use the town generation system to generate districts within a city.

I noted down my session through a series of Google Drive documents and photos of drawings arranged in four groups: Rules, World Catalog, Log, and Notes.

Session notes below the fold...

Read more…

Solo RP as a New Adventure

We here in the Bay Area have been under shelter in place orders for quite a while at this point and, even with my family around, it's pretty isolating.

In my various late evening digging around the Internet sessions, I stumbled across the notion of solo PnP gaming. I was initially intrigued by the premise of Journey Back (unreleased at the time but available now). Digging, I discovered the similar game The Adenturer, which was interesting but seems structured more as journal prompt and less as solo gaming experience.

In my searching, I discovered Shut Up & Sit Down had put out a few videos on solo gaming:

  1. The Wild, Affordable World of 1 Player Print'n'Play Games, which introduced me to Bargain Basement Bathysphere (BBB). BBB is quick, fun, totally free, and has quite a bit of content. After a handful of fun dives, I kind of lost interest in continuing. There's a little too much of a push your luck mechanic for my taste and it's too light on story for what I want right now.
  2. The Quiet Year - A Perfect Game for Isolation, which just speaks to me on a geometry and cartography level. I haven't played it but it sure adds wood to the play solo games fire.

From there, I scoured /r/soloboardgaming, and BoardGameGeek in search of something that would be exactly what I wanted. An honorable mention is due to Pocket Dungeon, which is a kind of fun PnP roguelike game.

Somewhere, somehow, I learned that solo roleplaying games are a thing, which is why /r/Solo_Roleplaying exists. This has turned into quite the rabbit hole and I have subsequently consumed (and re-consumed) a number of role playing game books figuring out how I want to approach Solo RP as a concept. Ultimately, I've decided to develop my own system; it'll be built as a series of game layers based on the scale of the setting. The goal of the final layer is something interstellar that scales up and down depending on where the player is at any time. For now, I'm focused on the basics of character creation, gameplay, and story building. World building, and galaxy building can come later.

Some of my major influences so far are:

  • Shadowrun - honestly not a huge influence on this specific project but it's the RPG that I played extensively in my teens and early 20s, so it will always be a seminal influence on me as a RPG player. I can't not mention it and I still think that 3e is the best edition.

  • Traveller - I am pretty sure that I want to build up to an interstellar scale and Traveller is kind of the gold standard for space operatic RPGs that span large swathes of a galaxy. Traveller also introduced me to the idea of a lifepath-based character creation system.

    A quick aside is needed for MegaTraveller 1: The Zhodani Conspiracy, a computer game that I played as a kid and never got much of anywhere in. I wanted to figure out how to make this game get anywhere but I was a small child and the idea fell out of my head until after MS-DOS stopped being an easy thing to use.

  • Mythic - here is where we start to get into the meat of the solo side of things. I, honestly, had never seen something like Mythic before. It's less a system for managing characters actions within a planned narrative and more a way of randomly generating a universe through an endless series of yes/no questions.

  • The Burning Wheel - I want to play The Burning Wheel for real. It looks so awesome. There is a skills and progression system that encourages using the rules to progress the game but also narrows everything down to success tests (that feel very Shadowrun 4e). But everything boils down to those success tests and there's a very rich in-game/in-character karma system. The character generation is lifepath-based and then, the most novel bit of all, there's the "Let it Ride" rule.

    "Let it Ride" basically says that the result of a die roll determines the nature of reality and must stand. If I fail to pick a lock, that's it; the lock cannot be picked, by anyone. If I roll to convince someone of something and I succeed; they're convinced. No re-rolling; no trying again later; reality is set.

  • Fiasco - Fiasco is a delightfully simple (from a rules standpoint) game for constructing fun shared narratives with a Coen Brothers feel. I've played it in person once and had an absolute blast of a time. Fiasco very much takes scene-based narrative in games to an extreme. Relationships are established; settings are established; MacGuffins are planted; and the narrative flows from there. The more I think and focus on my game plans, the more my core structures are narrowing to PC+NPC+motives+location as the central game Oracle components. I wasn't even thinking about Fiasco until a thought caught me and I dug my copy out of the depths of my garage.

  • MechWarrior - a game that sits in a universe that I love, by a company that is dear to my heart, but that I've never had the opportunity to play. I cannot speak to the modern editions (i.e. BattleTech: A Time of War) but the old ones had a few great things going for them; namely being made by FASA, being BattleTech, thereby interstellar, and by having a lifepath-based character generation system.

  • UNE - the Universal NPC Emulator (UNE) is a tool for generating NPCs out of nothing, including motivations, and so on. This will be pretty important as a guide for figuring out how to create people for my game and seems like a pretty quick and straightforward system.

I'm pulling ideas and influences from elsewhere but those account for a solid thousand or so pages of role playing game manuals that I've read in the past month or few. I've finally started putting things to paper and had a false start of a play session. I'm retooling a little but I'll drop some notes from the false start soon and then, hopefully, use this space as a dev-journal of sorts.

Uncut Jewel

Once a year, I take a month off from Caffeine and Alcohol (sometimes I'll throw in something else like high fructose corn syrup). It was fairly arbitrary for a number of years but now, having learned it's kind of a thing, I tend to take my temperance in January. This time around, I've moved things up a few months and am abstaining in October.

Giving up booze, even temporarily, doesn't mean that I want to give up cocktails. Turns out, however, it's really hard to make something without alcohol that doesn't end up tasting like juice or flavored water. Seedlip is meant for this purpose and helps some but tends to fall pretty easily into the juice or flavored water trap.

Through a mix of experimenting, Seedlip recipe ideas, Aviary Cocktail Book inspiration, staring at my liquor shelf, and starting at my fridge, I've had a modicum of success. I seem to have hit on a formula that works well stirred with ice and served Up:

A Non-Alcoholic Up formula

  • 1 oz Seedlip (Spice 94 or Garden 108)
  • 1/2 oz Verjus Blanc (Fusion Napa Valley)
  • 1/2 oz Verjus Rouge (Fusion Napa Valley)
  • 1/2 oz Cranberry Juice
  • 1/2 oz Syrup (Simple, Demerara, etc.)
  • 1-2 dash(es) bitters

Gomme Syrup and Garden 108 seem to work well together but I think the best that I've hit on so far is what I'm calling an Uncut Jewel:

Uncut Jewel and its ingredients

Uncut Jewel recipe

  • 1 oz Seedlip Spice 94
  • 1/2 oz Verjus Blanc (Fusion Napa Valley)
  • 1/2 oz Verjus Rouge (Fusion Napa Valley)
  • 1/2 oz Cranberry Juice
  • 1/2 oz Maple Syrup (Grade A Amber Color, Rich Taste)
  • 1 dash Salted Cacao Bitters (Workhorse Rye + Dandelion Chocolate)

Stir with ice, serve up, and garnish with a Maraschino cherry.

Notes

The drink leads with a note of allspice before taking on dominant notes of fruit and nuts and finally closes with a hint of cocoa. Overall, it's well balanced, sippable, and fairly complex, without assaulting the palette.

An Arbitrary map from SQL with Go

I've been writing a lot of Go lately and finding it a pleasant balance of simplicity, power, functionality, and ecosystem support. In a lot of cases, I am finding the guarantees afforded by type safety to be really nice but, occasionally, the strict requirements can make some easy things much harder than I want them to be.

Recently, I found myself wanting to test the behavior of some code the hit a SQL database. Specifically, I wanted to check the results of a handful of queries with varied columns and column types. With Python, I'd approach this with SQLAlchemy, and turn the result into a list of dicts.

def rows_to_dicts(rows):
    """Covert a SQLAlchemy RowProxy into a list of dicts."""
    return [dict(r) for r in rows]

From here, it's pretty straightforward to assert the result matches expectations. If you're using pytest, you'll also get really clear details on where the results aren't what you expect. If you don't have the expected columns or column types spot on, you're assertion will be off but you won't hit any underlying errors at this point of your testing.

Go, on the other hand doesn't have quite as easy an option. The crux of the problem is that the only way to get a result row out of a sql query is via (*Rows) Scan, which demands you know something about the structure of the result before you query. Luckily Scan is happy to read anything into a *string as long as you're asking for the right number of values so we can write an equivalent function to the python list comprehension.

import (
    "database/sql"
)

func RowsToMaps(rows *sql.Rows) ([]map[string]string, error) {
    columns, err := rows.Columns()
    if err != nil {
        return nil, err
    }
    columnCount := len(columns)

    cursor := make([]interface{}, columnCount)
    for i := 0; i < columnCount; i++ {
        var columnValue string
        cursor[i] = &columnValue
    }

    var resultMaps []map[string]string
    for rows.Next() {
        err := rows.Scan(cursor...)
        if err != nil {
            return resultMaps, err
        }
        rowMap := make(map[string]string, columnCount)
        for i, columnPtr := range cursor {
            key := columns[i]
            var columnStr string
            if columnStrPtr := columnPtr.(*string); columnStrPtr != nil {
                columnStr = *columnStrPtr
            }
            rowMap[key] = columnStr
        }
        resultMaps = append(resultMaps, rowMap)
    }
    if err := rows.Err(); err != nil {
        return resultMaps, err
    }
    return resultMaps, nil
}

This, much like the Python above, gives us a list of maps of column name to column value, with the minor caveats that all values are strings and NULL values become empty strings. I found it a useful chunk of code, so I thought I'd throw it up.

Sure, it's more verbose but sometimes that's the price we pay for dealing with dynamic results in a staticly typed language. There are other prices paid in the other direction.

Not all rules live forever

At some point in high school, while gallivanting around New England on inexpensive gasoline and end of the day donuts some random guy at Dunkin' Donuts gave us on the cheap, I developed my first set of canonical rules to live by:

  1. When you're chucking a danish, everything's a cop car.
  2. When in doubt, go left.
  3. When in doubt, buy double.

These were born empirically from the demands of the time. A few years later, an addition was made:

  1. Even floors do not exist.

This rule was born from spite and soon after another rule was introduced to provide a loophole:

  1. Apathy is the lazy man's whatever.

Spite and loopholes aren't really good ways to build a morality or worldview so I am retiring rules #4 and #5.

Dredging the past and updating the present

A few months ago, while digging around my gargage, I found an old server of mine. I was looking for a particular bit of old data that I couldn't find on my current computer and thought it might be on this one. It didn't have what I was looking for but it did have a bunch of content from my old blog, going back to 2004.

It was a really old computer that wasn't cared for after I moved stuff to the cloud and the hard drives started failing reads almost as soon as I looked at the thing. However, with some running dd and a lot of finger-crossing, I was able to pull out a backup of the old blog. The backup, annoyingly, was a MySQL dump of a Wordpress page. After trying a handful of text based approaches and a couple of automated approaches, I figured I might as well install MySQL, load the dump into the database and hack together some one-off code to rip things out in a format that I liked.

The data extraction code isn't pretty but it gets the job done:

Read more…

Fortune Cookie: 2018-09-04

Adventure is
worthwhile in itself.
---
LEARN CHINESE - Good luck
好(hǎo)運(yùn)
Lucky Numbers 25, 55, 8, 17, 54, 1

Commentary: Many things have intrinsic value; adventure included. Many things have extrinsic value; aphorisms included.

Grenadine

In my ongoing quest to make delicious alcoholic beverages, I have increasingly found myself digging into my ingredients. Syrups, as a class of ingredient, have received a decent amount of my attention. As an aside, if you're buying simple syrup, you are doing a lot of things wrong. In my experience, it is decidedly tricky to find decent grenadine, where decent is defined as being made with real pomegranate and without high fructose corn syrup or food coloring. So, I've started to make my own:

Grenadine

A pomegranate syrup that adds a sweet tartness to drinks and a distinctive red color. Notable in small quantities in a great many drinks and also as the second ingredient in a Shirley Temple, a drink the actress was apparently never fond of.

Ingredients

  • 1 cup fresh Pomegranate Juice (~2 large pomegranates)
  • 1 oz Pomegranate Molasses
  • 1 1/2 cup White Sugar
  • 1/16 tsp Xanthan Gum (optional)
  • 1/2 tsp Orange Blossom Water
  • 1 oz over-proof grain neutral spirit (Everclear or vodka)

Read more…

Bash history synchronization

Bash is my go to shell. I've tried fish; I've heard about zsh; but Bash is my go to.

I really like command history (pressing up arrow or Ctrl+R) and there are a few specific behaviors that I want in my history:

  1. If I have multiple terminals open, I want history shared across them.
  2. If I run the same command multiple times, it should be in my history once.
  3. My history should stick around forever.
  4. The last command, I entered should be the first thing I see when I press up arrow.
  5. Race conditions of long-running commands shouldn't erase history entries.

Turns out all of this is a little tricky with bash, but I've mostly managed it:

Read more…