Anchorite is the personal work of Mathew Purchase and friends. So far we've released three titles, Unstoppable, Interloper, and Exoloper. Paw. We previously worked on and have since paused work on Charge.


Reducer Pattern

This week was a bit of a mess. At the end of last week the game was in an ok position but still not fully working. The newly implemented reducer was definitely doing its job but only a few things had been migrated across to it.

I spent Monday doing admin stuff, cleaning up bugs and generally making the project a little smoother. Tuesday focussed on getting some new features in, such as dice modifiers (and a general rework to the dice class), retools and then finishing off dependent tasks like abilities and unit psychology.

But then.. Disaster Turns out that the game would crumble pretty quickly on device.

The issue was down to the way I'd architected the multiplayer classes, LocalMultiplayer and GameKitMultiplayer. For testing (and eventually for local play) I'd built a parallel version of GameKitMultiplayer that just works on my dev machine, but over time the two classes drifted in terms of functionality, meaning that whilst everything worked fine in my editor, nothing worked on device. The reason for this drift was effectively because they tried to manage too much. From handling local player info, to talking directly to the game controller.

Anyway I made the decision to completely rewrite these classes into small, clean interface implementations. This should ensure their functionality going forward, and make them much easier to debug.

That process took the rest of the week. But at least the game is now singing along nicely in both the editor and on devices.

I also spent a bunch of time thinking about how I'll end up monetising Charge, and a whole set of time building out tasks for the lead up to a public alpha (games kinda need some graphics, sounds and UI)

I know I said this last week, but I think next week I'll work on some more fun stuff and less systems-y stuff.

Tasks completed:

(10/03/2023) * Look into the Project Auditor tool * First pass at Unit Traits systems

(09/03/2023) * Rework broken tests * Complete switch over to Reducer Pattern * Reducer: Write Tests * Reducer: Identify further events that need to be transmitted * Re-implement UI Lobby for local games

(08/03/2023) * Before hooking the new multiplayer handlers up to the game, test them out in both dev and prod environments * Unit distance for orders is calculated on leaderpoint. Suggest using corners instead. * Turn on TDD Build guards again

(07/03/2023) * Run another playtest of reducer functionality, both in editor and on device * Unit Psychology * Reducer: Implement ability logging * Unit Abilities * Rerolls & Dice Modifiers * Change initial deployment to be one big event.

(06/03/2023) * Write up Monetisation strategy for Charge * Line up graphical tasks for Charge * Line up audio tasks for charge * Line up UI design work for charge

Bugs squashed

  • Archers attempted to fire, but were exhausted on first try.
  • Game state isn't properly rebuilding across player turns.
  • Significant issues with turn replays / board state
  • Nullref on game load / create on Device
  • Nullref on game load after turn one
  • Null ref on loading existing game (iOS)’
  • Sometimes the "Complete deployment" button doesn't properly show (iOS)
  • Local multiplayer breaks on setting camera position
  • Player two can once more see player one's units during deployment
  • RaiseGameLoaded and RaiseDataLoadeda are firing too often inside GameController
  • Local games. Quitting then attempting to load again causes issues
  • KeyNotFoundException: Dependencies keep firing between editor game play runs.
  • Loading a match results in units spawning at 000
  • Localmultiplayer doesn't properly mirror gamekit multiplayer in the create-game-flow, leading to inconsistencies between the two.
  • Camera not swtiching under new multiplayer systems
  • Player 2, iOS, After sending complete deployment, Deployment zones are still visible
  • terrain doesn't sync on iOS?
  • Save games need to be cleared properly on iOS
  • New system to cast abilities via order has broken all other abilities aside from Attack

Charge

This is the first in the series of blog posts detailing how I'm going with Charge.

So far I've got most of the core gameplay systems up and running. There's turns, each player has an army, you can do all the core orders for each unit, movement, pivots, charges, using abilities, etc etc.

The game isn't much to look at right now, but I'm thinking that once the core systems are implemented I'll move onto making it less.. placeholder-y. Then the screenshots will come thick and fast.

I hit a roadblock last week where the data that was being sent between turns (aka, the entire game state and history) was too big for Apple's GameKit turn based systems. I figured I'd hit this point eventually, but not quite so soon. So this post picks up where I left off last week trying to implement the reducer pattern roughly inspired by this blog series:

Making a turn-based multiplayer game in Rust - What's a turn-based game anyway? (part 1/3)

Long story short, we just send the actions for the previous turn, and then rebuild the game state locally.

It's more or less working at this point minus a couple missing features and a nasty bug with the Unity Editor itself. I'll figure that out sooner or later.

It's also a roaring success for transmission size. Back down to under 10% of the budget.

I've got some concerns about how saving the game state to iCloud is going to perform, I'll have to keep an eye on those sizes, but at least 1mb is bigger than 64kb.

I genuinely think it's all coming together pretty well so far. Sure it's taking forever, but I think I'm getting better at programming whilst doing this, so fingers crossed it doesn't all fall over in a shit heap.

