Happy Christmas, I guess

Even though I haven't written anything for a while, I've still been honing my craft. I've been reading a lot -- this repository of design patterns, and this collection of tips for implementing Clean Code in PHP. I feel like I've learnt a lot in the last few weeks, and I'm very happy with that. Hopefully it will result in a better project in the long run.

I'v been reviewing the Event and Rulebook objects I have already, and I thnk the Rulebooks need a quick refactor -- such that the individual books (like MazeRats) implement the core Rulebook interface, for example. This will let me be a lot more flexible when I'm writing Events, and should allow for events which implement rules from multiple rulebooks (for example). I've also got this nascent idea for implementing some rudimentary "AI" that will let NPCs interface with the world by running their own events -- and the same events that player characters do -- which could result in some really fun interactions.

It also implies players could own -- or subcontract -- NPCs to run events for them; so henchmen, artisans-for-hire and the like become a distinct possibility. I really like that idea.

No more zero days

There was no changelog discussion blog post this weekend, and neither was there a r/roguelikedev Sharing Saturday thread. I didn't have anything to share. Over the last week, according to cloc, I added only 45 lines of code to the project. It was a slim week. I'm still going though, albeit much slower than I would like. Honestly, this weekend, I just couldn't be bothered, and working on BotLG seemed like a colossal waste of time. I'm going to chalk that up to a general melancholy, and continue on regardless. What else can I do?


The whole "No More Zero Days" thing is irritatingly twee, but there's probably something to it, nonetheless.

So where are we up to? We have characters, locations, and a sense of location. We have some dummy items and a dummy item-creating process, so we're ready for events. The handful of lines of code I produced last week are working towards that -- there's a skeleton Event object, and a corresponding ItemFactory.

The EventFactory's main method is generateRandomEvent, which is passed both a Character and a Location. It then consults a list of template events (stored in the database) to find a suitable Event for the character and location, and then customises it -- by adjusting duration and difficulty, producing values for any random qualities, and so on -- and then returns a complete Event object. These Events can then be stored away on a per-player basis, so each player gets their own selection of things to do, based on their specific party. So far it seems like a nice, flexible system that will allow me to serve up a mix of hand-made and procedurally generated things to do.

Next steps -- write a few example Events, and come up with a first-pass at the UI for displaying and starting them.

Midweek monsters

I had sort of thought this would be the week where I started implementing the base Event object that would power most of the actions that take place in BotLG, but thinking about events lead to thinking about of the most common types of event, a combat, and that in turn lead to thinking about monsters, which leads me here -- to the @maze_monsters twitter account I set up earlier this year.

Every hour, the @maze_monsters account tweets out a randomly-generated monster, powered by the brilliant (and Creative Commons licensed!) tables in Maze Rats, and it's these same types of monsters that I'm ultimately aiming to use in BotLG; albeit with a little more procedural generation brains than the pure randomness that's served up on Twitter. Here's a couple of recent examples:

A system where characters can learn the strengths and weaknesses of monsters over multiple encounters and then elect to bring along items to help overcome and exploit them would be great. Getting events implemented is still my next step, but so far this week has consisted of a lot of thinking, writing lists, and organising. Lots of necessary work, to be sure, but it's oh-so-much administrivia and not so much concrete work for the changelog so far. It'll be worth it in the long run, I tell myself.

Changelog, week commencing 2018-11-19

After much wailing and gnashing of teeth, account creation is now finished! (Or a first pass at it, anyway). Oh, how tedious this kind of basic web app stuff is, but it's done now (for now). New players can create an account, and then select their first character from a pre-generated list of unsavoury types.

"The people of BONES of the LOST GOD aren't particularly heroic; not to begin with, anyway. But by picking one from this rag-tag bunch of characters, you can start your adventure. Perhaps they will become a great fighter, either in the great Arena of Rooksfoot, or in the dark dungeons of the world. Maybe they will be a great artisan, a gilded merchant, or study the ancient and arcane arts. They will be lucky; most will die in poverty and obscurity. Such is life."

