1. The Hand of Merlin
  2. News

The Hand of Merlin News

Dev blog 28 - Making an encounter

Hey folks!

This time around, I’ll be talking about the encounter syntax. The reason why I’m talking about the internal systems sometimes is because being on Serious Engine, it gives us the possibility to deploy the editor as well. This opens up the game to modders to create their own content for the game, which includes new characters and monsters, new Skills and Spells, new Guardian Cores, and (today’s topic) new encounters.

Early on, we knew we wanted each world location to have a small story encounter, similar to FTL. The initial implementation in the old engine used Lua to define each encounter. It followed a tree or graph structure, where each “page” seen in the game was defined with a couple of strings: the text itself and the text for the possible choices the player can make to drive the encounter forward. Since this was all written in Lua, part of it was essentially code that drove the transitions between the different pages and choices, another part of it was text to show in the UI and the last part was providing rewards, like gaining or losing gold or supplies.



When Jonas and Verena Kyratzes joined the team, we knew we didn’t want them to bother with writing the code, so we decided to make a special file format for the encounters where the only thing you’d need to think about was writing the flow of the encounter. This boils down to writing a declarative list of elements that define the encounter: encounter name, default image, and a list of pages with their options. We went with a text format because that's what the writers are comfortable with, but it also means creating a visual tool isn't too difficult because all it has to do is spit out the file with the same format. It's something I'm interested in trying to make at some point.

Each encounter starts with a header of sorts, where we define the name, default image, type, and zone. After that, we start listing the pages that form the encounter. Every encounter has to have an “Intro” page - this is the first page we open when an encounter starts. Each page is defined by the text on it and a list of options that form the choices the player makes on the page. Each option can have a large list of conditions and triggers. Conditions are checks that control whether the option can appear on the page and if it does, whether it’s enabled (clickable). Triggers are side effects that happen after clicking the option - gaining or losing currency, recruiting a hero, acquiring a relic, or setting some session or profile variables. These variables can be used by other encounters to control their internal flow, like setting up long term rewards. Each option has to link to a “next“ page which should open when that option is clicked. This is the name of the page (which can be any page), or a special value of “END” which ends the encounter.



There are 3 types of pages we use: normal pages, fight pages, and wheel pages. Normal pages are the standard generic page you can see in any encounter. Fight pages are not really pages you can see but are used to start a combat map. Wheel pages are incorrectly named due to historical reasons but are used to spawn cards to provide the player with a random choice. There are improvements we’re planning with the cards, but that’s a topic for another time (when we add them).

A lot of these also allow a way to randomize things with the OR keyword. For example, the next page for an option can be chosen between multiple possible pages - Page1 OR Page2 OR Page3, etc. The cards also define their individual next page, which again opens up a multitude of possibilities. Finally, using session or profile variables, it's possible to start the entire encounter on a page that isn't strictly the Intro page, which we occasionally use for making the encounter different based on the chosen king for that session.

Thanks for reading! This was a very general overview of the encounter syntax. We have some internal documentation for this which will be exposed to modders when/if the editor is released, and I'll always be available for questions about it should things be unclear.
If you want to ask those questions straight away, join our Discord server and ask! I also occasionally post stuff on my Twitter.

MarkoP

Dev blog 27 - World gameplay changes

Hey folks!

Recently we had a discussion about furthering the development and improving the world map. Our writer Jonas gave an idea of reducing the number of world locations so the maximum number of moves to reach the end of a zone is lower - previously our critical path was about 22 locations, and now we’re reducing that to around 14. The idea was given as a way to make each location more impactful but is also causing a number of side effects.
One of these is it reduces the total number of world locations. Having fewer locations on the map makes it easier to parse where to go. We had to increase the size of the models that represent the locations because they were too small now that there were fewer of them - the map seemed too sparse.



Another effect this change has is to the frequency of other node types. In the old 22-long path, the Arcane and Heroic world locations (where you get encounters related to guardian cores and heroes) we’re fairly spread apart, with a lot of regular encounters in between. In the new 14-long path, you’ll get combat or special encounters much more often. We’ve also changed our internal random generation code to only spawn Arcane and Heroic locations randomly, Cities are now manually placed in the world to allow for known locations across runs. Each run will also feature a different layout of location connectivity, so not every run will be exactly the same.



