Programming

This page contains a compilation of programming and feature demonstrations made for Game and Passion Projects during my Bachelor and beyond. These are not ordered chronologically, but by the amount of Development effort put into them. For more information about the games themselves and their stories, please see Game- & Narrative Design.

Shards of Renaissance

Shards of Renaissance is an ongoing game project that has spanned multiple semesters during my studies at university and has now left with me to be continued as a passion project with a select group of my friends. I also wrote my bachelor's thesis about the games' combat system.

The game is a First-Person-Shooter with Hack and Slash elements and a focus on player autonomy in deciding their own playstyle. The player creates weapons from magical glass in dual-wielding combat, which he can use to fight the enemies in the game. The weapons break after using them, so the players loadout is constantly changing and adapting to the situation at hand.


This project, developed once again in the Unity Engine, has gone through many rewrites and restructures in code and project management. In this project I was able to create a new, agility-focused movement system along with the unique combat system of the game. During my bachelor's thesis, I also designed and implemented a plethora of enemies  and bosses to highlight the special features of the combat loop that I was working on. The game is being actively worked on and allows me to improve my skills in many different facets of Game Development in my free time.

More in-depth explainations of the games' systems  and mechanics, alongside video demonstrations can be found below.

 

Platformer Player Movement

The Movement of Shards of Renaissance is reminiscent of FPS games like DOOM Eternal or Ghostrunner, which were both games later analyzed in my bachelor's thesis.

This Movement System, in comparison to the other ones I had written, had to be balanced and mechanically perfected to create the optimal experience for the player, as an unsatisfying movement system in a game like this would lead to frustration and disappointment. 

The System contains the standard walking and jumping, however it also contains mechanics such as wall running, sliding, rail grinding and a dash, all of which were tailored to fit into the games level design. The rail grinding mechanic makes use of Unity's Spline system, which I had already grown accustomed to from my work with it in Railroad 9.

The system is currently being refactored to work with Unity's new input system, as it currently still relies on the old one in some places.

Weapon System
 

The Weapon and Combat Systems found in Shards of Renaissance are the unique selling point of the game and are thus specially made for it.

The player is able to dual-wield, meaning he can have different weapons in his left- and right hand and use both of them at the same time. Weapons are crafted from glass shards obtained by destroying glass constructs found throughout the level. These constructs have different colors, and each color corresponds to a different status effect the weapon will inflict when crafted from that type of glass. Some examples of status effects include wounding or stunning an enemy. When a player crafts a weapon, that hand is put on a cooldown specified by the crafted weapon. During the duration of this cooldown, no other weapon may be crafted in that hand. 

Weapons are crafted using a WeaponData ScriptableObject, which contains all data needed to craft the weapon such as crafting time, crafting cooldown, the weapon prefab and the positioning in the hand model. The weapons themselves all derive from the BaseWeapon class, which contains functions such as handling durability, weapon talents and the base attack function. Everything else is left up to the individual weapon.

Enemy AI & Spawning

Instead of using the fully code-based behavior tree system I wrote for Reflections, for Shards of Renaissance I decided to upgrade to the Behavior Designer plugin by Opsive. This visual editor allowed me to more efficiently create enemy AI far more complex than the ones I had made before.

For the enemies I designed a plethora of new tasks that allowed the enemies to teleport, jump to positions, heal and more. I also integrated the enemy attacks into the modular weapon system I made for the player, which allowed me to simply reuse that system without needing to rewrite a new one.

Enemies also now possess a dedicated EnemyHealth and EnemyData class which contains all logic partaining to damage, healing, death and more. These classes can be derived from for certain enemies whose logic strays from the norm.

Enemy spawning works through an arena system. When leaving the specified StartSafezone object, the Arena will receive an Event and start spawning the enemies given to it by its respective Wave ScriptableObject. Once every enemy of that wave has been eliminated, the next wave starts after a few seconds of downtime. This repeats until all waves are completed and the arena ends.

Railroad 9

After Development on Reflections concluded, I started my mandatory internship at CoreCraft UG. During that time, I missed working on something of my own, so I started developing Railroad 9 on the side. Since I was developing this Game alone, I had to find other ways to obtain Art, while myself being responsible for Development and Sound. The 3D Models in this Game are mostly comprised of Assetpacks from the Unity Assetstore, however some are also made by me or my friends. The UI and 2D Art are made by my Girlfriend, Jennifer Hager.