As always, you can see the live changelog here, but here's this week's entry:

[!] Simple account creation screen which forwards to a character select screen
[!] Created roster selection page to allow players to recruit characters
[!] Created Item class, database table, and a basic collection of items
[+] Rewrote database methods so I can call BOTLG::db()
[+] Added Save and Load methods to character object
[+] Added class templates to character object
[+] Characters now have portrait images and associated colours
[+] Characters now have class features
[+] Player object pre-loads characters and won't needlessly rebuild them
[+] Moved bootstrap functions from Page object into their own collection
[+] Router can force a certain page view for logged-in players
[-] Router can now load arbitrary javascript files into page footer
[-] Portrait image for mobile splash screen
[-] Fixed some cookie-related bugs
[-] Moved some PDO database stuff out into its own class for safekeeping
[-] Moved routing data into a separate file to maintain my own sanity
[-] Implemented DKIM signing for outgoing email
[-] Routine server maintenance

I'm actually quite pleased with how the character selection screen turned out (referred to internally as a "roster"). It's got a pretty hover highlight, the explanation text does it's job in a reasonably succinct manner, and the color-coded portrait images turned out quite nicely. But really, best of all, it's done. Perfect is the enemy of good, or done in this case, and I'm mainly just glad I don't have to work on this little corner of the system any more. Instead, I can start on the good stuff -- getting those player characters out into the work and completing tasks.

One last thing before I sign off for the day. This character was generated while I was working on the roster screen. The layout isn't the same as it is now, but he caught my eye for having a perfect combination of portrait image, name, and descriptors:


Sometimes the random number generator gets it just right. I'm hoping for a lot more of these moments as BONES starts to take shape.

Account creation, in progress

I'm in the middle of writing the sign-up pages and I've hit a bit of a creative roadblock; I'm hoping that writing about it will help.

It's perhaps a little early to be doing player sign-up, but I thought I'd get it out of the way early for a number of reasons. First, it lets me to get some basic, boring, but essential functionality out of the way, so I can get onto the more entertaining parts. Second; it forces me to answer a bunch of fundamental structural questions about the game: how are the Player and Character objects arranged and stored? What are the minimal set of properties a character needs to function within the mechanical rules of the game?

Over the last few days, I've made some good progress on the object side of things; I now have Player and Character objects with a good set of methods on them, and a neat and easy way to generate new characters, save and load them, and assign them to players. Where I've started to struggle is with the UI for displaying and selecting characters -- the first action a new player will take upon signing up is selecting and customising their first party member from a roster of pre-generated characters.

Here's some freshly rolled examples:

Orion Berrycloth
corpulent, matted hair, deep voiced
STR 2, DEX 0, WILL 1

Mortimer Slitherly-Belvedere
coltish, gold tooth, whispers
STR 0, DEX 2, WILL 1

Fitzhugh Culpepper
trim, missing teeth, spouts random facts
STR 1, DEX 0, WILL 2

Cleopha Graveworm
statuesque, sunburned, flowery speech
STR 1, DEX 2, WILL 0

Elsbeth Slitherly
brawny, acid scars, nervous
STR 2, DEX 1, WILL 0

Fox Southwark
gorgeous, battle scars, squeaky
STR 2, DEX 1, WILL 0

Godwin Tumbler
aquiline, birthmark, gravelly voice
STR 0, DEX 2, WILL 1

Jilly Dankworth
gorgeous, sallow skin, protective
STR 1, DEX 2, WILL 0

Despite what I wrote earlier; I have settled on using Bootstrap for the front-end (and I have a nifty Bootstrap object for outputting pre-canned HTML fragments). My initial thought was to use the Carousel component to allow the player to flip through their roster of pre-generated characters. It works decently, and I can hook into it's slide events to show additional details alongside the carousel, but I'm not happy with how it looks on mobile. Late last night I hit on the idea of using a more square layout -- two side-by-side on desktop, then stacked on top of each other on mobile -- and having the player swipe through characters, Tinder style. That might work better, but I think for now I'm just going to do the simplist thing that could work -- a list with some radio buttons. Fancy styling can come later.