If you’ve kept track of the development and some previous screenshots, you might have noticed these screenshots showing a different model for the locations. We’ve updated the models for the locations to follow a similar style, make them more consistent and solve some problems the previous models had, like being hard to parse from directly above or specific angles. The new models are also animated, which really makes the world feel much more alive.



The world steadily progresses it's state of corruption as you go through it. This manifests in some locations on the world becoming corrupted, which changes their visuals and the encounter at the location. Corrupted locations have a much higher chance of producing a combat encounter, and Heroic and Arcane locations will in most cases require combat in order to get to the reward (that being a Hero or Guardian Essence).

Thanks for reading! If you want to chat with us, we’re all on our Discord server, and I occasionally post stuff on my Twitter.

MarkoP

Dev blog 26 - Enemy AI

Hi there.
This week I wanted to talk about how we made the enemy AI.

The requirements for the AI system were apparent a long time ago before we moved to the Serious Engine. Our units each have a list of abilities they can use, and each of those abilities can be used in an area around the unit, determined by the unit range attribute and the ability range configuration. As humans, we can immediately know whether using an ability on a tile makes no sense because we know instinctively it would have no effect - like using a damage ability on a tile where there are no units. Unless it’s an area effect thing, but we can also intuit that very fast.

The AI has to evaluate using an ability on each tile until it can safely determine that “move” makes no sense. I use the term “move” here because I started thinking of our AI as a chess program. A single unit will have many abilities and has to evaluate each one being used on every tile in range to decide if that makes sense, and find the “best move”. We do this for every AI unit that can act, so the data set of [unit, ability, tile] (you can read this as “unit using ability on tile”) is evaluated, given a score, and stored. After all possible combinations of that data set are calculated, the AI picks the best one and runs with it.



Our entire AI is data-driven through the configuration of the underlying utility AI system. We call this the Brain of the unit, and it contains descriptions on how to use a specific ability. The unit might know how to use an ability, but it can only use it if it also HAS that ability (as a side note, this allows us to tell a unit how to use many abilities, but only give it a subset of those abilities, and give the full suite of abilities to an advanced version of the enemy). This means that when we invoke the AI to calculate the best move, every AI unit will attempt to use every ability it has and knows how to use on every tile in range of that ability. Every tile is evaluated using a list of considerations that describe the scoring of that ability. These considerations produce a score between 0 and 1 which defines the utility score of using the ability on that tile. There can be multiple considerations evaluated per tile, and the score of each of these is multiplied with each other to produce the final score.

If all considerations produce a score of 1, it would imply that is the best move. If there is more than one action with the same best score, we pick a random one amongst them, since we assume it doesn’t matter which we pick, since all of them are equally good. Once an action is chosen, it is executed, and then the entire process repeats. We have to repeat the entire process because, after every action, there can be changes to the state of the game that might affect the thought process for other units. For instance, if unit A prefers attacking enemies that have lost health (because it can smell blood or whatever), the score for using that ability would be low for all units that have full health. If another action with a greater (or not penalized) score is executed first and has the outcome of damaging the health of an enemy, then that changes how unit A thinks about using its blood-seeking ability. Another simpler example is having units move around the area, affecting whether they can now attack enemies or not.



This system allows us to create enemies that prefer specific rules, but are not forced to use them or bust. It creates a feeling of uncertainty for what the enemy will do, because it’s dependant on the state of the game that’s not immediately clear, but is still learnable with enough observation.

Thanks for reading! This is just a glimpse into how our utility AI works, the topic is very complex, and if you’re interested in learning more about the general concept of utility AI, I recommend watching some Dave Mark’s videos on the topic. If you’ve got more in-depth questions about our implementation, join our Discord and ask about it, I’m happy to go into much more detail than I’ve written here. You could also ask via Twitter if that’s your preferred medium.

MarkoP

Dev blog 25 - Cataclysm monsters

Hi there!

This week I wanted to talk a bit about the monsters in the game. The idea behind some kind of cataclysm or corruption was there from almost the very beginning of development when we were still a 2D game. We iterated over many different designs and many different ideas for it and the monsters. We went from robot ninjas to plants and zombies, Giger and Lovecraft, acid stone lizards… Most of them were discarded because of one reason or another, something just felt off with them.



