Hi, I'm Radu!

Enthusiastic Creative Media and Game Technologies student on the path to becoming a skilled game programmer. Explore my evolving portfolio to observe my journey and achievements in the world of game development.

Projects

VR / Unity / 3 months / team of 5

Fast Food Worker Simulator (2023)

This VR game serves as a training simulator for fast-food workers in a future where 3D-printed food from recycled materials is the norm and efficiency is the key.

android & PC / Unity / 2 months / solo

Meal Master (2024)

Open the doors to a high-paced, culinary adventure where your cooking skills and time management will be put to the test.

PC / Unreal engine / 2 months / solo

Into The Backrooms (2024)

Survive the eerie backrooms by collecting seven mysterious images while evading a relentless, lurking menace.

PC / Unity / 2 months / solo

FPS Microgame: Leveling System (2024)

A dynamic leveling system with escalating enemy waves, providing strategic depth, enhanced progression and customization.

AR / Unity / 2 months / team of 4

De Buitenschool AR (2024)

With the help of our AR application designed for young explorers, visitors can embark on an immersive journey through the rich history and culture of Glimmen's primary school.

Prototypes

Pc / Unity / solo

ARPG Mechanics (2024)

Prototype that showcases my proficiency in developing core gameplay mechanics while adhering to clean coding practices such as DRY and SOLID principles.

© capnRadu. All rights reserved.

Education

Hanze University of Applied Sciences

Creative Media and Game Technologies (2022 - 2026)

Currently learning game development and several related topics, such as:

  • VR / AR Development

  • Mobile Development

  • Multiplayer Development

  • SOLID Principles

  • Unity

  • Unreal Engine

  • 3D Modeling / Animation

  • Game Design Theories

  • Scrum Methodology

  • Level / Narrative Design

  • User Experience / User Interface

  • User Research

University of Bucharest

Computer Science (2021 - 2022)

I studied Computer Science for one year in my home country. Some useful and interesting topics I have learned are:

  • x86 Assembly

  • Python

  • Computer Architecture

  • Linux / VirtualBox

  • Web Development

© capnRadu. All rights reserved.

Skills

Technical Skills

  • C# / C++

  • Unity

  • Unreal Engine

  • Git / GitHub

  • Blender

  • Figma

  • Trello

Soft Skills

  • Able to efficiently manage my time and prioritize my work

  • Able to plan my work and set goals

  • Able to constantly adapt to new work environments

  • Able to problem-solve through observation, brainstorming, and logical reasoning

  • Experienced at working within a team and being an active team member

  • Experienced at communicating and presenting ideas

  • Experienced at researching and troubleshooting encountered problems

© capnRadu. All rights reserved.

About Me

profile-pic

My name is Radu Duicu, known online as "capnRadu." I began my gaming journey at a young age with classics like Counter-Strike and Minecraft, which sparked my passion for gaming. During high school, I developed my programming skills in C++ and explored editing tools like Photoshop and Sony Vegas, enjoying the creative process.My curiosity about how code creates engaging experiences led me to study computer science, where I gained valuable insights into Python and x86 Assembly, enhancing my critical thinking skills. Despite the field not fully satisfying my aspirations, this experience solidified my passion for programming.Currently, I am a third-year student at Hanze University of Applied Sciences, where I have been exposed to game industry programs and have had the privilege of collaborating with exceptional individuals on group projects. It is within this environment that I have discovered my passion for becoming a game programmer.

Delusions: Shadows of the Mind

pc / Unity / 1 month / solo

About

The challenge involved the creation of a polished and playable game level. This encompassed not only the actual development of the level but also the creation of a comprehensive game design document outlining the underlying concept.The project demanded the application of diverse game design theories, spanning across mechanics, narrative, aesthetics, and various other facets of game development.

Work Method

I developed a structured approach to the GDD creation. This involved starting with a high-level overview outlining the game's core concept, target audience, goals, and key elements, highlighting the originality and innovative aspects of the game design, emphasizing its unique contributions, and detailing the level design, including item placement, player progression, flow, pacing, and aesthetics.Finally, I translated the GDD into a functional level by selecting and implementing assets while ensuring proper documentation of their source within the GDD, constructing a playable space with objectives, collectibles, pickups, and other elements that complemented the overall game concept and provided a clear beginning and end to the level.This project showcased my ability to create well-documented game design documents and translate them into engaging and well-structured game levels.

Gameplay

Players step into the shoes of an individual navigating the challenges of obsessive-compulsive disorder, confronting the daily struggle of maintaining a balance between work and an overpowering urge for cleanliness.The narrative takes an unexpected turn when the protagonist's cleaning routine becomes a gateway to an alternate dimension. In this surreal realm, identical houses present opportunities to escape, but only by meeting strict cleaning challenges within tight time constraints, enduring disturbances, and visual distortions.

Unique Selling Points

