Exploring projects because it's fun

This blog post you’re reading is my first of the year.

I didn’t forget to write blog posts. Instead, I’ve been trying a different focus: spending time on bigger initiatives with that time I might have spent writing blog posts. And the nature of how I pick things to work on is that most of the effort will end up with the label “exploratory” which is the kind phrasing for “not published”.

Explorations

Twilight Imperium game engine

Twilight Imperium 4th edition is one of my favorite board games of all time but is not a game that’s easy to get to the table. I had the thought that AI players would allow me to play this boardgame on my own.

The problem I’ve been running into is that the game is immensely complicated. Each piece of the game is about exceptions to the core system rules. This one brief type from a 500 line file containing all the types might give the broad idea of how many systems there are in the game based purely on the attributes of a player model. Further complicating any effort is the timing windows, how everything is up for negotiation, and how there will always be “I forgot to do ___ last turn” or “do you mind if I go back and do ____?” which necessitates going outside of normal rules again.

Typescript

export interface PlayerI {
  playerId: number;
  factionId: number;
  homeSystemId: number;
  handActionCardCount: number;
  handPromissoryNoteCount: number;
  handSecretObjectiveCount: number;
  technologyIds: number[];
  exhaustedTechnologyIds: number[];
  leaderIds: number[];
  unlockedLeaderIds: number[];
  exhaustedLeaderIds: number[];
  unitTechnology: UnitTechnologyI;
  reinforcements: Reinforcements;
  points: number;
  currentCommodity: number;
  maxCommodity: number;
  maxSecretObjectives: number;
  scoredSecretObjectiveIds: number[];
  scoredPublicObjectiveIds: number[];
  faceUpPromissoryNoteIds: number[];
  faceUpRelicIds: number[];
  strategyCardId: number | null;
  planetIds: number[];
  tacticalTokens: number;
  strategyTokens: number;
  fleetTokens: number;
  fleetCapacity: number;
}

TTRPG DND5E Campaign Management Tool

I used to more frequently play a moderate amount of weekly Dungeons & Dragons. I’ve been on both sides as a game master and a player and I had the thought that managing the numbers of a campaign can too easily become a nasty spreadsheet.

Generally managing a campaign from a standard system via this toolset would include an encounter generator, a combat tracker, interactive summary dashboard that can be displayed on a tv, and easy freedom of data to import/export.

This project has been an amazingly fun proving ground for trying out many Go libraries. I mention a few of them here.

The below snippet shows an example of a specific system’s monster attributes.

PostgreSQL, Go, ReactJS, Docker

create table "dnd5e_monster"
(
    dnd5e_monster_id       bigint
        constraint dnd5e_monster_pk
            primary key,
    created_by             bigint  null,
    created_at             timestamp without time zone default (now() at time zone 'utc') not null,
    version                bigint  not null            default (0),
    dnd5e_setting_id       bigint  not null,
    name                   text    not null,
    sources                text[]  not null,
    user_tags              text[]  not null,
    languages              text[]  not null,
    environments           text[]  not null,
    is_legendary           boolean not null            default (false),
    is_unique              boolean not null            default (false),
    monster_type           text    null,
    alignment              text    null,
    size_category          text    null,
    milli_challenge_rating bigint  null,
    armor_class            int     null,
    hit_points             int     null,
    description            text    null,
    str_score              int     null,
    dex_score              int     null,
    int_score              int     null,
    wis_score              int     null,
    con_score              int     null,
    cha_score              int     null,

    CONSTRAINT fk_dnd5e_monster_createdby
        FOREIGN KEY (created_by)
            REFERENCES "user" (user_id),
    CONSTRAINT fk_dnd5e_monster_setting
        FOREIGN KEY (dnd5e_setting_id)
            REFERENCES "dnd5e_setting" (dnd5e_setting_id),
    CONSTRAINT fk_dnd5e_monster_dnd5e_size_category
        FOREIGN KEY (size_category)
            REFERENCES "dnd5e_size_category" (name),
    CONSTRAINT fk_dnd5e_monster_type
        FOREIGN KEY (monster_type)
            REFERENCES "dnd5e_monster_type" (name)
);

Roguelike Game

The Roguelike game Morgemil has been on off-and-on project for years now. Never quite reaching a level that can be published. It feels like folly to admit that I’ve been adding little bits here and there, but I have.

F#

Train board game adaptation

Last year, I started adapting one of my favorite train boardgames. I absolutely wrote myself into a corner in a way that only allows for old-school hot-seat multiplayer. I haven’t yet revisited to untangle that mess.

Go

Factory Game and paper notes

Most of my writing is never published. And my writing is mostly divided between plaintext markdown files and physical notebooks. Over the past year, one of my new notebooks has been all about a video game oriented around logistics, production, sustainability, and margins of predictability on a planetary scale. No code has been written for this but here’s two early sample pages showing some thought process.

Recent changes in thinking have been oriented around two questions: how can each decision be meaningful? and how can controller support be a first-class concern? (brought on by steam deck usage) Both of those questions together really are making me inspect and revisit the almost spreadsheet-esque design to really hone in on what I want the game’s identity to be, if indeed it ever moved past the notebook stage. Really honing in on the core gameplay loop is difficult to nail down.

Page 1

Page 2

Related to factory games, I found this article talking about how Factorio is functional programming and that is fascinating.

Maintenance

MSSQL Exporter

A couple days maintenance of this MSSQL Exporter was badly needed but there’s still more to do. Twenty thousand docker pulls, for all the little that metric means, is a fair amount for me.

C#, Docker

Misc. asides

I’ve moved on from openSUSE Tumbleweed to a M1 macOS and will be trying that for a while as daily driver. This MacBook is compiling this very blog about as fast as my AMD 3900X desktop does.

Proxmox has been running on my server with no problems since last year. I might experiment with TrueNAS and make it a dedicated storage machine.

Summary

To keep work and hobbies separate and to keep a better balance, I really prefer to explore either technologies or use-cases that I wouldn’t normally see at work.