Personal site of Fiona Hopkins. Coding, crafting, gaming, and queer shit.

Latest Posts

Sentinel Comics rulebook cover

My twin loves of TTRPGs and superhero comics make me always on the lookout for new and interesting superhero RPGs. Since I’m GMing a campaign of Masks, I like to read other systems to see if there’s any good ideas I can adapt. Since I’ve quite enjoyed Sentinels of the Multiverse, I picked up the Sentinel Comics spinoff RPG, but it was the recent System Mastery podcast episode about it that convinced me I really needed to give it a try.

Though my current campaign schedule is too booked up to add another game, I wanted to at least get a taste of Sentinel Comics’ detailed character creation. What better way to do that than see how well it could make my favorite comic book character, Squirrel Girl.

tl;dr: Quite well. Read on!

Cait and I play a fair bit of KeyForge together, and even go to small local KeyForge nights when we can get childcare. But since we were going to the Albany Vault Tour, we needed something we’d never had before: separate boxes for our components.

So I made a pair of these:

Wooden KeyForge box with three large gears in the lid

Inside is space for three sleeved decks (it was a survival tournament, after all), a small component tray, and a storage area for our aember tokens and spare card sleeves.

Inside of the box, showing a tray of components, sleeved cards, and storage

The best part, though, is the three gears on the lid. Not only do they come off so you can use them as key tokens in the game, they’re the keys to opening the box itself.

To unlock the box, you need to remove the center gear and then turn the outer gears.
Learn more about how they came together after the jump.

Cait and I spent the last weekend playing KeyForge at the Albany Vault Tour. We both had a ton of fun and met up with friends old and new.

I wanted to write up a report so I don’t forget. It was a ton of fun and my last game had an epic last two turns that was the most dramatic KeyForge I may have ever played, and an emotional rollercoaster that followed when I started reflecting on it.

The Format

Each team was made up of three people, and got six Worlds Collide decks to open. From those, we had to pick three. One would be for standard Archon, one would be for reversal, and the last would be for chain-bidding Archon. (Someone described this as the three stages of Adaptive, just played in parallel. Deconstructed Adaptive, if you will.)

Each teammate would take one deck for the four rounds.

My Team!

I was very fortunate to play with two pals from New York City: Will and Jonesy. Will I had met when he and his also-awesome wife Rowan came to Cambridge for the KeyForge Prime Championship at Pandemonium. (Will won it, by the way.) In Albany they introduced me to Jonesy who, besides being the most dapper person in attendance, was likewise tremendously friendly and a great KeyForge player.

I was the least experienced of the three of us, and Will’s brain was fried at that point from going 4–2 in the main event, so we nominated Jonesy to take on the chain-bidding role. Will very kindly deferred to me for the choice of remaining roles. I picked reversal because it was the best fit for my less-than-complete familiarity with Worlds Collide, and because it sounded like the most fun.

It was.

The format was actually blind reversal. Which meant that, after we got the deck from our opponent, we weren’t allowed to flip through it or even look at the list on the back of the Archon card. The only way you knew what was in the deck was to draw it.

This is now my favorite way to play a KeyForge tournament. What got so exciting was that, by the end of the tournament, I was very familiar with what was in the deck I was playing against, so I knew what to watch out for, but had no idea each game what my tools for stopping it might be. Every draw was a surprise.

The Deck

Our reversal deck was Pvt. Barbaxe Brant which, at an SAS of 65, is actually not that bad of a deck. A bit above average, maybe.

Prv. Barbaxe Brant
Sadly, not a very sucky deck.

Here’s what I learned to watch out for when playing against it:

  • 2 Musthic Murmook, both for the +1 key cost and the substantial direct damage.
  • EDAI “Edie” 4x4, which was good for at least +1 key cost.
  • Interdimensional Graft. Not that hard to play around, though, especially as the decks I was handed weren’t generating piles of AEmber.
  • A huge Brobnar board, hopped up on power counters from their various brews.

I lost the first two games (though as a team we ended 1-and-1) from not guarding enough against that last point. I learned not to waste a board wipe on anything less than a ton of giants.

I also learned not to hope that a Cauldron Boil — which I kept seeing, and holding — could do work for me. These decks were not giving me a lot of ways to get the damage on in the first place. Doubling it would do nothing.

I was able to sneak in a win in my third game, though. I had a nicely-timed Grasping Vines of my own Fangtooth Cavern for a little aember boost that put me over the edge. It was a good thing, too, as Jonesy and Will split their matches, so mine was the one that gave us our second team win.

Will gave me a thumbs-up.

The Finale

I have to write about this because it was so dramatic. If you can follow KeyForge, you’re going to want to read this. See you after the jump.

Update, 1/18/20: I found the deck I played against: Titanlight, the Adviser of The Legend. Descriptions updated to be more certain, now that I can look at the exact card list.

My custom theme for this blog is derived from Gatsby’s gatsby-theme-blog-core package, and I try to hew to it structurally, even as I build things on top of it. When adding comments to this blog I came across a part of Gatsby I hadn’t really explored: sourcing my own nodes, and associating them with nodes from another plugin.

Comments for this blog are stored in a Cloud Firestore database, keyed by the path (i.e. “slug”) of the post they belong to. I chose the path because it’s a stable identifier1, which I can’t guarantee of the Gatsby node IDs.

But node IDs are exactly what gatsby-theme-blog-core’s createPages lifecycle function passes in as context. Which means they are the inputs to the GraphQL query for making a post page.

So how do I query for my path-indexed comments when all I have is a post ID?

See how to sort this out after the jump.