This game stands out for its unique blend of features that create a captivating and unsettling experience. Visually, it combines VHS and PS1 aesthetics, resulting in a nostalgic yet striking atmosphere. The narrative delves into mental health themes, specifically the protagonist's struggle with OCD, offering a nuanced exploration that adds depth and emotional connection.The horror atmosphere is crafted through disturbing visuals, eerie soundscapes, and unsettling environments that heighten player tension and perception. Surreal environments in an alternate dimension add another layer of mystery and challenge, forcing players to navigate distorted realities. To further immerse players, the game incorporates skill checks during the cleaning process, requiring active participation and decisions that directly impact the atmosphere.Furthermore, the puzzle-driven gameplay with environmental puzzles demands critical thinking and strategic decision-making, keeping players engaged and adding to the overall challenge.

Obtained Skills

  • Game design

  • Level design

  • Narrative crafting

  • Psychological horror design

  • Skill-based gameplay implementation

  • Puzzle design

  • Challenges implementation

  • Dramatic progression

  • Feedback loops

  • Difficulty progression

Check out the project

Gallery

© capnRadu. All rights reserved.

ARPG Mechanics

PC / Unity / solo
Github / Itch.io

About

I developed this prototype as a way to strengthen my understanding of software design principles, particularly SOLID and the DRY method. My focus was on writing clean and modular code that’s easy to maintain and scale as the project evolves. Building interactive game systems was an excellent way to put these concepts into practice.Besides, I've always liked the gameplay and mechanics of the ARPG genre. Developing core systems like movement, combat, abilities, and enemy AI and getting them work both independently and together was an exciting challenge, and it pushed me to grow my skills as a game programmer while working on a project I’m passionate about.The project features core mechanics inspired by action RPGs like Diablo, such as point-and-click / hold movement, abilities including the primary slash attack, the charge ability, and the rage ability, and potions used to refill the health or mana points. Additionally, skeleton enemies that follow the player and engage in close combat are continuously spawned throughout the map.

Player Mechanics

The PlayerController script enables the player interact with the game world using a point-and-click system.There are 2 ways the player can move:
- by pressing the LMB on a specific location, thus triggering the player object to move to the destination;
- by holding the LMB and triggering the player object to follow the mouse cursor's location.
Using the Input System package, the movement is coordinated by 2 methods:
- SetDestinationPerformed, which is triggered when the player presses the LMB but doesn't release it:

  • Here, the bool variable isKeyHeld is set to true, and the StartFollowingDestination method is called, which starts the FollowToDestination coroutine to continuously update the player's destination while the LMB is held.

  • This coroutine uses the GetLocationUnderMouse method to find the mouse destination, and if the player is not targeting a damageable object, it will move towards the destination and play a walking animation.

- SetDestinationCanceled, which is triggered when the LMB is released:

  • Here, the bool variable isKeyHeld is set to false, and the HandleInteractionOrMove method determines whether to perform an attack or move to a destination when the input is released, by using the GetLocationUnderMouse method.


The PlayerCombat script manages the player's combat actions, allowing them to cast abilities, consume health and mana potions, and handle cooldowns.In the Update method, the UpdateHealthPotions and UpdateManaPotions methods handle the refill of the respective potions.The CastAbility method encapsulates the logic necessary for executing abilities in the game, ensuring that players can only cast when they have the necessary resources and are not already casting another ability.

Abilities Mechanics

The Ability script is the base class for all of the player's abilities. The Setup and ActivateAbility methods are used by the child scripts of this class to perform the necessary initializations and logic.In the Update method, the UpdateCooldown, UpdateCastDuration, and UpdateBuffDuration method are used, in order, to decrease the cooldown timer and destroy the ability object when the cooldown reaches zero, signaling that it can no longer be used, reduces the castDuration timer and disable the ability when the duration ends, manage the buffDuration and call the Debuff method when the duration ends.


The AbilitySlash script is designed to represent a slashing attack. The OnCollisionEnter method is triggered when the ability collides with another object. It checks if the collided object is the intended target and if the ability is active.
If the conditions are met, it retrieves the Stats components from both the caster and the target and starts a coroutine to deal damage.


The AbilityCharge script implements behavior for the charging mechanic. When the ability is activated, the transform is set to be a child of the caster, and the ChargeForward coroutine starts. Here, The caster's position is continuously updated in the forward direction, moving them rapidly forward. Similarly to the slash ability, the OnCollisionEnter method is triggered when the charging ability collides with another object and handles the damage.


The AbilityRage script is used to significantly increase the caster's strength and restore their health when activated. When the ability is activated, the Buff method is called to apply the strength buff and health restoration. The Debuff method is called when the ability is deactivated and is used to reduce the caster's strength back to its original value.

Enemy Mechanics