In this project I was able to use my, now rather expansive, knowledge of the Unity Engine. This Game also introduced me to Unity's Spline System, which I used to create the Train and the Rails it follows.

More in-depth explainations of the games' systems  and mechanics, alongside video demonstrations can be found below.

 

Spline-Based Train Movement

The main Gameplay-Loop of the game takes place inside of the train itself. To create a moving train, I used Unity's built-in Spline System to create the train tracks. This allows me to make the tracks curve and go anywhere i want while still being editable diretctly in the engine, without needing to remake a mesh everytime the tracks are changed.

The train engine itself uses kinematic Rigidbodies to follow along the splines rotation and position. The speed can be controlled from the inspector and is changed ingame through the Gas- and Brake-Levers. 

The passenger carts are placed behind the engine and assigned their respective predecessor in the inspector. The cart is then placed at a set offset from its predecessor and follows it using the speed of the engine. This allows for theoretically infinitely long trains as well as carts of different lengths, since the only value that requires changing is the offset from the predecessor.

Passenger System
 

As the player travels through the map using the train, passengers will spawn at hand-placed stations alongside the tracks. These passengers are integral to the Gameplay-Loop. When the train leaves a station, the passengers at the next station are spawned in to increase performance.

On spawn, each passenger is assigned their own PassengerData in the form of a ScriptableObject, consisting of: gender, first- and last name, exit station and starting satisfaction. It is also decided whether the passenger is a human or an evil spirit. The player can view the PassengerData using his Ticketing Machine item.

When the player interacts with a passenger at the station, a list of all stations on the track is shown alongside the passengers ticket with their exit station. Should the exit station be on the list, the player can let the passenger aboard. Otherwise, they have to decline their request to board. When the passenger is on board and something on the train breaks, their satisfaction value slowly drains towards 0 while the tasks remains unfinished. Should satisfaction reach 0, the passenger will disembark from the train at the next station. This can be prevented however, using one of 5 refunds given to the player per run. A refund resets a passengers satisfaction back to full, no matter how low it is.

Should the player suspect the passenger to be an evil spirit, they can go up to the passenger and use the Charm item on them. If the player is correct, the spirit will be destroyed and leave the train. Is the player wrong however, the accused passengers satisfaction immediately drops to 0.

Task System
 

The Task System sits at the core of Railroad 9's Gameplay Loop. It determines what the player has to do to keep their passengers satisfied and aboard the train. Should they fail, the spirits overrun the train and the player loses. 

The Task System relies on the TrainTaskManager to determine which tasks are selected. Each task is assigned a risk level in the inspector, going from Normal to Extreme. The selection algorithm follows a specific set of rules to decide which task to start. These rules include e.g. number of total passengers, number of spirits compared to humans, distance from final station, distance from next station, time since an extreme task and average satisfaction of human passengers.

When a task is selected, an audio cue plays to alert the player. The player can then view the task on the task screen in the train cabin. The broken object is highlighted with a red outline, which the player can then move towards. The object has a TaskFixInteractable component, which can then be interacted with to start the relevant minigame that has to be completed to fix the object. During this time, satisfaction of all passengers starts slowly ticking down.

After a task is completed, the satisfaction of the passengers increases by a percentage of the satisfaction lost dependant on the risk level of the completed task. This means that a higher risk level can drain satisfaction faster, but also returns more satisfaction upon completion.

The Liminal Party Pool

During my 6th semester studies, I had a subject known as "Tool- and Backend Development". As a project for this subject, we were asked to create something that contains some form of Client-Server-Communication. This could include a Build Pipeline, a Multiplayer Game or anything else we could come up with.

Despite the lack of time, I decided to make a Multiplayer Game in Unity, as this was something I had always wanted to try.


After doing research I found out about Unity's built-in Multiplayer Solution in the form of Relay and Lobby. Learning these tools allowed me to create a multiplayer compatible game. To fit the style of party game I was going for, I also implemented correct, server-authoritative physics-simulations across multiple clients, which took up a lot of development time. 

