A quick tour of Entity-Components in BotLG

I’ve started working on a better entity system for BotLG. The current code for dealing with entities — monsters, NPCs, things you can interact with in some way — is a bit of a rat’s nest of objects referencing each other, and creating a new monster or NPC means adding references in a half-dozen different places. It’s not ideal.

So, I’ve come up with a new system, using an Entity-Component pattern. There’s one base Entity class, which consists only of a unique identifier and properties for storing location and speed. More specific entities can be created by extending that class, but thanks to the Component system, they don’t really need to be. Components represent a bundle of properties about an entity, and the methods needed for working with them. For example, let’s make a rat.

let boris = new Entity();
boris.name = 'Boris the Rat';

(In actual fact, you wouldn’t make Boris like this. There’s an EntityManager class that creates entities and puts them in to a collection, so the rest of the game knows where to find entities, and the scheduler can loop through them, and so on.)

Now that Boris exists, we can add some components to him. Rats have legs, so they can move. So:

boris.addComponent(new canMove());

The canMove component (all of my components are in the format canDoThing or hasSomeProperty) gives Boris a .move(dx, dy) method, so he can be moved around the map. We should probably also give him some health, and the ability to die from any wounds taken:

boris.addComponent(new hasHealth());
boris.addComponent(new canDie());

Great! This highly modular approach means writing new actions and abilities for entities can be split into much smaller chunks, and entities can share components. It also means I can things like saying; this attack cripples creatures, making them unable to move, so:

boris.removeComponent('canMove');

One slight downside to this implementation is that you might have some code that ends up trying to perform a method call on an entity that doesn’t support it. What would happen if we tried (the hypothetical):

boris.fly(dx, dy);

Well, rats can’t fly. There’s no canFly component, and even if there was, Boris doesn’t have it. There are two options here. Either we wrap every attempt to do something up in a check:

if (boris.hasComponent('canFly')) {
boris.fly(dx, dy);
}

or we take advantage of the .try() method that every Entity has:

boris.try('fly', [dx, fy]);

Entities, components, actions and certificates

Saw this article about LetsEncrypt, the service I use to get my HTTPS certificates, accidentally revoking millions of certificates… and then noticed the email from them in my inbox informing me that they’re very sorry, but all of my domains are affected.

On Wednesday, March 4, Let’s Encrypt – the free, automated digital certificate authority – will briefly become Let’s Revoke, to undo the issuance of more than three million flawed HTTPS certs.

The Register: Let’s Encrypt? Let’s revoke 3 million HTTPS certificates on Wednesday

Luckily fixing it was as simple as SSH’ing into my server and running certbot renew –force-renewal, so it was no great emergency. Still, I imagine tomorrow a whole swathe of domains across the internet will be suddenly insecure and promoting browser warnings all over the place.

In roguelike development news, I for some work done on the new Entity/Component/Actions system I’m going to be using for BotLG.

So far I’m really pleased with it. Soon I’ll begin putting it into the BotLG codebase and converting the existing game verbs over. It’s so much cleaner and easier to expand than the current entity/NPC system.

Merchants, items and inventory

Two major things and a whole bunch of polish this week. I wrote earlier about improving procedural dungeon generation, so I won’t rehash that; the other big feature this week was getting merchants and shops into the game.

I now have the ability to add buying and selling as actions when interacting with an NPC. Each NPC merchant will (currently) buy any item, and has a list of items that they will sell to players. Heavily inspired by old console RPGs like Final Fantasy and Pokémon , there’s also a shop location. I can alter this on a case-by-case basis, to customise the merchant themselves, the products they have on display, and the crafting workstation on the left.

I think I’ve got all the bugs, exploits and edge-cases worked out (like adding an item to your sell list, then consuming it in another window, then completing the sale of the now non-existent item, for example), but it’ll be interesting to see what players come up with. Buying and selling are kind of an important, potentially economy-breaking feature if there’s any horrific item and/or currency duplicating bugs left in there, so I’ll be keeping an eye on it for a while.

