LIONHEARTS REFORGED, 2025
Role [Gameplay programmer]
Software [Unreal Engine]
Framework [Blueprint, C++, GAS]
Duration [4 months]
Date [Fall 2024-Spring 2025]
Team size [10]
Type [MMORPG Simulator]
OVERVIEW
Lionhearts Reforged is a medieval MMORPG where you lead armies, build trade empires or rise to religious prominence in a player-driven persistent multiplayer feudal simulator: a living medieval open world where every player’s choices shape history. Build kingdoms, forge alliances, wage wars, and rise through the ranks of military, trade, or religious hierarchies in a persistent, player-driven world. History and legacy is created by the players.
I worked on this project during my internship at Credenzio Studios. Since I am under an NDA I won't go into implementation details, but I can speak to what I worked on and the reasoning behind it. Since I was part of starting the project from scratch, a large part of the work involved laying the foundation before any features could be built. The primary goal during my time was to build a demo for the Kickstarter campaign.
SHADOW SYSTEM (AI)
DEVELOPMENT
During the internship I worked across several areas: the Shadow system for AI behaviour and tasks, a directional combat system for AI, a prayer mechanic, project setup, and technical documentation. Getting to contribute across that range from the start of a project was one of the most valuable parts of the experience. I was given a lot of responsibility early on and had to learn fast.
PROJECT SETUP & DOCUMENTATION
Before feature development could begin, the project needed a solid foundation. I set up the GitHub repository and wrote documentation covering project setup, naming conventions, development priorities, and the order in which systems should be built. Getting this right early meant the team had a shared reference for how to structure their work and integrate with each other, which matters a lot when everyone is building new systems simultaneously.
The documentation covered technical setup, planning, and rules for how the codebase should grow. Having that in place from day one avoided a category of integration problems that tend to compound quickly on a project of this scope.
The Shadow system is designed to allow player characters to persist in the game world while offline, continuing to perform assigned tasks, engaging with other players, and keeping the world feeling alive even when the owning player is not actively playing. For the Kickstarter demo I built a visualisation of how the full system was intended to function.
When a player logs in, they start by spectating their Shadow while it carries out its assigned task. When they are ready to play they possess the AI and take over directly. When they log off they have the option to assign a new task to the Shadow via the task menu, which it then begins performing once the player exits.
I built this using behaviour trees. One challenge was finding a clean way for any Shadow to switch tasks quickly without needing a separate tree per task. I solved this with a single large tree that selects the appropriate subtree based on the assigned task, determined by a struct using enums. This kept the logic centralised and made adding new tasks straightforward without duplicating tree architecture.
SHADOW TASK MENU
The task menu is where players assign tasks to their Shadow. Each area of the world has a set number of Shadow slots per task, and the menu reflects availability in real time. If a slot is taken it disappears from the menu, and if one opens up it reappears. Players can open the menu at any time, review available tasks, and assign one before logging off.
I built this using widgets connected to the behaviour tree, so the menu state and the AI state stay in sync.
SHADOW TASKS
I created the full set of tasks that a Shadow can be assigned. Each task is a self-contained behaviour that the AI executes while the player is offline, and they fall into a few natural categories based on what they do in the world.
Gather Resource tasks cover productive work: chopping wood, mining, and harvesting from trees and wheat fields. These give the Shadow an economic purpose while the player is away.
Role tasks place the Shadow into a functional world role that other players can interact with. A Shadow assigned as a merchant operates an actual store with inventory that players can browse and purchase from. A baker produces and sells goods. A quest giver offers quests to other players, making the Shadow a live part of the world's content rather than just a passive presence.
Patrol task has the Shadow follow a guard route through an area, behaving like a stationed NPC. It needed its own navigation logic to feel credible rather than just standing in place, using spline tools or random move to locations.
Ambient tasks are lower-key behaviours meant to fill the world naturally: resting on a bench or wandering an area at random. These exist so not every Shadow looks purposefully occupied, which would itself feel artificial.
Each task has its own behaviour tree logic rather than being a simple state flag. A Shadow working as a merchant cannot just play an animation; it needs to actually function as a store. A patrolling Shadow needs a route and reactive behaviour.
Keep in mind that these tasks were implemented early in development, so they lack proper animations and polish. The Shadows move through their loops using placeholder visuals rather than the finished look. That said, the purpose at this stage was was to prove that the loops work. Each task needed to demonstrate that the AI could navigate, perform its actions in the right order, handle transitions cleanly, and slot into the broader Shadow system without breaking. The visuals can come later once the foundation is solid.
GATHERING RESOURCES
I built several resource gathering tasks covering grapes, apples, wheat, wood, and ore. Each one follows the same core loop: the Shadow navigates to the resource area, collects from the source, deposits into a nearby container, and repeats until the container is full. Once full, it carries the container back to the player's storage.
The collection step varies by resource type. Wood and ore require an active action against the source, chopping a tree or striking stone, before the resource is yielded. Crops and fruit are grabbed directly from the plant. That difference meant each task had slightly different behaviour tree logic at the collection node, even though the surrounding loop was shared.
Getting the loop to feel continuous without breaking was the main thing to get right. The Shadow needs to reliably find the next available source after each collection, know when the container is full, and navigate back without getting stuck or idling. Each of those transitions is a potential failure point, so the behaviour tree needed to handle them cleanly.
CRAFTING
The crafting tasks, covering a blacksmith, baker, and construction worker, follow the same foundational loop as the resource gathering tasks. The key difference is that instead of collecting something that already exists in the world, the Shadow is producing something through a series of steps before depositing the result.
COMBAT SYSTEM
The combat system is ability-based and directional, meaning attacks and blocks are tied to specific angles rather than being a single undirected action. Players can perform light attacks, heavy attacks, blocks, and parries, each from different directions, creating a system where reading your opponent's angle is as important as reacting to their timing.
The base combat system was built for the player character by another developer. I took that foundation and extended it to work for the AI, writing the additional code needed to make it function as an opponent. I also built the accompanying HUD warning system. The AI attacks in random directions, and when it commits to an attack the player's crosshair lights up in the corresponding direction, up, left, down, or right, giving the player a window to respond. If the player blocks in the matching direction the attack is parried or the AI is stunned. The warning system ties the AI behaviour directly to player feedback, so the directional system has real weight during a fight rather than feeling arbitrary.
PRAYER MECHANIC
The prayer mechanic is a word-sequence minigame tied to the game's religious progression system. The player is presented with four word choices at a time. Selecting the correct word adds it to a forming sentence and presents four new choices. Successfully completing the full sequence rewards the player with a buff such as increased stamina or health. Selecting the wrong word resets the sentence entirely.
The interesting implementation challenge was managing a large set of words where each one carries its own sound cue and correct or incorrect status. To keep this modular I stored each word in a data table with its associated sound cue, sequence order, and whether it is the correct choice. A prayer is then just a data table of words in order, which means adding a new prayer is a matter of creating a new table rather than changing any underlying logic. The mechanic can support as many prayers as needed without touching the system itself.
SIT ANIMATION STRETCH


I created a sit interaction mechanic where both the AI and player can sit down at benches using motion warping. Motion warping adjusts the character's position and pose dynamically as they approach, so the sit animation aligns correctly with the bench regardless of the angle or distance the character approaches from. Without it the character would snap to a fixed position, which breaks the illusion. The same mechanic applies to both the player and AI so the behaviour is consistent across both.
TAKEAWAYS
This internship was a very formative experience. Being part of a team with daily standups, code reviews, and ongoing technical discussions meant I had to communicate my decisions clearly and defend my reasoning. Even tho I have done standups before in smaller teams that kind of professional rhythm was new to me and pushed me to grow fast.
Working on AI behaviour through behaviour trees gave me a solid practical foundation in how to model complex state and task logic, and the directional combat work deepened my understanding of how ability systems need to account for spatial context, not just activation conditions.
Setting up the project infrastructure and writing the documentation also pushed me to improve my documentation habits. The scale of the team and project demanded more structure and consistency than I was used to. Getting naming conventions, repository structure, and development priorities agreed on early saved the team significant pain later.