All in all, even though the project was made in two weeks under time pressure, i still learned a lot about the differences between developing a Single- or Multiplayer game.

Multiplayer using Unity Relay

Complying with the Task given by my professor, The Liminal Party Pool was designed to be a multiplayer game. 

To achieve not only multiplayer, but to also avoid problems like port-forwarding, I decided to use Unity's built-in multiplayer solution in the form of Lobby and Relay. These tools allowed me to create a system of custom, player-made lobbies with players all around the world that could play together with minimal effort or challenge. 

They would simply need to create a lobby in the starting menu and then other players could join that lobby. The system could even be expanded to use password-protected lobbies, so that only people you want to play with can join.

Minigame System
 

In The Liminal Party Pool, the players can either play their own games with the objects around the environment like floaties, water guns, beach balls or more. If they get bored of that however, they can play one of two minigames made by me; Boom Squid and Kraken Trackin'.

Boom Squid is a simple Hot Potato-esque game. The "Boom Squid" is placed on one player's head and they are stunned for 30 seconds. In this time, the other players can run away and hide from the tagged player. Should the tagged player catch another player, the boom squid is transferred over. When the timer runs out, the person with the Boom Squid explodes and is kicked from the Lobby.

Kraken Trackin' is a search and retrieve minigame. At the start of the game, a "Crystal Squid" will spawn for each player in the lobby except for one. These squids are hidden all throughout the map, but will reveal their location for just a moment every 30 seconds through a visual and audio queue. Players can collect Crystal Squids and bring them back to the starting area, which makes them safe. The last player without a Squid is removed from the Lobby. During the game, other players can try to steal Crystal Squids directly from their oponents hands.

Multiplayer Audio
 

In order to account for multiplayer, I had to expand the AudioManager System I had been developing throughout my studies.

These new restrictions meant splitting up the AudioManager into a client- and serverside AudioManager, each with their own functions. The ServerAudioManager can play 2D sounds that every player should hear, without having to notify the clients directly. In comparison, the ClientAudioManager can only play 2D sounds for its respective client. However, the ClientAudioManager can also play 3D Sounds at specific positions, which can then be heard by other players, should they be in range of the sound.

Reflections

After Development on The Journey Above concluded, our group split apart to work on different projects. Myself and our 3D Artists and Game Designer wanted to continue evolving the World, so we decided to work as a Trio on Reflections. I took on the role of Solo Developer, meaning I was responsible for all Code in the Game once again. In addition to this, I also took on the role of Writer, as the story for this game was supposed to be very expansive, considering our dream to one day turn it into a full game.

In this project I was able to use my, now rather expansive, knowledge of the Unity Engine. In addition to making use of past knowledge, this game also allowed me my first proper insight into Quests and Enemy AI, which I used a lot of my time on.

Zelda-inspired Movement System

Just like The Journey Above, Reflections was supposed to use a third-person camera. However, since Reflections' gameplay loop is more oriented towards combat and stealth, we decided on a Movement System inspired by games like Genshin Impact of The Legend of Zelda: Breath of the Wild. This Movmement System was made fully compatible with my dependency-injection-driven Event System and uses a custom state machine to switch between movement states. 

The Movement in Reflections includes Walking, Running, Crouching and Jumping but can be expanded to include states like flying or swimming.

Advanced Ability System

The Ability System I made for The Journey Above may have worked for that game, however for Reflections I wanted to make a more modular and robust solution to which we could easily add more and more abilities as we wished. 

The System relies on an AbilityManager, which contains all of the player's unlocked abilities. The abilities themselves derive from an "Ability" parent class that includes basic functionality such as starting, updating or stopping the ability. Each ability could then decide what to do with these methods. Each ability is also tied directly to a specific keybind, which can be assigned in the inspector. In the final game, only the first five number keys, as well as the middle mouse button were assigned an ability, however due to the modularity of this system more abilities could be added at any time.

Custom Behavior Trees 

During the semester in which Reflections was being developed, I also had a subject known as "Game AI". I decided to combine my submission for this subject with Reflections and programmed a custom Behavior Tree System for Unity which includes basic functionality such as Sequences and Selectors. This System was then tested and implemented in the form of the two enemies of Reflections