The Enemy script implements the IDamageable interface, indicating that it can take damage, and includes functionality for movement, attacking, and animations.The Update method is used to check the distance to the player and update the enemy's state based on their position. It calls the Attack method if the player is within attack range; otherwise, it calls ChasePlayer to pursue the player.The ChasePlayer method sets the destination for the NavMeshAgent to the player's position, and activates the walking animation if the enemy is not already in the walking state.The Attack method resets the NavMeshAgent's path, updates the animation, and starts the AssessAttack coroutine, which waits for half the duration of the attack animation before playing the slash sound, and checks if the player is still in attack range and deals damage to the player if so. Besides, the ResetAttack coroutine is used to allow the enemy to attack again and randomize the attack delay to vary the timing.

Stats Mechanics

The Stats script represents the attributes of a character and provides functionality for managing health and mana, including taking damage, refilling health or mana, and determining whether the character is alive.The TakeDamage method handles the health / damage system of the game and utilizes the Die method to handle character's death.The DisableObject method is used to prevent further interactions while the character is dead, but the animation is not yet complete.The GetPercentage methods are used by the UI to update the progress bars of the respective resources, while the Refill methods are used by the health and mana potions.

Obtained Skills

  • Software design principles by experimenting with the application of SOLID principles and the DRY method throughout the development process to write maintainable code.

  • Input handling through the use of Unity's enhanced Input System to create interactive mechanics while gaining knowledge in event-driven programming.

  • Combat system design by creating combat systems and abilities, and ensuring proper interactions with the enemy AI.

  • AI programming by using Unity's NavMesh to develop an enemy behavior capable of chasing and attacking the player.

Gallery

© capnRadu. All rights reserved.

Meal Master

android & PC / Unity / 2 months / solo
Github / Itch.io

About

The goal of the project was to gain familiarity with the mobile development workflow by designing a game concept and releasing it on mobile platforms.This involved building the appropriate user interface, examining the user experience in relation to the needs of the chosen target audience, and researching analytics and monetization methods.

Concept

Meal Master is a fast-paced game where players manage a kitchen, fulfilling customer orders while balancing cooking and time management.Players start with 3 chef hats, and if an order's waiting time expires, a hat is lost, ending the round when all hats are gone. There are two modes: novice, for a relaxed pace, and expert, with faster customers, more orders, and higher rewards.With the collected money from each completed order, players can purchase upgrades for various skills and kitchen tools.

Design Requirements

Business Requirements

  • Single-player mobile game for casual gamers aged 16-35.

  • Quick, intense gameplay for short sessions (max 15 minutes).

  • Fast-paced with increasing difficulty and light stress.

  • Offers rewards to trigger dopamine and a variety of customization options to maintain engagement.


Functional Requirements

  • Players view and fulfill customer orders with specific prep times.

  • Point-and-click navigation for interacting with kitchen tools and serving orders.

  • Players have three chef hats, losing one if orders expire, and ending the round if all are lost.

  • Game modes: novice (beginner) and expert (unlocked after round 5).

  • Players can upgrade skills and tools using earned money.


Qualitative Requirements

  • Immersive, intuitive, and user-friendly experience.

  • Provides progression, achievement rewards, and high replay value with customization.

  • Minimal tutorials, offering immediate rewards to keep players motivated.

Analytics

OverviewThe game includes analytics to track player stats and events, such as rounds completed, customer order times, failed or incorrect orders, and upgrades purchased.


Custom Events and Parameters


FunctionalityThe AnalyticsManager script deals with the initialization of the analytics service, as well as starting the data collection only if the player gave their consent using the consent menu.The ConsentMenu script is attached to the consent menu object and deals with the functionality of the 3 buttons present: opt in, opt out, and delete data and opt out.Regarding the actual tracking, we first have the GameManager script which tracks the roundReached event (from line 100), the failedOrder event (from line 201), and the gameOver event (from line 272).The PlayerController script tracks the completedOrder event (from line 218), and the wrongOrder event (from line 229).The UpgradeStandard script tracks the upgradePurchase event (from line 109).The RoundEndMenu script tracks the roundEnd event, and the Menus script tracks the chooseGameMode event (from line 70).

Ads Monetization

OverviewFor monetization, I researched Unity ad integration and various ad types. To avoid disrupting the player experience, I chose to implement only rewarded ads. When players lose all 3 chef hats, they can watch an ad to refill them, making the ad experience optional.


FunctionalityThe AdsManager script is used to load the rewarded ad on awake, instead of loading it right when displaying it, to prevent ads not showing on the spot and being shown later, thus potentially causing bugs, while the InitializeAds and RewardedAds scripts are used for different ad methods.The GameManager script is then used to trigger the ad and handle the reward logic (from line 256).

In-App Purchases

OverviewFor the IAP service, I figured the most basic way to implement them would be under the form of in-game currency. Inside the shop menu, players have 4 money packs available for purchase. For these, I used the IAP buttons and populated the IAP catalog with the 4 different options.