Because I’d spent so much time working with merchants and therefore items, I also made some improvements there. Can you believe BotLG contains 57 different items already (and I feel like I haven’t really even started on generating item content yet)? First, I consolidated the item types into a much smaller set — With that done, I added a dedicated inventory screen, which can be filtered by these new categories. Then, as a last bit of polish, I made it so that wherever an item is displayed, it shows an icon next to the text label. I’m really happy with how it looks, and now the console looks a bit more exciting while you’re gathering resources:

So this leaves me with just two major mechanics to implement: account-wide storage and account-wide progression through character retirement, which I’m hoping to get done next week. After that it’s just bug fixes, content and polish. I really want to completely revamp the starting area, so that players can get into a dungeon much quicker — and a more exciting one than the pretty trope-heavy Rat King’s Nest. This week (and last) have introduced a lot of new stuff, and the current maps don’t really show them off to the game’s best advantage; I actually think I’m going to hold back on making these things live until I have some shiny new locations in place.

This week’s changelog

Here are the edited highlights from this week’s changelog. You can view the whole list here.

  • As usual, BotLG is a little less idle and a little more roguelike. Every type of gathering node is now a limited resource. To compensate for limited resources, lowered global action duration to 3 seconds (from 8 seconds)
  • New skills: gathering, hedge magic, mining
  • New items: plum-nose mushroom, gorgeous plum-nose mushroom, myconic essence, myconic potions, part I, rough stone, copper ore, iron ore, silver ore, lump of coal
  • New recipes: distill (gorgeous) plum-nose mushroom into myconic essence; brew small healing potion from myconic essence
  • NPCs can now buy and sell items
  • Looking at a skill’s details (click the name of a skill from the skills panel) now shows which recipes you both know and have yet to learn. Learning a recipe now grants the corresponding skill at level 1 if you do not already have it.
  • The inventory panel now only lists the most recent items received, but contains a link to browse your entire inventory, which is filterable. Players can click an empty equipment slot to open their inventory filtered for items suitable to equip there
  • Each floor of a procedurally generated dungeon now requires a randomised quest to be completed before you can descend to the next floor. Closing the page or refreshing while in a dungeon will cause you to lose some of your inventory
  • Location name and difficulty is now displayed as the minimap window title
  • Consolidated item types down to: accessory, armour, bones, component, drink, food, ingredient, junk, potion, quest, recipe, weapon
  • Wherever an item name is displayed, its icon is also shown
  • Monsters now slow down when the player is chasing them, and will pause if they end up adjacent to a stationary player

Procedurally generated dungeons

I finally got around to improving the way procedurally generated locations work. Now, locations can have a procgen tag, which causes the game to look for a default set of rules for generating the location when the player enters it. This lets me specify things like which dungeon generation algorithm to use, what tiles to use, which monsters to make present, and things like that.

Additionally, I can specify a list of overrides on a per-level basis, so I can make certain floors of a dungeon different. For example, the first few levels could be brick-and-mortar dungeons, before devolving into rock face caverns with their own colour scheme and different monsters present. Another option available to me is to specify a premade map, so I can have fixed points within a dungeon — boss chambers, alters, shops, or whatever. Within these premade locations, I can even specify which position and level within the dungeon an exit should take you to, so I can also make shortcuts around larger labyrinths. All this should let me build some more engaging dungeon locations.

Alongside this dungeon revamp, I added a couple of complimentary features: procedurally generated quests and quest-locked portals. BotLG is a little unusual in that monsters won’t attack the player; combat is only initiated by the player bumping into a monster themselves. Now, this would mean that you could carefully navigate your way to the bottom of a dungeon and never face any actual danger, which is ridiculous.

To help combat this, I implemented a flag on portals (like doors, staircases, etc., any tile that moves you to another location) that makes that portal only work if a specified quest has been completed. When you enter a dungeon floor, a quest template is picked from a list, and the conditions to complete it are adjusted based on the current difficulty level. Players can only use the stairs down to the next level once the quest is completed; if the player leaves the dungeon, the quest is abandoned.

