Witch & Knight.

Year- Started working in 2025
Length- Undetermined
Engine- Unity
Language- C#
Workflow- Solo, Waterfall
Team Size- Solo
Role- Everything (for now)

Introduction

The project that I work on whenever I have free time. The game is a 2D Soulslike, inspired by blasphemous. You control Lyra and Asmorian, a witch and a knight, and are meant to go through levels and defeat bosses. All assets are placeholders. This will be updated whenever I add a new feature that is worth mentioning or unique. I plan on trying to create a full level by the end of the summer vacation.


Table of content

Strategy pattern for the player State Machine for the enemy Character Swapping. Player movement via the new Input system Features not included in the page. Planned features

Strategy Pattern

I wanted my character to be able to switch weapons (or more accurately, projectiles). After researching patterns, I decided to use the strategy pattern.

I created an interface, IFightStrategy, with the function ExecuteAttack() and implemented it in both the Fireball and Iceball strategies.

In this Context, I added a function called SetAttackStrategy, which sets the current strategy. I also included a function AttackDone, which starts the coroutine ExecuteAttack() attached to the current strategy.

Next, I implemented the WeaponManager. Pressing the 1 or 2 keys allows you to switch the active strategy accordingly. If you press the left mouse button, it triggers the AttackDone() function in the context, which shoots the projectile, as shown in the gif. The reason I do not use a foreach loop to go through a list is because I want to have each number to represent different magic types.



State Machines

I wanted to learn about State Machines, so I did some research and decided to use them to manage my enemy AI in an efficient and reusable way. I started by creating an abstract State class that other classes would inherit from. This class contains four key functions: Enter(), Exit(), Act(), and Reason().

The StateMachine manages these states by adding them into a dictionary using AddState(). The SetState() function handles state transitions by calling Enter() and Exit() functions to ensure smooth transitions between states. The Guard script sets the default state on the start and helps the StateMachine script.

A good analogy for the StateMachine is thinking of it as a playlist manager. The StateMachine adds "songs" (states) to the playlist and ensures they switch in the correct order, while a Guard is what decides which "song" (state) should be played next.

Enter() is like entering a new state,

Exit() is like leaving that state,

Act() defines what happens in the state (for example, in the WanderState, the enemy might move randomly),

Reason() decides if a state transition is needed (for example, if the enemy sees the player, it might switch from WanderState to ChaseState).

sss

Character Swapping

A unique feature of my game is the ability to switch between two characters and execute combos using both. Players can seamlessly alternate between Lyra, a spellcaster, and Asmorian, a melee fighter, to clear levels efficiently. To achieve this functionality, I developed a CharacterSwap script. The reason I wanted to do this, was to give my game something that makes it stand out. I thought, what would be cool and not as often seen? And taking inspiration from my dnd campaing, I decided to use the two main villains, Lyra, and Asmorian. By creating two characters with unique mechanics, this also allows me to have more creativiy when I finally design some of the bosses later.

This script manages a list containing both playable characters as GameObjects. The PlayerSwapManager handles the switching logic based on player input


Movement, jumping, and dashing Via the modern input system

Ensuring smooth player movement was a key feature of the project. To achieve this, I implemented the new input system to develop a simple yet effective movement script.

The jumping script allows the player to jump only when grounded, updating the grounded state accordingly. I plan to later change it to include a double jump for the knight.

The dashing script determines the player’s movement direction before applying a set amount of force while temporarily disabling movement. It also interacts with a stamina script, utilizing the UseStamina() function to reduce stamina. If the stamina level falls below a certain threshold, dashing becomes unavailable.


Stuff not included on this page.

To not crowd this page too much with unneeded or not that noteworthy mechanics, I will instead mention them here, this will most likely get updated.

-Player health decreasing upon being hit.

-Enemy health decreasing upon being hit + Dying and despawning.


Planned features

While unable to work on this project as often as I want, it is still something I refuse to give up on. These are features that I would like to finish by the end of the upcoming summer vacation

-Strategy pattern for the knight, to include different weapons.

-A combo system to allow unique combos for each weapon for the Knight.

-A unique ability for each of the witch's magic, as well as an ultimate that would charge up by doing damage.

-More enemy variants, to include melee enemies, flying enemies, etc.

-a complete small level to show off some of the features

-A single boss fight at the end.

-Parrying mechanics for the knight.