NPC Technical Rundown

Hello everyone! This post is going to briefly cover some topics relating to Hytale's NPC framework, its current state, how it looks, and where we want to take it. Some of the content might be a bit more technical, so feel free to skip through or skim the parts that don't interest you. There's also a lot to cover when it comes to NPC-related systems, so don't expect this one post to be exhaustive!

Where we are

As it stands, the NPC framework supports a wide variety of behaviours across multiple systems, all of which are configurable using data-driven assets. You don't need to know any programming languages to be able to set them up - even our most complex NPCs are almost entirely data-driven.

We achieve this through a number of different behaviour-related systems, but the two we'll cover in this post are 'Roles' (the heart of our NPCs) and the 'Combat Action Evaluator'.

Documentation and Tutorial

If you want to learn more about NPCs, our friends at hytalemodding have a lot of great documentation already and we provided the generated NPC one as well as a written tutorial.

Together with this tutorial we made a 6 part video series, where we cover some parts of it in extra detail; for the best experience use both:

Roles

Every NPC has a role. This is the expression of their general behaviour and how they'll react to different stimuli in the world. Changing an NPC's entire behaviour set is as simple as changing its role, and we provide a number of templates with customizable values that can be applied to make creating new NPCs quick and efficient.

In addition to the behaviour itself, the Role also dictates aspects such as how an NPC will move, what items it carries, what it looks like, and so on.

On the technical side, this behaviour is represented by a concept we refer to as 'instruction lists'. This isn't too far removed from decision trees or behaviour trees, but with some of the semantics simplified. Each instruction is made up of a 'sensor' - an element that queries the state of the game to decide if this instruction can be executed - as well as the actions or motions the NPC should take if this instruction is selected. Alternatively, the actions and motions can be replaced by a nested instruction list, giving rise to more intricately constructable behaviours.

If you're familiar with behaviour trees, you might wonder where the actual differences lie - sensors are somewhat analogous to decorators and it's still a tree-like structure. The key is in the semantics we use for traversing our instruction lists. Where behaviour trees may follow different semantics depending on the node type, we always follow the semantics of the fallback selector node. Each instruction is evaluated in order and - if matched - executed. Unless specific flags are included in the instruction, we won't evaluate any further instructions in the list. This ensures that the flow of logic within the NPC is easy to follow, no matter how large or deep the trees grow.

While all the individual element types (sensors, actions, motions, etc) are written in Java, the instruction lists are constructed entirely in JSON. At this stage we have more than 150 different element types that can be combined to build behaviours and a framework in place to make it easy for modders to add more with Java. Not all of them are in a finished state, but we're actively working to iterate on them and add as many more as we can!

At its core, we designed our NPC framework to be interacted with on several different levels. Whether you're completely new to modding and NPC design or a veteran able to craft complex behaviours, we want to ensure there are ways for everyone to be able to bring their creations to life.

Here is an example of changing the Sheep role to go from a Livestock behavior enabled by Template_Animal_Neutral to being aggressive with the help of Template_Predator.

And it goes from being fond of you to attacking.

With some basic templates we created, you can also give it a random Weapon and you are ready for Die Hard Sheep mod

The Combat Action Evaluator

Though instruction lists already give designers a great deal of flexibility to configure their NPCs and implement combat behaviours, crafting a character that does more than few basic attacks and needs to make some sort of decision about when to use certain attacks quickly becomes cumbersome.

The combat action evaluator exists to address these needs, by offering a companion framework to an NPCs central behaviour that can make smart moment-to-moment decisions about its state, the state of the world around it, and its enemies or allies. Each possible attack (or other combat action) is assigned a set of conditions that designate the best time to use it - when HP is low; when the enemy is close; when a player is trying to sneak around the back. These conditions are then evaluated and each action is weighed against the others to determine the course of action the NPC wants to take.

Making decisions this way introduces a level of 'fuzziness' to the NPC and leads to more interesting combat encounters with less verbose configurations. The downside is that there's a steeper learning curve and NPCs might not always act the way you expect! It's also not as performant, but that's something we hope to improve with further iteration.

For example, the Skeleton Praetorian can decide between using different abilities with some degree of intelligence: blocking, summoning at low health, and charging, alongside basic attacks.

Below is a snippet that shows part of the configuration for the summon ability condition:

And here is a video example of those decisions:

The reality check

This all sounds pretty far along, right? Maybe you could even believe it was shippable?

Well…no. There are still very many rough edges, missing features, and areas in need of vast improvement. Just as we talked about what the systems can do, it's important that we talk about some of the major areas where we're not quite there yet.

With great power comes…the need for great tooling. We're very far off the mark here. There are plans for visual editing and debugging, but right now most NPC configuration is done directly in JSON files using text editors. It's workable, but painful, and though we provide a variety of avenues for debugging NPCs when they don't work as expected, none of them are intuitive and most require reading through pages upon pages of detailed log files.

We mentioned the learning curve associated with the combat action evaluator, but that applies pretty much everywhere when it comes to working with NPCs as well. We envision an easier and smoother onboarding into NPC modding, but at this stage we can only offer a limited number of templates as examples along with documentation on available elements and simple tutorials.

