Games Development - Final Project : Playable Game

21/04/2025 -  ( Week 11 - Week 14 )

Ho Winnie / 0364866 

Games Development / Bachelor's of Design Honors In Creative Media 

Final Project : Playable Game




1. Final Project : Playable Game

Requirements : 

Students will integrate their art asset to their game development and produce a fully functional and playable game. 

Progression : 

For our final project of Sands of the Stolen Heart, our main goal is to complete the full level of the game and bring all core mechanics to life. This includes finalizing the crafting system for minions, expanding it to allow players to summon more followers, turrets, and shields to aid Sahira in her quest to collect souls. We will also be adding new enemy types to make the gameplay more dynamic and challenging.

A key focus will be on designing and implementing the full boss mechanics for Anubis. The boss fight will feature two distinct phases, with Anubis entering an ultra state once his health drops below 20%, unleashing stronger attacks and patterns to intensify the final showdown.

Additionally, we will develop the game’s introduction and ending sequences to complete the narrative experience. For this phase, I will take charge of writing the intro/outro story and finalizing the crafting mechanics, while my teammate will focus on building out Anubis’s full boss mechanics.

This final milestone will tie together everything we’ve built so far, ensuring players experience a complete and polished adventure.

My Tasks :
  • Write and finalize the intro and outro story to complete the game’s narrative.

  • Complete the crafting system for minions, including:

    • Adding new followers, turrets, and shields as craftable options.

    • Balancing crafting costs and progression.

    • Add more enemy types to make combat and soul collection more engaging

Guo Ying’s Tasks : 
  • Build the full boss mechanics for Anubis, including:

    • Implementing two boss phases, with the ultra state activating below 20% health.

    • Designing new attack patterns for both phases.

  • Conduct combat balancing and bug fixing for boss fights and enemy interactions

  • Final polishing and debugging of gameplay mechanics, UI, and transitions.


The Intro & Outro Story : 

Intro Story – Sands of the Stolen Heart

Sahira awakens amidst a vast, golden desert under a blazing sun, only to realize that this is not the Egypt she once ruled. The familiar temples and palaces are gone, replaced by twisted ruins and corrupted sands. As she explores, she senses the presence of a powerful being watching her every move.

From the shadows emerges Anubis, Guardian of the Underworld, who confronts Sahira for trespassing into a realm that no longer belongs to mortals. His voice booms across the wasteland as he reprimands her for daring to step foot into this forsaken land.

But Sahira, Queen of Egypt and rightful ruler of the sands, refuses to yield. With defiance burning in her heart, she challenges Anubis, declaring that she will take back the desert with the help of her loyal minions.

Thus begins her journey to reclaim the stolen heart of Egypt, gathering souls, summoning followers, and building her army for the ultimate battle against the god of death himself.


Outro Story – 

As the dust settles, she smirks and remarks with biting sarcasm, “What a weakling.”

With a wave of her hand, Sahira binds Anubis’s defeated soul into the form of the Gayer-Anderson cat, a mystical relic said to hold the essence of power and control. The once-mighty deity is reduced to a silent, powerless figure—now the very key to opening the portal that will grant Sahira access to conquer even greater parts of the desert realm.


Technical Progress – Setting Up Scene Flow in Unity :


Scene Setup in Build Settings -

  • I added the Intro Scene, Main Level Scene, and UI/Menu Scene to Unity’s Build Settings so they can be loaded at runtime.

  • Each scene contains its own hierarchy setup: background sprites, UI canvases, and necessary components like EventSystem for button interactions.

Button OnClick Configuration -

  • On the Start button (UI Button component), I configured an OnClick() event to call a custom function using SceneManager.LoadScene().


Intro-to-Level Transition -

  • Inside the IntroScene, I used a Timeline/Animator event or a script with Invoke() to automatically transition to the Main Level Scene after the intro finishes:


Testing & Validation

  • I ran the game to confirm that clicking Start successfully loads the IntroScene, which then transitions to the MainLevel scene.

  • Adjusted Canvas scaling, text, and sprite positions to ensure UI elements render properly across scenes

This setup ensures that gameplay now follows the correct flow: Menu → Intro Story → Main Level.

Fig 1.1 Setting Up Scenes In Unity



Enemy Controller Script : 