I’m going to use this system to flesh out the Rat King’s Lair, the first procedural dungeon the player will come across, and then add in a couple more. I’m increasingly thinking I need to revamp the starting area so the player can more immediately jump into some dungeon crawling without having to find the Rat King’s Lair, which is a fair distance away from the player’s start location, and a little off the beaten track.

Work, work

I have some news. About four months ago, I quit my job to work on BONES of the LOST GOD, and, after a few mis-steps and prototype dead-ends, it’s now nearly finished. I’m really pleased with it and the work I’ve done.

However — I need to go back to work and start earning some money, and so I’m taking a full-time devops role at an e-commerce company. However, I don’t start for three weeks which should give me time to finish off, do a little refactoring, and get the game into a position where I can more easily add further content on evenings and weekends.

I’ve got four main things left to do:

  • Re-balance combat and the monsters. Monsters (and combat with them) doesn’t scale very well at the moment as you level up; in particular attack quickly outstrips defence, and combat is a bit swingy at low levels, which can feel frustrating. So this needs looking at, and I have a big spreadsheet of numbers on the go at the moment.
  • Improve procedural generation of dungeons. This works, but the environments it generates are not very interesting. I want to improve the environments it generates, add more dungeon templates (forest, cavern, dungeon, caves etc.), and make delving into dungeons a more rewarding experience.
  • Implement merchants and account-wide storage. So far there’s no UI for buying or selling items, and no UI for long-term storage and retrieval of items. Both of these are going to share some UI and behind-the-scenes work, so I’m bundling them together.
  • Character retirement and account-wide progress. Right from day one I’ve envisaged BotLG as an idle/incremental game, and the one key genre mechanic that’s missing is the idea of prestige; that is, giving up all your current progress for a long-term bonus. I’ll be implementing this by allowing player characters to retire, at which point they will provide resources periodically based on their skills.

I don’t regret doing this — I’m incredibly proud of what I’ve created — and similarly I’m not sad about going back into work; I’m looking forward to it. If I get everything listed ticked off, the game will contain all the major mechanics I envisaged, so I can’t complain.

I’m going to keep the Patreon campaign open until the end of February and then close it; it seems a little disingenuous to take monthly pledges for something I can’t hand-on-heart say I’ll be working on most of the time. If you want to continue to support BONES of the LOST GOD, I have a ko-fi donation page up and I’m going to try and use that a little more.

This is definitely not the end of the project! There’s still a tonne of content to implement (on top of the things listed above) and I have a feeling I’ll be updating and supporting this for a long time to come. Thanks for sticking around.

Questing and crafting

Two new things this week; quests and crafting.

Quests

When you enter a location containing an NPC who has something for you to do, you’re presented with a little message:

When you find the NPC, you can interact with them to see what quests they have available, and to hand in any you have completed for them in return for some rewards.

So far, the quests system can handle three different types of quests; all of which will be familiar to RPG players:

  • Kill a specified number of specific enemies
  • Acquire a specified number of items
  • Acquire a specified number of quest-specific items, which only drop while the quest is active

For the gathering items quests, those items can be from the result of performing a gathering skill, like fishing or logging, or looted from monsters. All quests can have multiple objectives. Quests can be one-off or repeatable, and can require the player to have completed previous quests before they become available, allowing me to chain them together to create a quest line.

Recipes and crafting

The second big thing of the week was adding in recipes and crafting. Characters can learn recipes from various items, which then enables them to do some crafting. At the moment that’s limited to cooking and woodworking, but there’s a few more production skills in the pipeline.

Once a character has learnt a recipe from a book or scroll, they can approach a crafting station — the campfire in the traveller’s camp to do cooking, for example — a little window pops up allowing the player to select a recipe and begin creating items.

Because BotLG has a strong gathering/crafting focus, I expect I’m going to be writing a lot of recipes in the next few weeks (and probably authoring a huge spreadsheet in an attempt to achieve some semblance of balance).

Miscellaneous other tweaks