Now with Comments!

1 December 2019

I rolled my own comment form using Firebase’s Cloud Firestore as the backend (and Akismet integration, so don’t try anything).

You can try it out below and at the bottom of most other posts.

I’m trying out doing this server-side rendered. The comments form POSTs to a Cloud Function hosted on Firebase that does the spam check, writes to the database, and triggers Netlify to re-publish the site.

My Gatsby blog theme then sources the nodes from the Firestore database so they can get added to each page.

I learned a good deal about Cloud Firestore — which I hadn’t used before — and combining Gatsby nodes from different sources together.

Does it work? Give it a go!

Bargain Quest

17 November 2019

I broke out Bargain Quest at our game night this past Friday, and I don’t think I’ve been at a table that laughed as hard or as long. I solidly recommend this game.

I heard about Bargain Quest from an old episode of the Shut Up & Sit Down podcast, and recently got my copy from the Kickstarter for its expansion.

The Shut Up & Sit Down video review is worth a watch and will give you an overview of how the game plays, why they like and recommend it, and plenty of their own jokes and gags.1

Game Summary

Here’s the pitch for Bargain Quest: You’re in a fantasy town where adventurers are going into dungeons below to battle monsters. Good for them! Keep the town safe! You, however, stay on the surface, as the owner of a shop that is happy to outfit said adventurers with all of the weapons, armor, and magic items that they can afford.

Each turn, you’ll get one hero as a customer before they go and fight whatever is dangerous this week. If the particular hero who came to your shop wounded and/or survived their encounter with the monster, that’s great! You bask in the good reputation with some victory points. If they didn’t succeed? Well, you got their money anyway.

This setup is inherently funny, and the game builds on it by giving heroes, items, and shop employees incredibly thematic abilities that help you tell a story with each turn.

Recent Crochet Projects

14 November 2019

I’ve finished a few crochet projects recently. You can take a look on my Ravelry profile, but I’ll cross-post here as well.

Wildrose Market Bag

Market bag

You can get this design from All About Ami: Wildrose Market Bag

I’ve subscribed to her blog (remember we’re doing that again) and as soon as I saw the motif go by in my RSS reader I wanted to make it. Though, of course, I needed to do it in an on-brand color:

Close-up on the granny squares
Made with Lion 24/7 Cotton in 142 Rose

This is worked as 13 granny squares, which are then stitched together before you crochet the top border and straps. The pattern was interesting but easy to follow. Granny squares are great for working on the train, bus, or when watching my kids at the park.

For best results, you need to block granny squares to make them square and even. I may have also summoned something while doing it.

My LJ for the Moment

12 November 2019

I’m depressed. I’ve been fighting with it on-and-off since I was a teenager. It’s cyclical, so I can go for weeks or sometimes months without any problem, and then it will knock me on my ass for a few days. Sometimes I just don’t want to do anything, and can’t focus. Sometimes I can barely move my body and just stare until my vision goes weird. Sometimes I just cry about all the ways I think I’m hurting people.

I’m on medication, and I think the medication is helping. I don’t have a great memory for my own experiences so I’m not sure. But I think I’m better than before I was on it. I wish I had taken notes.

It took me some time to find a medication that was right. I went through 3 SSRIs as well as Celexa. The SSRIs made me really anxious. The Celexa put up a wall between me and other people. I felt numb and unable to connect to people I’ve loved for years.

Now I’m on Welbutrin. If it’s not helping, at least it doesn’t have noticeable side-effects.

I’m also on HRT. That might not be helping with the depression. I can’t take much spiro as an androgen blocker because my blood pressure gets too low. So I’m only on a little. We tried adding finasteride and dutasteride as alternate androgen blockers but they made me more depressed. I cut myself for the first (and so far last) time.

I worry that my T levels and my depression are linked. Like, if my T goes down, I’ll just get more depressed. That’s apparently a thing. I just got more estradiol patches that may be encouraging more conversion of testosterone to estrogen (which is also a thing; bodies are weird). Of course, if I don’t get my T down and keep on with HRT that will hurt my mental health in other ways. It’s a nice transition catch-22.

This is just a stream-of-consciousness post. I don’t know if there’s any real point. I guess depression is a part of me, and I wanted that reflected in this blog.

It’s also a writing exercise. Can I just talk about my experiences without needing to be authoritative or have supporting evidence or any of the things I feel like my technical or gaming posts need.

This is now my LJ, at least for a moment. I haven’t been listening to music, but if I were it would be The Mountain Goats. You know the song.

Maybe this will get me to post again soon. How long do I want this to be the first thing you see on the blog? Does it matter, given that I have no traffic? Can’t we all blog again?

Depression is real, depression is hard, depression lies. I’m lucky. I feel like a burden to my family when I’m like this but they don’t feel like I am. How much depressed can I be until I really am one, though? I worry about that, when I’m depressed.

I have therapy on Friday. I’m counting the days.

The Rust team have released 1.39.0, which means the async/.await syntax has arrived!

My excitement level is in the intrigued-to-enthusiastic range, like a new expansion dropping for a game that I liked but haven’t played in a while.

What I’d like to do is see how this can be used in my not-yet-released pet project, wifinina-rs, and its released-but-not-used-by-anyone support library, cortex-m-systick-countdown.

wifinina-rs is a Rust client for connecting to wi-fi co-processor chips (typically ESP32s) running the WiFiNINA firmware or its derivatives. (Including the Adafruit PyPortal, which is my target of choice.)

Sidenote: debugging wifinina-rs when the only way I was able to get output was to set the name of its SSID is possibly my favorite development hack.