I redid the entire Enemy Controller script to make it more modular and reusable, allowing us to add multiple enemy types easily by adjusting serialized parameters in the Inspector. This redesign ensures that new enemies can share the same core logic for movement, chasing, attacking, and taking damage while still having unique stats and behaviors.

Technical Breakdown – Enemy Control Script

1. Script Structure & Variables
  • Defined serialized fields for enemy stats (health, moveSpeed, attackRange, damageAmount) and references (NavMeshAgent, Animator, Transform targets).

  • Used state booleans such as isKnockbacked, isDead, isAttacking, and isChasing to control behavior flow.

2. Initialization (Start() method)
  • Cached component references (GetComponent<NavMeshAgent>(), GetComponent<Animator>()).

  • Set initial enemy state (idle/patrol) and assigned starting waypoints if applicable.

3. Enemy State Handling (Update() method)
  • Implemented distance-based decision logic:

    • If player within detectionRange → switch to chase state.

    • If player within attackRange → trigger attack animation and damage logic.

    • Else → perform patrol behavior.

4. Movement & Navigation
  • Used NavMeshAgent.SetDestination() for dynamic movement toward player or patrol points.

  • Incorporated rotation alignment towards currentTarget for more natural movement.

5. Combat & Damage Processing
  • TakeDamage(float amount):

    • Reduces health, triggers hit animation.

    • If health ≤ 0 → calls Die().

  • Die():

    • Disables NavMeshAgent, triggers death animation, and optionally destroys enemy GameObject after animation completes.

6. Knockback & Recovery
  • Implemented knockback response using AddForce on Rigidbody or positional adjustment.

  • Invoke(nameof(RecoverFromKnockback), duration);

    to reset isKnockbacked after delay.

7. Gizmo Debugging (OnDrawGizmosSelected())
  • Visualized attack range (red), ground check sphere (green), and patrol distance lines (cyan) for easier debugging in the editor.

8. Extensibility for New Enemies
  • Exposed key parameters as [SerializeField], allowing each new enemy prefab to have unique stats without modifying the script.

  • Designed logic in modular methods (Patrol(), Chase(), Attack(), TakeDamage(), Die()) for easy reuse and override if needed.

Fig 1.2 Full Enemy Controller Script


Enemy Flash Script :

This script handles visual feedback when an enemy takes damage, making the enemy sprite flash a specific color (red by default) for a short duration. This enhances the player’s perception of hit confirmation.

I created the Enemy Flash Script to give visual feedback when enemies take damage, making combat feel more responsive. The script requires a SpriteRenderer and stores the enemy’s original color. When the FlashRed() method is called, it starts a coroutine that temporarily changes the sprite color to red for a short duration (flashDuration) before reverting to the original color. This setup ensures that any enemy with the script attached will automatically display a hit flash when damaged, without extra manual configuration.

The script is modular, meaning it can be reused across multiple enemy prefabs. By exposing parameters like flashColor and flashDuration in the Inspector, different enemies can have unique flash behaviors without changing the code. The design makes it simple to connect with the existing enemy damage logic by calling GetComponent<EnemyFlash>()?.FlashRed() inside the TakeDamage() method.

It also includes collision handling for enemy projectiles, detecting when they hit minions (shields, followers, turrets), the ground, or walls. When a hit is detected, the script applies damage to the respective target, spawns a hit effect using Instantiate(), and destroys the projectile. Combining the flash effect with hit detection and visual impact effects makes combat more satisfying and improves gameplay feedback for the player.

Fig 1.3 Enemy Flash Script

Enemy States : 

I set up the Enemy States using Unity’s Animator to control enemy animations and behavior transitions. Each enemy has multiple states such as Idle, Walk, Attack, and Death, with parameters to determine when to transition between them. These states are connected using transition conditions, for example switching from Idle to Walk when the enemy starts moving or from Attack to Idle after finishing an attack animation.

The Animator is linked to the Enemy Controller Script, which updates the parameters (e.g., isWalking, isAttacking, isDead) based on the enemy’s current logic. This ensures that animations sync correctly with enemy behaviors such as patrolling, chasing, attacking, and dying. Each state has its own animation clip that plays automatically when the enemy enters that state.