On the productivity front, I switched out Notion for Things 3. Had a couple days where the internet was basically dead and I couldn't get onto Notion to see what I had to do next. Decided I wanted something with a little more purpose, a little more offline and Things definitely seems more of both.

Next week I hope to finish the work on the reducer pattern and get back into regular dev. Might even treat myself and make some more models or work on effects.

Tasks completed:

(03/03/2023) * Playtest Reducer pattern some more. * Reducer Event: Dice Results * Reducer Events: Combat results * Attacks aren't deterministic, their results occur upon consumption. * Reducer Events: Morale Results and Psych changes * Change auto-deployment so that it intersperses leaders amongst regiments * Orders: advanced * Unit Controller Status Checks

(02/03/2023) * Anything that is consumed by the reducer should be logged to logger system. * Split order results into individual result-events * Look into building a better way of divvying up tasks into sprints

(01/03/2023) * Switch bug reporter over to Things * Research Astra Fellowships * Add Deselect button to Unit UI * Don't store full unit data in game data * Replace existing c# events with messenger service * Camera FOV gets wonky sometimes with an NaN error * Change gamplay transmission to be orders only * Unit Exhaustion

Bugs squashed

  • Using abilities causes a nullreff
  • Attacks just fall over. The event doesn't actually fire.
  • Order results are busted completely lol.
  • Orders get spammed / looped somehow
  • Missing Ref: UnitUI.ShowAbilityRadius
  • Player one can see Player Two's army on deploy
  • Individuals are hard to select
  • Cannot pivot a unit unless dragging from centre
  • Unit names incorrect in viewer
  • Order events only send state, not dice rolls or logs
  • Local games camera always starts at player one
  • Turns aren't sending on Device
  • Load game crashes after a game has already previously been loaded

Command and Control

Command and Control

One of the elements that was prevalent in older tabletop games was a concept of leaders directly.. well.. leading their units. The main title I keep thinking back to is Napoleons Battles. In that, a unit can only be ordered if a leader model was within range, else they’d either hold or at best, return fire. I’d played many games with this mechanic and always thought it gave a sense of value to the leader units beyond their direct combat utility.

Modern titles reduce heroes and leaders down to a morale bonus at best and at worst, mostly redundant. To me this feels like a shame and a missed opportunity. The leader, as part of the hobby is going to be a centrepiece to the army, and as part of the gameplay should feel like the core gear that an army turns on.

In Charge then, my initial approach is to make them both a powerful unit and a centrepiece of an army. Leaders begin each turn with an order pool. They may issue any order to a unit within their radius, including themselves and other leaders. They also may function as a bonus to morale checks (depending on the army list) and / or also function as a powerful hero unit. In this sense I feel like they’ll act as directorial units. A powerful melee hero leader with a small pool of orders and limited range will naturally pair well with cavalry or shock troops, where a more strategic leader will offer options to a wider set of units..

This also creates opportunities for vulnerability within an army, as a unit without orders cannot do much. That aforementioned hero unit might be killed early in the match, opening up opportunities for a counterattack.

There’s a ton of edge cases this opens up, like losing all leaders early on, or not having enough orders to cover the army, but I think that the overall opportunities for interesting tabletop storytelling outweighs the potential issues. I also feel like modern techniques for handling individuals lend themselves nicely to keeping them alive long enough to be effective.

All this is to say I'm still exploring the subject within the game, but I do feel that it'll feature heavily.

Website

Capping off the year with some more personal work, I decided to rebuild my website. A couple years back I put the last iteration together, which included some fancy three.js models from both Unstoppable and Interloper. The idea was cool but I was never quite happy with the execution, I might revisit it in the future but for now I’m taking it in a more minimalist, and easy to maintain direction.

If you’re viewing this directly in the browser, then, welcome to my corner of the internet.

Design:

I wanted to keep this all super lowfi, very clean and minimal, so I opted for using the default browser font. It’s easy to read, looks fine, and generally just does an ok job at being legible. I chose a charcoal and orange theme, only applying the key colour to major headings. Images are centred and some extra styling was added for code blocks. Nothing fancy, but it should be easy to read.

Code

I’d like to preface all of this with a couple points. First, I’ve got limited experience building web content, I’ve made a couple angular web sites, and some of those have been turned into apps, and then I’ve made my own personal content. Secondly I don’t know a damn thing about shell scripts, this is the first time I’ve dove deep into them. I’m likely making a ton of inefficient, or even wrong choices here, and that’s a-ok!

This is the part I really wanted to be minimalistic. Very limited use of JS, no site generators running in the background, nothing but static html hosted directly on a shared hosting web server. Basically, if this thing can render on a win95 machine I’ll be happy. Ideally it’d load super fast too, but I’m still working out some kinks with gif loading. The real kicker is that the pipeline is built around Bear, my main note taking and writing tool, export html from bear, run a bash script, and boom, blog updated.