I’ve also done a fair amount of smaller tweaks and improvements this week:

  • There’s now a little minimap that shows the surrounding area with interactable objects highlighted
  • Player characters and NPCs now have a configurable speed, so different monsters can move around at different rates; the player can also equip some boots of striding to boost their movement speed
  • Pop-up dialogue boxes now stack, so you can click an item referenced by a quest, for example, and keep your position
  • Side panels now remember if they’re open or closed between sessions
  • New reading, eating, and potion-quaffing actions; potions are automatically consumed in combat as required
  • Various CSS and JS tweaks

People, places, and things

I’ve worked on three things, mainly, this week. I started out by implementing NPCs the player can interact with. Under the hood they’re essentially just the same as monsters, only they have a dialogue system for their main action, instead of combat. But there’s no reason why in future you couldn’t fight NPCs or parley with monsters. I created a simple branching dialogue system, where you’re presented with what the NPC has to say, and then you have some pre-canned responses to choose from that can lead to further dialogue.

BONES of the LOST GOD is based on a play-by-mail Labyrinth Lord campaign I ran back in the day. At the centre of that campaign was the city of Rooksfoot, an economically-thriving but morally dubious city dominated by a magical arena where sell-swords and adventurous hopefuls would fight to the death for a cheering crowd and the promise of fame and riches. I’m both excited and nervous to be re-implementing the city in this game, and having some NPCs seemed like a good excuse to put the first hint of the city in-game:

Image
Image

Getting past that guard forms the opening segment of the game, and forces the player to go explore the surrounding area. I have two or three different ways in mind for the player to get into the city for the first time, and once they’re in, coming and going as they please will become much easier.

The next thing I worked on was items. I made the view item screen much more detailed and attractive, and made a bunch of new items to support initial character creation, so new characters now receive a set of starting gear better tailored to their rolled attributes. Here’s an example item:

It’s listed as a two-handed weapon, with a strength attribute, so performing basic melee attacks with it will use your strength attribute. Most weapons are strength based, but lighter, more finesse based weapons will use dexterity, instead.

But the main thing to note here is how wielding the item — a staff in this case — actually grants the character access to two actions: fireball and basic attack. For the first time, player characters can now perform different actions in combat, instead of just wailing away with basic melee attacks round-after-round. I’ve been wanting to implement this for weeks, and finally it’s here.

BotLG is a classless game, but characters have attributes and items available to them that are very much in the mould of the traditional fantasy RPG. How your character behaves in combat (and elsewhere) is very much decided by the items they choose to equip themselves with. You can load yourself up with heavy armour, sword and shield and play a strong warrior type, or wield a poisoned dagger and light armour and be the assassin-rogue. This also allows for some neat customisation. If you want to be something a little more unique — a necromancer-bard, perhaps — that’s fine! Get yourself some evil robes covered in death-magic runes, and equip the biggest, baddest trumpet you can find.

Note: neither evil necromancer robes nor trumpets of any size have been implemented (yet). But they could be! And you’d get different spells and actions from each, and they might even synergise a little, and you’d be the happiest necro-bard for miles around.

Image

My next steps are to spruce up monsters, so there’s a bit of variety as you’re exploring dungeon-like locations. Monsters work mechanically the same as player characters, so they also benefit from equipment granting actions to use in combat, but so far none of them are wielding anything that provides anything other than a basic attack.

In tandem with improved monsters, I want to add some quests into the game, so there’s a bit of structure to the slaughter. I already have code written that tracks when you need to collect items for a quest, how many you have, and if a monster should have a chance to drop a quest item. All that’s missing is some UI to allow players to start and complete quests, which I can now tie into the NPC dialogue system.

But is it a roguelike?

It’s been an interesting week for thinking about the word roguelike. On Tuesday, I was finally forced to admit that the game I am making is, in fact, a roguelike:

I’ve been working on procedurally generated maps this week, you see. And with that final piece of the puzzle slotted into place, I finally felt like I had enough elements to realistically consider BotLG to be a roguelike game. Not a traditional roguelike, perhaps, but a roguelike nonetheless.