The Peacekeeper, the main enemy found throughout the game, contained a simple patrol algorithm between multiple points as well as a field of view. When the player was spotted, the Peacekeeper would chase the player and use its melee attacks when in range. The Peacekeeper could be killed by hitting its weak spot at the back of its armor.

The Guardian served as the final boss of Reflections. It was found in an arena at the end of the main Level. The Guardian had a more complex set of abilities compared to the Peacekeeper. When the player starts the fight, the Guardian will first deploy four Peacekeepers to protect it and afterwards it will enter its combat state. In this combat state, the Guardian fires projectiles at the player when in range, and tries to stay away from the player in the meantime. Should the player come to close, the Guardian can unleash a shockwave that knocks back the player and deals damage. The Guardian has a weak spot on each of its four legs. Once these are destroyed by the player, the core of the Guardian exposes itself. When the core is struck, the Guardian dies.

Quest System

In addition to my work in AI, I also had a subject known as "IT II: Frontend Development". For this subject I could have either used a RestAPI in a WPF-Application or created an Editor Tool in a game engine of my choosing. 

I decided to create a visual editor for the Quest System we wanted to create for Reflections. This node-based system allows the Designer to create main- and side-quests with titles, descriptions and more. When a quest is completed, all successor quests are unlocked. These can then be displayed using a UI interface in the game itself.

The Journey Above

Due to the larger group size of this project (10 people), the distribution of tasks was slightly different here. I took on the role of Lead Developer, i.e. I distributed the tasks between myself and the other developer, but also generally continued to do the majority of the programming.

In this project I was able to expand my knowledge of the Unity engine, but also of dependency injection. In addition, this game also gave me insights into physics-based player movement, abilities and more complex UI dialogues.

Third-Person Movement

In comparison to Prisoner's Curse, The Journey Above was always intended to be a third-person game. Since I had never made a third-person controller before, this was my first experience with the systems connected to it. 

The movement controller I wrote was once again based on rigidbody movement. Due to the more natural shaping of the terrain, in comparison to the straightened terrain in Prisoner's Curse, I also learned about moving the character across slopes and other physics-based specifics. Other than that, the movement system once again only contains the basic features of walking and jumping.

This time the camera itself was made with Cinemachine, which marked my first contact with the tool. I was able to learn a lot about orbiting cameras, camera collision, culling masks etc.

Ability System
 

The gameplay loop of The Journey Above entailed the player unlocking five different abilities across the span of the game, all of which I created. 

These abilities rely on a RuneManager, which manages which abilities the player has already unlocked and can use in specific situations. The abilities themselves are all very different from each other. 

The first ability, "Leap", is a simple high jump that allows the player to reach higher elevations. The second ability, "Lotus Platform" creates a platform beneath the players feet which the player can walk on. The third ability, "Translocate", allows the player to swap the position of two objects marked with the "Swappable" Component. The fourth ability, "Radiant Unity", is the most complicated one. When activating this ability while looking at an object with the "Synchronizable" component attached, the component will start copying the players positional movement, while its rotation remains the same. The final ability, "Prismatic Surge", shoots a simple projectile in the direction the player is looking.

Puzzle Mechanics
 

In connection with the abilities in The Journey Above, I developed a multitude of Puzzle Objects and Mechanics for our Game Designer to then use for his Level Designs. 

This includes e.g. the previously mentioned "Swappable" and "Synchronizable" Components, which allow the objects to interact with their respective abilities. 

In addition to these basic components, I also created buttons/pressure pads, which could either be activated by shooting a prismatic surge at them or by moving a heavy object onto them. These buttons could then interact with other objects in the scene, such as Doors, which were also placed in the Levels. 

To unlock the abilities, I created robots that the player could "steal" the abilities from, using a simple timed minigame. However, to make the player not rely on a certain ability at all times, I also created "Inhibitors". These devices had a Box Collider around them which would prevent the player from using specific runes when inside of the radius.

All of these mechanics combined allowed for varied puzzle designs in the game world.

Shield Shader

During the development of The Journey Above, I also had a subject called "Shader Programming". In it, I learned about programming shaders in HLSL and GLSL but also about using the Shader Graph in Unity.

Using these tools, i created a magical barrier shader for the final set piece of The Journey Above, the magical tower the player travels towards in game. 