Content in bear is written in Markdown, but I’ve found its text pack export has issues with providing the relative link paths to the files for images, so instead I opted to use the html export instead. This also resolves the need for a markdown parser as well… everything has already been parsed. The downside of this approach is that html exported from bear comes pre-styled and can’t easily be extracted to a single page feed (more on that later) without fudging up the relatively minimal css I’m using, so part one of the bash script is to cut out the first couple hundred lines of inline css that comes with the exported html file.

The second part is cleaning up some other bullshit from the bear HTML exporter, removing all the <br> tags, fixing the instances of apostrophes using the incorrect Unicode character, making sure the relative links point absolutely (again, more on this later) and rebuilding the h1. This last part happens because Bear uses the first h1 as both a title, and a file name proxy. I could always change the file name at export, but it’s an extra step I’d prefer to avoid. All of this is achieved using a ton of sed, iterating through the file and changing instances where required.

Once the exported html is cleaned up, I move onto compression images using sip and its aggro jpeg compression to bring images into line. This is the first space where I’ve got work to do, as I’m not covering the rather large gifs that I generate to show off gameplay. I’m not sure these can be compressed any further than they already are. (I use macOS’s native video recording and the desktop gif conversion app Gifski)

After the images are cleaned up, I then start propagating the new file amongst the website. First stop is the homepage, where I’ve got some incredibly basic jquery to load the five most recently uploaded posts into the main index.html. This acts as a kind of feed, and limits the effect of images on load time. In the future I might improve this to auto load more posts as the user scrolls, but for now this works fine. This code leads to some limitations however, primarily that relative load paths for images get messed up, thus the need for absolute pathing. The main code function here is simply changing the html to load the most recent pages, again more sed html manipulation.

Secondly I’ll add the pages link to the post index, easy enough here, more sed.

Third, I create a new entry in the sites rss.xml. The implementation here is as basic as it comes, and sometime in the future I’d like to change include the full article text.

For safety reasons I then commit and push my changes to a repo. One of the benefits of already being in a terminal is that can be done pretty seamlessly.

Then finally I ssh into the website and upload the new and updated content.

Conclusions

For now this all works pretty nicely, and I’m generally happy with the outcome, though I feel like it could be made faster somehow, maybe by moving from bash over to using Shortcuts? While I hate shortcuts interface and clunkiness, it would open up the opportunity for a very seamless export and upload from any of my devices.

A huge stretch goal would be to host the website myself, have a machine running in my own home, and do something a little bit like Low Tech Magazine’s solar website

If anything it’s nice to own the process of writing content for my own website end to end. As the years go on I trust companies or third parties less and less with the content that I create, and being able to have some slice of the internet completely written by me is reassuring (if not exactly the most sensible approach).

Charge Introduction

So for the past few months I’ve been primarily working on my next title. Interloper has done way better than I could’ve expected, but after two and a bit years I think it’s time to work on something new.

I’ve built a bunch of prototypes over the past year or so, every now and then taking the time to create something small, or some tiny slice of a larger game. From a spiritual sequel to Unstoppable, to some experiments with smaller game mechanics to taking some new swings at old ideas I’ve had running around, none of them stuck.

That is until Apple released the Unity Plugins at WWDC this year. There’s a lot of good API’s exposed via these plugins, including some cool audio stuff, a neato input alternative, but the one that stood out to me was GameKit, particularly Turn Based Games.

I’m a long time tabletop wargamer. I was brought up on the likes of Operation Warboard, Squad Leader, Napoleons Battles and then of course… Warhammer. My first miniature was a 2nd edition Space Marine Dreadnaught, but the first army I’d fully painted was a 5th edition Warhammer Fantasy Brettonian army. This is where my love for what became the genre of “Rank and Flank” games began. Growing up through my teenage years I’d assembled both the aforementioned Brettonian army, and then later a Skaven army. Building the miniatures, painting the ranks of rats, trying out the odd combinations of the army lists, winning and losing games were all some of the most formative moments of my life. I was extremely fortunate to have an incredibly supportive family with this hobby. My Dad, Brother, Stepdad and Uncle were all just as into the game as I was. Most weekends we’d have a game of some kind.

This is all to say, I’ve spent the past twenty years forming opinions on tabletop wargames. That through my time as a game developer I’ve felt that I can bring something to .. uh… the table.

Enter: CHARGE (working title) a tabletop wargame that spans both digital and physical versions.

The core conceit is that it should get to the meat of what makes a rank and flank interesting quickly. It’ll bring back some mechanics that’ve been lost to time, and it’ll simultaneously be a multiplayer digital title (initially available on apple platforms) and a rules set for physical tabletop play. (there’s a stretch goal of adapting the digital models as printable files for 3D printers, separately available on something like MyMiniFactory)

This is a bit of an ambitious project (why would I make games if they weren’t ambitious) and I expect it’s going to take a while to build, and I’m hoping to chronicle it’s development here.