Changelog, week commencing 2018-11-12

Inspired by this FAQ Friday thread on /r/roguelikedev, which lead me to keep a changelog, I've started keeping a log of everything I've done on BotLG. I'll be keeping it all in one file, divided up by weekly chunks rather than version numbers. You can always read the plain text, latest version at, but I'll also be doing occasional blog posts like this one, where I'll expand on what I've been doing.

So, without further ado, this week's changelog:

[!] New and important features or content
[+] Changes to existing features or content
[-] Minor tweaks, bug fixes, miscellany
[?] Arcane and unsolved puzzles, disturbed thoughts

Week commencing 2018-11-12
[!] Signed unholy covenant with the LOST GOD to resurrect this accursed project
[!] Added splash screen with mysterious countdown timer
[!] Implemented the Router and Page objects to handle URL routing
[!] Pages now consist of Models and Templates to provide a nice MVC-esque divide
[!] Created working log-in form action and template
[!] Created log-out action
[!] Created simple navbar menu
[!] Created Character object with functions for generating names and personalities
[+] Added support for public, private pages with optional redirects
[+] Added support for custom CSS, headers and footers on a per-page basis
[+] Added FontAwesome icons to navbar elements
[+] Page model can output JSON instead of HTML
[+] Converted existing session code to use the Router object
[+] Logging function, database table, page view
[+] Simple admin flag for Player accounts, routing options
[+] Nice little function for returning random elements from array
[+] Wow, that regex for URL rewriting is really something, huh?
[-] Created favicon
[-] Fixed up some minor CSS issues
[-] Slight adjustments to blog stylesheet, header image
[-] Ongoing tweaks to mobile view

First of all, the symbols. The idea is to make the file a little easier to skim through looking for the important stuff -- players will want to focus on the [!] that marks out new content primarily, and may want to dig into [+] lines, which denote changes to existing content. Only the super-fans will care about [-] lines, the most basic bugfixes and mundane dross that nonetheless needs doing.

There's a lot of [!] important and new lines this week, because this is essentially the first week of development work -- almost everything is new! I've mainly been working on the basic objects that make up the game's structure; there's a lot of behind-the-scenes scaffolding work here. I've settled on three main objects so far:

  • BOTLG.class is actually one of the slimmest classes so far, but it deals with low-level authentication, talking to the mySQL database, and provides some helper functions that lots of other objects will lean on.
  • Router.class does HTTP routing, surprisingly. All requests are directed through one script, and the Router object handles them (very nicely, if I do say so myself). It's main goal is to transform an HTTP request into a bunch of configuration options for this next object...
  • Page.class does the heavy lifting. It takes a successful request from the Router, and generates the content to send back. It has Models, which do something, and Templates, which format results from the models and generates the actual pages you end up looking at.

It's a really nice, flexible system, with a clean delineation between processing and content display, and it's easy to add new pages and output types (like a route that results in JSON, for consuming via an AJAX request). I'm really pleased with how this has turned out, which is important, because this is the stuff making up the most fundamental, building-blocks that everything else will rely on.

I've also got two objects that are leaning toward more actual gameplay purposes, which is of course what we really care about. I have a Player object, representing the real, actual person playing the game -- email addresses, passwords, account-wide settings -- important but dull things like that; and a Character object, for holding the various heroes and NPCs the players will both control and interact with.

The next step is to create some behind-the-scenes functions for creating fully fleshed-out characters, and then to create some UI to allow players to recruit their first hero and get into the main gameplay loop of adventuring, exploring, crafting and carousing with them. This sounds easy, but that first step into UI creation is going mean a lot of Javascript / AJAX / JSON scaffolding will need creating first. I think I can make a few tweaks to the Router and Page classes to speed that along, but I'm going to need a corresponding "application" object up and running in Javascript in the web browser to handle everything. That's going to be fun. 

Home ← Older posts