I had used the Shader Graph before, for example to make the water and clouds in Prisoner's Curse, but this was the first time fully understanding all the rendering and mathematical components the tool used to create the desired results.

Prisoner's Curse
A Mystery in Notes

In this game I took on the role of the team's (consisting of 6 people) sole developer and the Sound Designer/Composer. This taught me how to work independently and create my own workflow that would work with the given time constraints.


In this project I was also able to familiarize myself with the concepts of dependency injection, but also the general operations of the Unity engine.

Dependency-Injection-Driven Event System

Coming from a more standardized IT background, I found the basic Unity Event System to not exactly fit my needs, and so I decided to write my own system using the unity plugin Extenject and the Microsoft Prism library as a base. 

This system would allow not only for events to be broadcasted to all subscribers, but also allows for classes and their values to be shared between scenes and even throughout an entire project with relative ease. 

I would further evolve this system throughout my studies and still use it in my own work to this day.

First Person Movement
 

Since this was my first time properly working with Unity in a few years, I first wrote a simple first-person movement controller for the player using rigidbodies to make myself familiar with the engine and its workflows once again. 

The movement itself is fairly standard, only consisting of walking and jumping.

Interaction System, Inventory and Notes
 

Due to the more exploratory nature of Prisoner's Curse, the gameplay loop wasnt very rich in features. 

For the collectable items that could be found throughout the game and that were required to complete it, I wrote an interaction System for the player. It works by sending raycasts from the player. Should these raycasts hit an object with an "Interactable" component, the component calls its "HighlightMe" function, which in the case of Prisoner's Curse simply reveals a red outline around the object. This outline is deactivated when looking away. When the player presses the interaction keybind while looking at an Interactable, its "Interact" function is called. In Prisoner's Curse, the item is then added to the player's inventory and can be viewed in the notebook.

Alongside the notebook I also wrote a similar system to view and track the lore notes spread across the game world, the score of which could then be viewed on the end-screen of the game.



Ship Looter - Buoyancy Simulation

This aim of this project was to create a Physics-Simulation of our choice and implement it. My friend and I decided to make a small game where you play as a pirate ship. You sail around and are able to grab onto ships with a ballista and pull them in. Once reeled in, the ship will drop varying amounts of loot, which each weigh a different amount. These will have to be balanced into 6 crates aboard the ship, which can affect the buoyancy of your ship.

For this project I created the buoyancy-system, along with the enemy-AI. The buoyancy-system consists of invisible Floater-Objects submerged beneath the Ship that then apply relevant forces onto the ship's rigidbody, simulating buoyancy. It also takes into account the current wave height from the water shader I made. The Weight of the collected Loot is applied in a similar vain, applying a counterforce at the position of the respective crate.


Constrained Pathfinding

The aim was to create a pathfinding algorithm that works with various “constraints”.

The algorithm I used as a base for this project I found on GitHub, but I wrote the implementation and evaluation of its results as well as the visualization tool (with WPF) myself. In my example, I created a grid of pentagons, with each pentagon representing a biome that could be changed as desired. Now you could use the constraints to determine how many of the individual biome tiles the algorithm was allowed to use in its calculations to create the desired path.



Lands of Infinity

Lands of Infinity was my first introduction to the world of Programming and Game Development. It is also the longest consistent project I worked on. 

The idea for this project came to me when I was eleven and I then spent about seven years developing it with the help of my father, after which I published it.

Lands of Infinity is a large Minecraft mod in the style of an RPG game. I used it as a sort of playground for myself, where I tried out all possible facets of modding. Be it magic, enemies, world generation and dimensions, ranged weapons or much more.

After development was completed, there was a plan to port the mod to the newer Minecraft versions and thus "modernize" it. However, this plan was put on hold as it turned out to be too much work.

© Copyright. All rights reserved.

Wir benötigen Ihre Zustimmung zum Laden der Übersetzungen

Wir nutzen einen Drittanbieter-Service, um den Inhalt der Website zu übersetzen, der möglicherweise Daten über Ihre Aktivitäten sammelt. Bitte überprüfen Sie die Details in der Datenschutzerklärung und akzeptieren Sie den Dienst, um die Übersetzungen zu sehen.