It’s since turned out to be the perfect week to have these thoughts, as yesterday @humbit set r/roguelike on fire by publishing the excellent blog post, The “Roguelike” War Is Over. I’m firmly in the camp that @humbit argues for; language changes whether you like it or not, and roguelike doesn’t mean the same thing today as it did Back In The Day, and that’s okay. What’s important is that everyone knows what you mean when you say it — yes, even you, grumpy grognard, even if you don’t like it — and it’s easy enough to just say traditional roguelike if you really, really, want a pure turn-and-text based experience. No-one has to lose out here.

The obvious problem with discussions about roguelike vs roguelite is that they’re UTTERLY BORING. There’s nothing new to say but we’ve been treading the same ground for literally years. It’s beyond beating a dead horse. It’s beating a zombie horse. Can we just… stop?

The “Roguelike” War Is Over

So is BONES of the LOST GOD really a roguelike — by anyone’s standards? I think so. Let’s take a look through the Berlin Interpretation guidelines as a flawed but decent-enough starting point:

High-value factors

  • Random environment generation: Yes! Dungeons and wilderness are now procedurally generated. There are some fixed-point locations that are consistent, however.
  • Permadeath: Yes! Characters die, and when they’re gone, they’re gone, along with all their stuff. There is an account-wide storage system, so you can “bank” some items between characters, which softens the blow a little.
  • Turn-based: Sort of! Combat is turn based. Movement is not, but combat and movement are modal, which we’ll get onto in a moment.
  • Grid-based: Yes! All the map locations are grid-based. Players and monsters of all sizes take up one tile.
  • Non-modal: No! Probably the biggest rule breaker here, but movement and combat occur separately from each other, and what actions are available to you very much depends on what you’re currently doing.
  • Complexity / Resource Management: Eventually! So, there’s not a lot of complexity in the game yet, but several systems are in place that will result in complexity as more items, monsters and effects are added. So watch this space on this one.
  • Hack’n’slash: Yes! Killing lots of monsters is important in roguelikes, and there’s plenty of monsters to kill in BotLG.
  • Exploration and discovery: Yes! I spent enough time on making field-of-view and fog-of-war work nicely alongside a mix of hand-made and procedurally generated maps, and all the best stuff will be tucked away in dungeons and the wilderness, so I hope exploration will be a strong component of gameplay.

Low value factors

  • Single player character: Yes! I originally envisaged BotLG as a party-based RPG, but after some play testing, I’ve fallen back to a single character to speed things up, and I think it was the right decision.
  • Monsters are similar to players: Yes! They share the same attributes, skills and equipment as players, and use the same rules for movement and combat.
  • Tactical challenge: Not so much! BotLG is slightly more about the strategic long-game of refining equipment and skills over the course of multiple characters, and combat is abstracted thus that there are not many tactical decisions to make.
  • ASCII display: Nope! The game world is represented with graphical tiles, and I think it looks great.
  • Dungeons: Yes! Not just the traditional rooms and corridors, but also cave systems, overgrown forests, mountain passes, boggy swampland, etc. etc.
  • Numbers displayed up-front: Yes! There’s no secrets here. You can see all your attributes, item properties and damage numbers.

So is it a roguelike?

I think it is! A weird one, maybe, but definitely in the ballpark! More importantly, I’ve started to think of it as one, and it’s partially how I would describe it. It still has all of its initial idle/incremental features, so I’m thinking of it as an idle/incremental RPG with a roguelike world. That seems to cover all of the bases. It’s not a traditional roguelike by any stretch, but it certainly ticks enough of the boxes.

It does have some distinctly unroguelike elements. As you and the monsters/NPCs are wandering around the map, there’s no taking turns; everyone moves at the same time, so there’s no tactical tile-hopping and waiting. But that doesn’t matter, because combat is initiated only by the player deliberately “bumping” a monster, and combat is modal, so there aren’t any positional considerations. Because a big part of the game is idle/incremental gathering and crafting, I ruled that is was not important that monsters could attack you when they wanted to. It’s entirely possible to play out a character to the level cap as a pacifist gatherer/crafter, though you’d be missing out on a decent chunk of content– crafting some items requires components only obtainable through looting monsters. What’s important is that you could play the game this way, and when you eventually retire that pacifist crafter, you’ll get account-wide bonuses reflecting the life they lived.

