Tales of Legindrea Devlog


This post is intended to explain the development process for Tales of Legindrea.  Some of the latter part of this devlog will consist of programming terminology that may be unfamiliar to some readers.

This project is a complete redesign from a previous project that was scrapped for various reasons.  For starters, some of the systems weren't readable enough: the Player System, the GUI System, etc.  To remedy this, those systems were heavily refactored and new systems were implemented.  In addition, the art style of the game did not have enough assets to produce a full prototype.

During this time, I went through several art designs and spent money on many assets from the Unity Asset Store until finally settling on Synty Studios POLYGON Nature Pack and POLYGON Scifi Space Pack.  Their stylized (low poly) art style was unified, so no need to worry about blending different assets together to fit inside the same cohesive world.  Lastly, they had a large library of assets, which is ideal for creating levels with diverse environments.

the following images are some of the previous art styles that were tested.  I was ambitious with this project and initially created special effects, paired with a more realistic art style as demonstrated in the screenshots below:


The following shows Flat Kit Toon Shader, which was the basis for the next set of art styles that were tested.  However, due to insufficient assets and the work required to blend differently styled assets together, it was abandoned.  Only the characters in the pictures below are using Flat Kit.  The environment is from a plugin called Hylophobia: Stylized Forest from the Unity Asset Store.



Eventually, I started using Flat Kit on all assets.  In order to achieve this, all models needed to map to stylized textures as a bare minimum.  As illustrated in the picture below, no realistic textures are mapped to any of the 3D geometry, all of which use Flat Kit.



Finally, after many experimentations in a short period of time, Synty Studios was the perfect fit.  The following is a demonstration of Synty Studios POLYGON nature pack and Map Magic 2: a node based procedural terrain generator which was very helpful at creating a quick environment using these assets.


Lastly, POLYGON Scifi Space Pack was used to create a laboratory for the game.  Unlike the terrain in the picture above, these assets were manually placed (it did not use procedural generation).  I wanted to make different parts of the lab unique to intensify the exploration.  The game doesn't have a strong story but uses lore as its primary, storytelling element.  Therefore, manually placing interactable objects (like computer terminals) with text-based lore in the lab to achieve a specific narrative made sense.  The following is a demonstration of this laboratory.



Finding the necessary animations needed for the main character was also a struggle.  I found a site called Mixamo which met some of these needs.  In addition, many animations were used from RPG Character Mecanim Animations Pack by Explosive.

However, most of my time was actually spent either coding new features or debugging preexisting features.  In the game, different groups of code are divided up into systems.  Each system achieves a certain feature or a set of features; and is designed with simplicity and scalability in mind.  The systems are as follows: Interfaces, TreeBuilder, AI, DontDestroyOnLoad, Equipment, Generators, Independent, Interactables, Menu and Player.  They will be explained in further detail in the following paragraphs.

"Interfaces" handle how these various systems talk to each other.  Its generally ideal to keep each system as decoupled as possible but in some cases, its not practical.  By using interfaces, programmers can explicitly define what methods and properties other systems require from any specific system.

"TreeBuilder" is a set of root behaviors and base classes that other systems--using the behavior tree editor--inherit from.  It contains classes that manage the graph editor and contains the functionality of commonly used nodes.

"AI" is one such class that inherits from TreeBuilder.  AI uses the behavior tree to define how each type of AI makes decisions.  This system primarily contains node classes that define different states or conditions used in the interactions with artificial intelligence.  The following is an example of an AI behavior tree.


"Interactables" is the only other system that inherits from TreeBuilder.  Interactables deals with player interactions that subsequently trigger other things in the game such as animations, branching dialogue, receiving an item, opening a door, entering a new level, saving the game, looking at the contents of a computer terminal in the lab, talking with NPCs, etc.  It also uses nodes that add progress to missions, which can unlock new missions or dialogue in the game.  The following is an example of an Interactable behavior tree.


"DontDestroyOnLoad" is a special system that deals with globally accessible objects.  These objects are useful when you have certain features that need to be accessed across different systems (and different scenes), such as playing a sound effect from an addressable group or implementing a factory that needs to instantiate different objects at runtime.  It is also useful when loading scenes from a coroutine because all MonoBehaviours attached to a DontDestroyOnLoad gameobject won't be destroyed when changing scenes.

The "Equipment" system uses scriptable objects for its functionality and covers weapons, items, armor, etc.  Using scriptable objects for equipment and items is useful because it allows other developers (non programmers) the ability to add new items without introducing errors.  It also slims down the memory footprint of the game and can be accessed across multiple scenes.

"Generators" were used in the project at one time.  It was scrapped but never removed.  It has since been rebranded as "Procedural Dungeon Generator" which is a project you can view on my GitHub account.

"Independent" contains scripts that are separate from any system (completely decoupled).  For example, writing a unique script for an object that only uses built-in Unity libraries.

The "Menu" system is a way to unify different GUI elements such that they're part of the same style and can be changed more easily.  That's the way it originally started.  However, this system is also useful because it handles the changes in the GUI display when adding new items into the players inventory and also declutters the children of the Canvas gameobject in the inspector: it only spawns elements when they are needed and discards them for the garbage collector afterword.  In addition, it can read items from the inventory class and display them in many different ways with only a few lines of code.

The "Player" system is the most complex of all.  It handles the events that happen when an object is hit, player controls, state machine behaviors,  specific menu displays, combat stats.  Many of the scripts that make up this system routinely communicate with each other.  However, many of them were decoupled by using C# events and extracting the functionality of each MonoBehaviour script into separate non MonoBehaviour classes.  This is a fairly common practice among all systems implemented for this game because it makes unit testing easier.


I hope you enjoyed this devlog and if you have any questions please feel free to leave a comment.

Get Tales of Legindrea

Leave a comment

Log in with itch.io to leave a comment.