FunctionalityThe ShopMenu script is attached to the shop menu object, and it has the BuyMoney method, which is triggered when players purchase a money pack.

Player Prefs

OverviewIn terms of the saving and loading system, I researched ways on the best practices when implementing such system. I found methods using more complex approaches that are suitable for bigger games, and the PlayerPrefs approach, which has its limitations but is perfect for the game I developed.


FunctionalityThe SaveLoadManager script deals with the saving and loading by using the SaveGame and LoadGame methods which use the PlayerPrefs class to update the values that need to be saved or loaded, while the Menus script uses the Quit method to either save the game or delete all player saves.

Player Mechanics

The PlayerController script manages the player's interaction within the game, using a NavMeshAgent for movement and handling various interactions like picking up items, grilling, and serving customers.

Movement

  • The player can click to move. The script detects mouse clicks and casts a ray from the camera to the clicked location.

  • If the ray hits a valid object, the player's agent moves to that point.

  • If the hit object is "interactable," it is stored for interaction once the player arrives.

  • The HasReachedDestination method checks if the player has arrived at the target location.

Item Interactions

  • The PickUp method allows the player to pick up interactable objects, instantiating them and attaching them to a specific holding point.

  • The Tray method manages the placement or swapping of items on tray points.

  • The Grill method handles placing or picking up patties on the grill, ensuring they are properly cooked.

  • The Serve method manages serving items to customers, verifying if the item matches the order, and plays success or error sounds based on the match and handles customer satisfaction and coin rewards.

Interactables Mechanics

The interactables system is made out of two key components: the Interactable interface which provides the Interact method for any class that implements it, and the BasicIngredient script which serves as a base class for different types of ingredients.

DeepFryer script

  • If the fryer is started, it counts down the cooking time and indicates when the fries are ready.

  • Initiates frying if not already fried; allows the player to pick up the fries once they are cooked.

Buns script

  • Calls the FinishHamburger method on the PlayerController, indicating the completion of a hamburger when the bun is used.

Grill script

  • Calls the Grill method on PlayerController, allowing the player to place a patty on the grill.

Patty script

  • Tracks cooking time and updates its appearance once cooked.

  • Displays a timer while the patty is cooking.

SodaMachine script

  • Similar to the fryer and grill, it tracks how long it takes to refill.

  • Allows the player to refill the soda when it’s available.

Customer Mechanics

The Customer script manages the behavior of customers in the game, including their movement, order management, emotions, and interactions with the player.

Attributes and State Management

  • The class maintains various attributes, including the customer's order, animation state, timer for waiting, and emotional state (happy, confused, or angry).

  • It uses a list of waypoints to determine the path the customer will take, including checkpoints for order placement and a final destroy point.

Movement

  • The MoveToWaypoints coroutine moves the customer through the defined waypoints while checking their position and updating animations. It also handles the customer's order and emotional state during this movement.

Order Handling

  • Upon reaching the order point, the customer receives their order and displays a timer bar along with icons representing the order's status. The customer’s emotional state changes based on the time spent waiting for their order.

Upgrade Mechanics

The UpgradeStandard script is responsible for managing a specific upgrade within the game. It allows players to purchase and apply upgrades to various game aspects, such as enhancing a grill, fryer, or increasing player speed.

Methods

  • The Start method initializes the upgrade details by fetching the current values from a global Upgrades instance, setting UI text accordingly.

  • The BuyUpgrade method handles the purchase of the upgrade, ensuring the player has enough money and that the upgrade isn't already at max level. If purchased, it increases the upgrade level and amount, updates costs, and plays sound effects.


The Upgrades script manages all possible upgrades in the game and tracks player money. It acts as a singleton, ensuring only one instance exists throughout the game.

Game Manager Mechanics

The GameManager script organizes gameplay by managing customer spawning, round progression, and player interactions.

Methods

  • The Start method initializes game settings based on the selected difficulty and starts the first round.

  • The Update method continuously checks if new customers can spawn and manages transitions between rounds based on customer counts.

  • The NewRound method increments the round, adjusts spawn rates, and updates UI elements.

  • The SpawnCustomer method handles the instantiation of new customers with random orders based on the difficulty level.

  • The RoundPanel coroutine smoothly scales the round panel UI when a new round starts, ensuring a polished transition.

  • The CustomerSpawning coroutine delays the spawning of customers based on the defined spawn rate.

Obtained Skills

  • Mobile game development by designing and developing a mobile game from concept to release.

  • UI design by creating an intuitive and user-friendly interface which focuses on accessibility and ease of navigation.

  • UX research by conducting research on target audience preferences, emphasizing gameplay mechanics that encourage engagement and enjoyment.

  • Data analytics by implementing a system that tracks player interactions and game events to assess important metrics such as player engagement, retention, and behavior.

  • Game monetization by integrating monetization methods, focusing on non-intrusive options to ensure that the ad experience enhances gameplay rather than disrupts it.

  • In-app purchases by managing the setup of catalogs and buttons, allowing players to buy money packs.

  • Save and load feature by designing a system that enables players to save progress and load it automatically.