Making a monster

I’m working on combat. It’s kind of slow going, because it’s the most involved part of the game, and it needs a lot of other structures and objects to be in place first. Not least of which are monsters. Thanks to an audience suggestion, I’ve started with skeletons, a classic 1 hit dice monster.

For that, I needed a way of creating new monsters, keeping each unique copy of them persistent in the database, and managing them. I also wanted a way of making sure that combat could occur between players-and-monsters, monsters-and-monsters, and players-and-players. I big part of the BONES of the LOST GOD setting is battling in the magical arena at Rooksfoot, so I need to support all those types of combat.

The easiest way to go about that is to make sure that both Monsters and Characters are interchangeable; Monsters should implement the same interface as Characters. Looking through the game ruleset I’m using, with a bit of fudging and the invention of some creative items (monsters will have to invisibly equip items like “dragon’s hide”, “dragon claws” and “scroll of dragon’s breath” to set their AC, damage output, etc.) I don’t see why that shouldn’t be possible. So after a bit of work and some refactoring, I now have some new factory and blueprint objects.

When I want to create a new type of monster, I just have to crack open my trusty Monster Manual, and create a corresponding new Blueprint. This defines the monster’s name, appearance, attributes and statistics, equipment, and so on. I can create permutations of the same monster by defining some methods in there to return different values each time.

Then when it’s time to spawn a monster into the world, I take the Blueprint and give it to the Factory object, which creates a new Character and applies the settings from the Blueprint, resulting in a brand-new character/monster saved to the database. In fact, it’s so nice and flexible that I named them NPC Factory/Blueprints; and I’ll be using them to generate townsfolk, quest givers and the like, as well as monsters. It’s also pleasing to me that everything that’s alive and active in the game world is stored away in the same place in the database. There’s some enumerated flags in there so I can tell PCs and NPCs apart at a glance, and it seems to work quite nicely.

(In theory, all this means monsters and NPCs could be recruitable as player characters, further down the line. It also means it’s trivial to turn or clone player characters into NPCs; which is how I intend to do asynchronous PvP combat — it’s almost like I had a plan for this all worked out!)

Last but not least, I’m changing the way Characters are attached to Users; instead of tying them directly to the user’s account as I’m doing currently, I’ll be introducing the concept of a Party; a container for a list of Characters. Having this intermediary step means I can write combat as an event that happens between two or more parties, without having to consider who owns the party; all the UI will have to do is allow the player a way to assign actions to their Characters instead of AI and combat will progress non-the-wiser. Actually writing the monster’s AI, though, is a task for another day.

Character and Item generation

I’ve been working on BONES of the LOST GOD’s Character and Item generation this week. First of all, here’s an example character, wearing a few items:

The stats rolled might look a little off if you’re used to Dungeons & Dragons‘ traditional 3-18 range. Instead, each ability score falls in the range 11-16, with lower numbers being much more prevalent. Ability bonuses scale much more linearly as well, with no dead spots, so getting an extra +1, even at the low end, should feel like a genuine improvement. It’s going to be a brutal game, but you’ll have a whole party of hapless heroes to use, and an infinite stream of fresh recruits, so the odds are still in your favour.

I’ve also got some encumbrance and quality ratings in there. Each item generated is unique (albeit built from templates), so I can track the durability of each item separately. Because your items can break, and you can’t carry an infinite amount of stuff, there’s some tactical decisions to be made before setting off into the wilderness. It also opens the door for having perishable items, field repair kits, and all sorts of other little mechanics.

You can have a play with the generator herelet me know if you manage to roll up someone cool! Both player characters and NPCs are going to be drawn from the same pool, so each time I need a NPC, or to populate a roster of potential new recruits, they’ll be coming from the characters created by this generator.

Next up I’ll be fleshing out the items a little more, and then having the game automatically generate a new party of characters for newly-registered players.