The very first monsters were all designed for the 2D game version of The Hand of Merlin (before it had a name). No animations, they were just a sprite on the screen that moved around and used skills. This was before we knew what monsters we wanted to have in the game and before we actually conceptualized anything related to them.
When Kaz came on board, she made a couple of concepts and versions of monsters we talked about in length, and at some point settled down on plant-like monsters. That’s when the first playable and half public iteration of the game was made - half public meaning we showcased it at the Reboot Develop conference in Dubrovnik, Croatia. This is what we went with for the longest time, until we moved to the Serious Engine and recreated a couple of these monsters, but decided we wanted to redefine what the cataclysm is (with the help of our writers) and make the monsters fit that vision.

After we had a better idea of what the cataclysm is, we gave Mateja the task of making a bunch of weird monsters. In a few days, she came up with around 10 monsters that were pleasantly fitting to the idea of the cataclysm. We chose 4 of those, updated two monsters we previously had in the game, and picked one from some newer concepts Kaz made and settled on the roster of 7 monsters.



Our current idea is to introduce all of the monsters gradually as move through the zones. The demo featured 3 monsters - the Behemoth, the Wyvern, and the Mandrake. The names were chosen by our writing team to fit with the narrative idea: these monsters are unknown to the world, and the people of the world gave them names that are most similar to descriptions of other mythical creatures they might have heard of in stories.



In the demo, one of these monsters was somewhat harder than intended, but he was meant to be introduced later in the game anyway when the players have more tools at their disposal. Our design intent with each monster is to have them be unknown in terms of skills and what they do initially, but once you fight them a few times, you learn what they do, and are more capable of defeating them in the future. The ideal scenario is to essentially be defeated by the monsters when you first fight them because you don’t know what they do. In subsequent fights, you know how they operate, which makes them easier to defeat. We’ll have to see how well we pull this off. :)

Thanks for reading! Join our Discord, ask questions, comment on what you’ve seen so far!
You could also follow me on Twitter for some additional content.

MarkoP

Dev blog 24 - How we create units

Hi folks!
After the Steam Festival, we now return to our regular broadcasts - talking about the game we’re making. I’ve talked my lead artist boi Ivan into writing this one as well since it’s more in his domain than mine. I just made it readable, as usual.

===
Like everything else, the task starts with an idea. The idea comes from our beautiful writers Jonas and Verena, like with this example of Breunor:
“A man of great passion and deep melancholy, Sir Breunor is driven by the death of his father, whose armour he wears. He once wished to become a Knight of the Round Table, but abandoned that dream when Arthur died.”
If needed, the artists who do the concept art talk about the description, to work out any vague details. In this case, the description was enough to get started.



When the concept art is done and we’re happy with it, we start the high-poly sculpt of the character. When doing this, we consider the fact the camera in the game cannot get too close to the units, so we don’t make it too detailed and complex.



After we have the high-poly sculpt, we move on to make the low-poly model. Our tech artist Toni takes this phase into his hands and does the retopology of the model. When that’s done, he goes directly into doing the weight painting and rigging the model for animations. At the same time, our texture guru Kaz does the textures for the model.



After this is all done, all that’s left is animating the character. Considering the number of artists in the team is low (just 5), and the ambitions for the game are great, everybody does almost every art task - except animations. Animations are done by just two of us, without either of us having direct ownership of the entire character’s animation. We collaborate over them and fine-tune them together until we’re both satisfied.



There’s one step veiled in mystery that just seems to happen suddenly during any point of this process (and something we even forget, so it happens later), and that’s the portrait of the unit which is featured in Merlin’s Journal and in combat.

Everything done so far is ready for one final test - adding the model into the editor where we see if anything needs to be tweaked. For instance, whether the gloss mask on the helmet is too shiny, or how the animations look in the game when moving, as opposed to being animated in place in Blender, etc.
Also, each character needs to be assigned animation events, like on which frame of the animation is the damage dealt, when is any SFX played, particles, etc. This part is also done by the artists since it’s tied to the feel of each character.



And finally, Breunor is alive! This is when we let our game designer Mat teach the guy how to fight by giving him skills and stats.


===

Thanks for reading. Make sure you wishlist the game, and come join our Discord to ask questions, complain about the state of the demo, or just hang out. I also have a Twitter thing if you're interested.

MarkoP