Gallery

© capnRadu. All rights reserved.

Fast Food Worker Simulator

VR / Unity / 3 months / team of 5
GitHub

About

Working within a team of 5 members, we faced the challenge of conceptualizing and creating a game set 30 years in the future, considering VR breakthroughs and upcoming gaming technologies.I took charge of the programming aspect and collaborated closely with the team to brainstorm ideas, design mechanics, and implement features.

Concept

In our game, set in a futuristic world, 3D-printed fast food from recycled materials has revolutionized the culinary landscape, offering convenience, affordability, and sustainability. The game serves as a tutorial simulation for fast-food workers, teaching them efficient 3D printer use for food preparation.One potential challenge that needed to be addressed was the initial hesitation among restaurant workers toward this new technology, potentially leading to discouragement. To address this challenge, we created an interactive tutorial game that presents essential skills in an engaging manner, empowering workers to embrace the future confidently.

Gameplay

Players, taking on the role of aspiring employees, engage in a tutorial simulation that guides them through various challenges representative of real-world fast-food kitchen situations. Customers have the option to choose from three distinct recipes: hamburger, hotdog, and the daily special.The overarching objective is for players to successfully navigate and master the essential skills involved in handling 3D printers, ensuring the proper printing and assembly of the received orders. Moreover, players are tasked with maintaining the 3D printers, ensuring their optimal functionality.

Core Mechanics: NPCs

The first version included core functions, such as spawning, moving to the counter, ordering, receiving the order, and moving to a destroy point. Upon instantiation, the script selects an order and transitions to the "spawn" state, then moves the NPC to the counter. After ordering, the NPC waits for the ordered object and transitions to the "destroy" state upon completion.


The second version introduced additional mechanics, including a timer bar for orders, a complex hamburger order check, and movement improvements. The system utilizes a recipe index using powers of ten to represent ingredients. Upon instantiation, the NPC randomly generates the order index. During the "order" state, the NPC waits for the order to be completed, checking if the entered collision matches the ordered hamburger. If the timer expires or the order is fulfilled, the NPC moves to the destroy point.


The final version introduced new recipes, difficulty progression, star ratings, new NPC models, and dynamic timers. Building on the previous recipe index mechanic, two new recipes were added: a hotdog and "today's special". For multiple orders, the script randomly selects a first order and, after a certain number of customers, a second order. The script adjusts timer length based on order complexity and generates recipe indexes for both orders. A new "order 2" state handles the second order.

Core Mechanics: Recipes

The first version includes ingredients like bottom bun, patty, cheese, bacon, and top bun. Attached to the bottom bun prefab, the script references ingredient prefabs and their indexes. In OnCollisionEnter, it checks object tags, calls AddIngredient, and updates the order index used by the NPC script for order verification. AddIngredient handles ingredient placement on the bottom bun, adjusting position and collider size accordingly.


The final version manages ingredient placement but accommodates new ingredients and improves spacing precision. With additions like tomatoes, onions, and salad, the script is structured similarly to handle the hot dog recipe. During initialization, spacing is adjusted for precise placement, and a DestroyObject function is added for unused ingredients. Spacing calculations ensure accurate placement on the bottom bun or previously added ingredients.

Core Mechanics: 3D Printers

In the initial development stages, I develped two object instantiating mechanics: a 3D printer system and in-hand instantiating. The 3D printer mechanic relies on OnTriggerEnter and OnTriggerExit to detect button presses, invoking functions accordingly. The SpawnObject function then instantiates a specified GameObject at the spawn point. Conversely, the in-hand instantiating script, inheriting XRBaseInteractable, uses OnSelectEntered to simultaneously instantiate and grab an object.


Once we chose to go with the 3D printer, I developed the second version of the mechanic. Structurally, it is the same as before, with only one addition to the SpawnObject function. The object is now instantiated only if the isInstantiated bool variable is false, which means if the printing space is free, in order to limit the number of spawned objects.


In the final version, new features included a cleaning system, smoke particles, and difficulty progression. Printer damage is managed by another script. The script sets printer health and damage bar position, adjusting smoke emission based on health. Cleaning is triggered by the OnTriggerStay method, checking for a sponge and enabling cleaning only when necessary. An IncreaseDeterioration function decreases printer health when spawning objects. The CleaningObject script utilizes an IEnumerator to detect sponge movement, tracking positions to determine movement.

Obtained Skills

  • VR development by working with immersive environments and creating core gameplay mechanics.

  • Performance optimizations by using static batching, GPU instancing, and occlusion culling.

  • Future literacy by employing the causal layered analysis methodology to envision and transform future scenarios.

  • Serious game design by developing a game that addresses real-world challenges.