There are plenty of major missing features as well. NPCs don't position themselves very well in combat; they don't use proper avoidance or flocking; while flying NPCs can land and take off, swimming NPCs can't leave the water and vice versa. There's no end to the list of features we still need to add to be able to deliver the game we envision.

Naturally, the potential for performance issues abounds. We can support a relatively large number of NPCs but there's much work to be done in making them more performant, particularly when it comes to pathfinding. We keep the pathfinder off as much as we can otherwise performance is likely to tank!

And then there's all the technical debt that needs to be solved, from NPCs not being able to deliberately break blocks outside of projectile-based explosions due to certain non-NPC system constraints that need to be revised (they can place them though!), to NPC physics needing a complete rework to unify it properly with player systems. There's a long road ahead to get things into proper shape - and we didn't even talk about spawning!

Bugs, bugs everywhere

Many community members have pointed out the plethora of bugs that cropped up in released gameplay footage. With our current development pace, much of that footage is already outdated and the most critical of those bugs have already been fixed! However, I do specifically want to take a moment to talk a bit more about pathfinding, its challenges, and what this is likely to mean for release.

Pathfinding is a large and complex topic - complex enough that many regular games struggle with it. When you add a procedural fully-modifiable block-based world to the mix, this becomes even more complex since we can no longer rely on many of the tricks games use to optimize performance around known terrain.

This means our pathfinding is currently slow. Not so slow that it causes any noticeable performance issues, but slow enough that we don't currently allow all NPCs to be using it at all times and put severe restrictions on its current capabilities. This is why - for example - cave raptors don't jump across gaps to chase after the player. We can't pre-populate the world with 'jump points' because the world could change at any time and each block of additional distance an NPC can jump over a gap is a large additional cost for every search.

We don't expect this to change in time for the early access release, but we're committed to improving our pathfinding as a whole and have already begun work on developing a new method that could solve most of these issues should it prove viable.

So what's next?

Tooling is high up on our priority list. If we want to support modders properly, we need to give them the tools they need to make creating NPCs fun! This won't include a full suite of debugging tools at first, but we'll pull together what we can.

We also need to address the issues with pathfinding and movement while dealing with technical debt to ensure that we're not creating performance bottlenecks when players face off against multiple NPCs in complex environments. There's a lot we can improve on here to make sure that combat feels enjoyable, even at this early stage.

Adding more templates will also help to liven up the world a bit more, with bespoke behaviours introducing life to the cultures of Orbis' many different species. These are also intended to serve as further inspiration and examples for modders seeking to create their own more complex NPCs - or can be used directly if the behaviour fits!

All of this leads towards the potential for creating proper bosses - encounters that will push all our PvE systems to their absolute limits. There's a lot of work required to reach this point - far more than has been listed here - but we're laying it out step by step and working our way through it. With a bit more time, we'll make it all work!

A headstart: debug commands

This post was originally written to be posted before our early access release. In the time since, we've put quite a bit of effort into trying to make NPCs more accessible to modders. While we don't have a visual editor or deep debugging just yet, we've added a number of different visualisations to make it easier to understand how your NPCs will function (and tracked down a number of bugs on our end through using them too!). Some of these features are still in development, but here is a sneak peak into our work in progress and what’s coming soon in future releases.

Each of these visualisations can be enabled by toggling certain NPC debug flags on individual NPCs. This is done by using the NPC debug command while keeping the NPC in your view. You can do this by typing /npc debug set <flag> in the chat console in-game or by adding the flags as a comma-separated list in the Debug property of the NPC role itself. Running the command /npc debug presets provides a full list of available flags and preset sets of flags that can be used, but the most useful visualization flags are detailed below.

/npc debug set VisAiming

You can use it to determine what the NPCs actually shoot at. Works for NPCs that have aim instructions in their logic.

/npc debug set VisMarkedTargets

Visualises all current marked targets locked onto by the NPC. In most of our standard templates, the NPC has a single LockedTarget which is usually the entity they're actively engaged in combat with. Useful for understanding how and when the NPC changes focus, as well as exactly what their current focus is in a crowd.

/npc debug set VisSensorRanges

Visualises all currently checked Mob sensor ranges as rings and view sectors, as well as which entities in range are being matched by which of these sensors. With how these sensors are generally used in our NPCs, this gives a quick visual overview of the 'sensory capabilities' of an NPC. Note that though these are displayed as sectors and rings, they are technically spheres and cones that can be bounded by height conditions.

The first screenshot shows the Bear sleeping and only having one sensor active. On the second screenshot the Bear has hearing, vision, and absolute detection range. Even though the Sheep are detected by the vision radius (they have target marks) they are outside of the view cone. The sheep family is still safe!

/npc debug set VisLeashPosition

Visualises the NPC's current leash position.

/npc debug set VisFlock

Visualises the flock (NPC group) associated with this NPC. This display includes marking the leader of the flock and all NPCs that are currently members of the flock.

Matiascommented
Some random comment
Matiascommented
Some random comment
Matiascommented
Some random comment