By structuring the states this way, I created a modular and scalable animation system. Adding new animations or enemy behaviors only requires adding new states and transitions without rewriting the main logic. This makes it easy to expand for additional enemy types while keeping animations consistent and synchronized with their AI states.

Fig 1.4 Enemy States

Spawning Enemies : 

I organized all enemy prefabs into categories such as Fox, Mummy, SandPirate, Scorpio, Skeleton Monster, and Undead Cat, each containing their respective idle, attack, and projectile objects. This structure made it easier to manage enemy animations, behaviors, and unique attack components within the Unity project.

Using these prefabs, I began spawning enemies around the map by placing instances of each prefab in different locations. This allowed me to test combat variety and ensure that different enemy types functioned correctly with their respective attack and movement behaviors. Because the Enemy Controller Script was modular, all these enemies could share the same AI logic while still having their own unique stats and animations.

This setup ensures a diverse enemy ecosystem, where each enemy type contributes to different gameplay challenges. By simply adjusting prefab properties like health, damage, and speed, I could balance difficulty and make encounters more engaging without modifying the core script.

Fig 1.5 Arranging enemy prefabs

Fixing Craft Process UI : 

I updated the crafting UI based on feedback from Dr. Mia, who pointed out that the initial layout was obstructing important gameplay elements. The new layout repositions the crafting panel and key icons to ensure they do not block the player’s view of the game area.

The turret crafting panel now clearly displays the available turrets, their required components, and the crafting button in a cleaner, less intrusive format. By refining the positioning and spacing of UI elements, the interface is now more user-friendly and improves overall visibility during gameplay, allowing players to craft turrets without interrupting their combat experience.

Fig 1.6 Updated Craft UI


Enabling the handbook button : 

I created an interactive handbook UI that allows players to click on Sahira’s character entry to view her tutorial keys and basic controls. The handbook displays information in a clean, book-like layout, making it easy for players to reference Sahira’s abilities during gameplay.

I also implemented an ESC key function so players can quickly close the handbook and return to the game. This setup uses Unity’s UI event system, where the panel visibility is toggled via scripts that respond to both button clicks and keyboard input. The design ensures the handbook is both informative and non-intrusive, giving players quick access to essential controls without disrupting gameplay flow.

Fig 1.7 Handbook Button

Publishing The Game : 

With the game completed, we uploaded the game to itch.io where users can download our game and play online.






Final Submission : 

Play our game "Sands Of The Stolen Hearts" HERE

Access to our Google Drive which has Unity file and exe file HERE



Game Play Presentation : 



2. Feedback

Week 14 : 
Dr. Mia praised the game’s unique gameplay, particularly highlighting the crafting system, which she acknowledged as technically challenging but successfully implemented, as well as the boss mechanics, which added depth to the experience. However, she suggested improving the crafting system’s UI layout, noting that its current placement blocks some of the text, making it difficult to read. 

3. Reflection

Experience : 
This module was one of the most challenging yet rewarding experiences I have gone through. At the start, our team had an ambitious vision of creating a full crafting system on top of standard game mechanics, knowing that it would be technically demanding to implement. Despite the complexity, we were determined to push ourselves, and many nights were spent coding, testing, and debugging to bring our ideas to life. The process of starting from a blank project and slowly building up all the systems, assets, and interactions taught me a great deal about perseverance and teamwork.

Observations : 
Throughout the development process, I realized how much effort goes into crafting a game from scratch. Every feature, from the crafting system to the boss mechanics, required careful planning, testing, and refinement to ensure everything worked smoothly. It was also clear how crucial communication and collaboration were—our team constantly shared ideas, divided tasks, and supported one another when challenges arose. The feedback we received along the way, such as suggestions to refine our UI, helped us see our game from a player’s perspective and improve its usability.

Findings : 
Completing this project opened my eyes to the full journey of game development, from concept to a playable final product. Despite the technical hurdles and countless late nights, seeing the game finally come together was incredibly satisfying. This experience reinforced how much can be achieved when a team shares the same passion and drive to succeed. I am deeply thankful to my teammates for their hard work and dedication, and this project will always remind me of how far perseverance and teamwork can take us.

Comments

Popular posts from this blog

Application Design 2 - Task 1 : App Design 1 Self Evaluation & Reflection

Application Design 2 - Task 2 : Interaction Design Proposal & Planning

Information Design - Exercise 1 : Quantifiable Information