Gallery

© capnRadu. All rights reserved.

FPS Microgame: Leveling System

PC / Unity / 2 months / solo
Github / Itch.io

About

The objective of the project was to simulate a professional game studio environment by implementing a specific feature within an existing codebase, the FPS Microgame.This process involved three primary phases: research, writing the technical design document, and implementation.

Work Method

For the feature, I opted to implement a leveling system, driven by my desire to understand the FPS Microgame codebase and enhance my ability to plan ahead for scripts by envisioning how different mechanics will interact with each other.Regarding the research phase, the feature draws inspiration Brotato and Hades. These influences converge to create a dynamic leveling system that enriches player progression and customization.Based on this, the requirement list for the leveling system mechanics included XP and coin gain, a level-up menu, a shop menu, a stats menu, and the persisting upgrades.

Gameplay

The FPS Microgame's leveling system adds depth and challenge, shaping gameplay into a series of escalating enemy waves. Players initiate runs from the main menu, respawning at the first wave upon death, retaining persistent upgrades but forfeiting skills and coins. Each wave increases in difficulty, rewarding successful eliminations with XP and coins.After each wave, players access the level-up menu for stat boosts and the shop menu for skill purchases using coins. The stats menu tracks upgrades and skills.

Technical Design

Various UML diagrams were used during development to visually represent the feature's systems, aiding in understanding design, code architecture, and implementation.

Object Diagram

This diagram illustrates multiple gameplay objects instantiated within the FPS Microgame's main scene, including hoverbots and Patrol GameObjects utilizing the PatrolPath script. To integrate the leveling system, the WaveManager script spawns multiple enemies. However, using the Enemy_HoverBot prefab led to shared patrol routes, requiring a prefab with unique routes. Two issues arose: Enemy_HoverBot lacked a PatrolPath reference, resolved by obtaining it from the parent, and hoverbot destruction left the Patrol GameObject, addressed by checking if the EnemyController component from its child was null. The second part depicts the Skill script and its instances, representing skills in the shop menu, with additional details provided in the class diagram section.


Flowchart

The flowchart visually breaks down the multiple interactions, processes, and decision points that contribute to the logical functioning of the system during gameplay.


Class Diagram

The class diagram visualizes the object-oriented aspect of the system. The WaveManager script serves as the foundational component, managing player upgrades, resources persistence, and the wave system. Key functionalities include NextWave and SpawnEnemies methods for enemy spawning and progression, along with a ResetWave method for new run initialization. It has a composition relationship with the GameFlowManager script for sound effects during wave starts.During final testing, I identified a chance to improve the wave system. The original design, relying on a fixed enemy count to progress, felt static. Building on playtesting insights, I introduced a second iteration with a 45-second wave timer, spawning mini waves upon eliminating the previous enemies.The GameFlowManager script controls the game flow, checking objectives, player death, and scene transitions. It has a composition relationship with PlayerResources, loading the level-up menu on level-up and the shop menu otherwise.PlayerResources maintains player resource information, with methods like GainCoins, GainXP, and HandleXP for updating values upon enemy elimination. It has composition relationships with WaveManager and SkillManager to update persistent values.The Health script manages player and enemy health, using RegenHP, Heal, TakeDamage, HandleDeath, and Kill methods. It has an aggregation relationship with PlayerResources for coin and XP updates, and composition relationships with WaveManager for health upgrades, and SkillManager for HP regeneration updates.SkillManager handles player skill persistence, level, and stats. It uses InstantiateSkills to spawn skills in the shop menu.The Skill script, associated with each skill prefab, initializes skill values and updates UI text. It has a composition relationship with SkillManager for communication and value updates.The BuySkill script manages skill purchases and upgrades, checking and updating player coins through WaveManager and stats via SkillManager.ChooseUpgrade handles upgrades within the level-up menu, using the Upgrade method. It has a composition relationship with WaveManager for persistent value updates.PlayerCharacterController controls player movement, with a composition relationship with WaveManager for applying speed upgrades.WeaponController maintains the weapons system, aggregating WaveManager for damage upgrades.

Reflection

Implementing this feature was a rewarding experience that contributed to my personal learning. Exploring the codebase deepened my understanding of its mechanics, while organizing scripts into multiple assemblies, though challenging, offered valuable insights. UML diagrams were crucial for planning and structuring the leveling system.I've grown significantly by adopting a disciplined, methodical approach to project planning, reducing issues like spaghetti code and redundancy. This project helped me overcome my lack of experience working within an existing codebase, refining my skills along the way.

Obtained Skills

  • Feature implementation by designing and integrating a leveling system into an existing project.

  • Working with existing codebase by navigating and extending a pre-existing codebase, and working within the game's architecture to ensure that my system communicated effectively with existing components.

  • Researching by understanding gameplay systems and industry-standard design practices.

  • Technical design by creating a document outlining key components, object relationships, and system interactions.

  • Working with assembly definitions by compartmentalizing different aspects of the leveling system.

  • Planning and organizing scripts to ensure smooth interaction between the system and the existing mechanics.

  • UML diagrams to map out system interactions and design a clear architecture for the leveling system.

Gallery

© capnRadu. All rights reserved.

De Buitenschool AR

AR / Unity / 2 months / team of 4
Github

About

As part of a 4-member team, I was tasked with programming and collaborating with a UI designer. We aimed to address a specific challenge posed by our client, De Buitenschool. They needed a solution to attract a significant number of visitors to elevate Gilmmen’s primary school into a popular destination in the region.Employing Agile methodology, we embarked on developing an AR application. Our focus was on delivering an immersive experience, covering the school's architecture, history, art, and culture. We tailored the app for children aged 12 to 15.The outcome was an engaging AR application that showcased the school's features and heritage. Our solution not only met the client's objectives but also provided an interactive experience for the visitors.

Work Method

Before this project, I had no experience with augmented reality development, making it an exciting project for me. To acquaint myself with AR concepts, I explored the Unity AR Foundation samples, experimenting with each one and studying the scripts.Given our app's emphasis on image recognition and multiple scanned images displaying specific prefabs, I delved into tutorials covering Unity's image recognition basics. Alongside programming the app's functionality, I designed the UI menu to present sticker information.

Gameplay

The app comes with a main flyer given to visitors upon arrival, featuring a QR code for app download. Once installed, scanning the flyer initiates a mini-story and objective: explore the surroundings, find stickers, and scan them.Each sticker scan prompts a related image puzzle, designed to engage users. However, the puzzle feature, created by another team member, was not integrated into the app. After the puzzle is completed, users can read the presented information, or press the history button, and read information about its past.Information is provided for four stickers, including a secret one unlocked after scanning the others. An inventory menu allows users to access unlocked sticker info at any time without revisiting the school.

Development

Regarding functionality, the PrefabTracking script handles the image recognition and instantiating of prefabs by having an array of GameObjects where the prefabs are placed. After the prefab is created, the scale and position are defined such that it appears on the right side of the tracked image.The FlyerEnable script handles information about the prefabs. When a prefab is created, the script checks if the prefab is not the main flyer or the secret sticker and if it wasn't already present in the scene to increase the scanned stickers count. This is important so the secret sticker is unlocked only when the first 3 stickers are scanned. The next part of the script, alongside the StickerStatusUI script, handles the UI from the inventory menu, specifically the locked/unlocked text.The ScannedStickers script is used only to keep track of the number of scanned stickers, so it can pass the value to the SecretStickerMechanic.The SecretStickerMechanic script handles the status of the secret sticker; if the other 3 stickers were scanned, then its content becomes available.The ButtonScript handles the logic of the "History" and "Back" buttons that are present inside each prefab, while the ButtonsUI script handles the button logic and functions from the inventory menu.

Obtained Skills

  • AR development by experimenting with various AR samples and creating scripts which controlled core AR functionality.

  • Wireframing by greyboxing the UX and UI, and defining the layout and flow of the app.

  • User researching by gathering and analyzing insights on what types of features would engage and appeal the age group.

  • Communicating and fulfilling client's needs by understanding their primary goal and participating in meetings for discussing progress, changes, and feedback.

Gallery

© capnRadu. All rights reserved.

Into The Backrooms

PC / Unreal engine / 2 months / solo
Gitlab / itch.io

About

The objective of the project was to experiment with Unreal Engine’s capabilities and visual scripting system by creating an interactive project using one of the standard templates. Initially unsure of a clear direction amid experimenting with various concepts, reminiscing about old horror games provided a starting point.Inspired by the uncanny ambience of the backrooms map, I crafted a first-person horror game, integrating a skill check system I had previously developed in Unity. While comfortable with the mechanics, adapting them to Unreal Engine posed its own set of challenges.

Gameplay

Players must navigate the backrooms and find seven scattered images to escape. Each image retrieval requires passing a skill check; failure prompts respawn of the image, prolonging the challenge.Armed with only a flashlight, their stamina, and limited resources like energy drinks and batteries, players must evade a relentless entity.

AI

Logic

The AI setup consists of a main entity blueprint, a blackboard with a behavior tree, and an AI controller for executing the tree's logic. When the "seePlayer" variable is false, the entity roams the map, pausing briefly between selecting random destinations. If "seePlayer" is true, the AI pursues and, if needed, eliminates the player.The "seePlayer" value is set by the main blueprint using a pawn sensing component. On detecting the player, "seePlayer" switches to true. To prevent continuous pursuit, a scheduled event resets "seePlayer" to false every 0.8 seconds. This ensures the entity doesn't endlessly chase the player.


TasksRegarding the actual tasks, the roam task selects a random map position for entity movement, while the chase player task directs it toward the player's location.The kill player task triggers the "kill player" event in the main entity blueprint, using a sphere trace to inflict damage. Upon damage detection in the “anydamage” event from the first-person character blueprint, a sound plays, a jumpscare widget appears, and the level restarts. To ensure this sequence occurs only once, the "wasKilled" variable is used, ensuring smooth animations and delays without multiple activations.


Speed and animation rateThe remaining logic deals with the walking speed and animation rate across three speed modes: normal, chasing, and slowed. Each mode corresponds to unique animation rate scales.In the roam and chase tasks, adjustments are made to the entity's walk speed and animation rate scale to match the designated mode. The slowed movement and rate scale are triggered by the player activating the flashlight. When the flashlight is on, the "slowentity" event is triggered in the first-person character blueprint, applying damage to the entity if hit. Upon receiving damage in the entity blueprint, the "wasSlowed" variable is toggled true, adjusting the walk speed and animation rate scale accordingly.In the chase player task, the walk speed and rate scale values are set to chasing only if the entity is not slowed by the flashlight. In the event tick, the "wasSlowed" variable is checked and set to false after a 0.2-second delay if the flashlight is no longer pointed at the entity. This ensures that the entity's speed and rate scale return to their expected values.

First Person Character

SprintingI adapted a sprinting tutorial to allow sprinting initiation by either pressing left shift then W or W then left shift.For the first option, after pressing left shift, if movement is active and canSprint is true, sprinting begins, increasing footstep rate, max walk speed, and changing camera FOV. Upon release, sprinting stops, resetting footstep rate, max walk speed, and restoring camera FOV.The second option, starting with W, functions similarly but swaps isSprinting with canSprint.Aside from the ChangeFov timeline, additional actions occur. When sprinting begins, the stamina bar widget is added, and stamina drains every 0.2 seconds. If stamina is depleted or movement ceases, sprinting stops, resetting values and triggering gasp sound if possible.


FlashlightWhen the flashlight input is pressed, we first check if player movement is active. If so, we play a sound and assess the battery status.Subsequently, we trigger a sequence: draining the battery, adding the flashlight bar widget to the viewport, and slowing the entity. In the drain battery event, we decrease battery level. If the battery depletes, we reset the spotlight visibility and remove the flashlight bar widget if the battery is full and if it's on the screen.The removeWidget custom event is used when obtaining a battery, resetting isBatteryEmpty and checking if the battery is above 100. If true, and the flashlight bar widget is on the screen and the spotlight is invisible, we remove the widget.


LeaningThe leaning input action (Q or E) stores the camera's target location. In the select node, the left and right lean target locations are stored, with the default camera location in the middle.Camera location changes occur in the tick event. Interpolation moves the camera from its current position to the target location. To adjust the camera angle to 45 degrees, controller rotation is modified using interpolation and a rotator. Pitch and yaw use controller values, while roll selects between left and right lean rotations.

Images and Skill Checks

The game features 7 collectable images, each with two possible spawn points for replayability. Interacting with an image triggers a skill check; passing collects the image, failing respawns it to the next point.The image collectable blueprint manages spawn points via an array variable. On begin play, a random spawn point is chosen, updating the image's location and rotation. The image is then unhidden, and a reference to the image manager is stored. Upon interaction, the blueprint creates a skill check widget.The image manager blueprint tracks collected images and facilitates communication between the skill check and the image collectable blueprint. It also updates the image collect widget to display collected and remaining images.

The skill check widget comprises three components: a full white circle, a movable black section, and a red target section for passing the check. Inside the graph view, in the preconstruct event, the red section's angle is randomized, and references are stored while player movement and input is disabled.Upon interaction, the skill check is displayed, a sound plays, and the image is disabled pending results. If the skill check input is pressed, the black section stops, and the angle is checked for success.Using a blueprint interface, the skill check communicates results to the image manager, updating settings accordingly. Failures trigger spawn point adjustments and speed reduction, while successes remove the image, increase speed, and update collected images. If all images are collected, the end level is triggered.

Obtained Skills

  • Proficiency in Unreal Engine by using the engine's tools and visual scripting system to implement various game mechanics.

  • Familiarity with the first person template by customizing it to meet the demands of a horror game and implementing new features.

  • Blueprint visual scripting by creating custom blueprints for player interaction, AI behaviors, and skill checks.

  • Behavior trees and tasks by creating a custom AI system and programming tasks to simulate complex enemy behavior.

  • AI logic by implementing an AI system capable of pursuing, attacking, and adapting to the player's mechanics.

  • Horror game development by designing and implementing mechanics tailored for horror gameplay, with a focus on creating a tense and eerie atmosphere.

Gallery

© capnRadu. All rights reserved.