
Kardtana
Gameplay GIFs
Overview
Kardtana is a project I have worked on over summer with my University colleagues. I worked with the team from pre-production until the demo release, and during this time I acted as a general developer. I mainly helped with the designing of mechanics and implementation of systems. However, due to the small team size, I also had to add systems such as sound effects, particles, and more.
For organisation and planning, we used Miro, Click-up, as well as discord for communication. Furthermore, we used Github Desktop as our Source Control for this Unreal Engine 5 project. This project has given me great experience in collaborative design, scope and milestone planning, and iterative development.
Role: General Developer
Genre: Strategy, Action-Combat
Engine: Unreal Engine 5
Team Size: 4
Duration: 4 Months
Platform: PC (Itch.io)
Year: 2024
The projects development time lasted 4 months, here are some of my key contributions:
-
Movement Controller - Developed the majority of the player controller ensuring quick and responsive movement.
-
Game Feel - Implemented a custom camera wobble, particles, and more.
-
Card Combination System - In Kardtana, you slice cards to add them to your 5 slot deck. This system checks for poker hand combinations, if any are detected, a cash out multiplier is applied.
Movement Controller
Kardtana is designed to be a fast-paced and fluid game. So for our movement design we were heavily inspired by Ghostrunner. The movement in Ghostrunner gives a lot of control to the player by being highly responsive, smooth, and fun to use, these were the goals for our movement system too.
Fig. 1
Fig. 1, is a video showcasing the standard movement. There is no sprint, just one constant speed. As a team we decided that we wanted the player to always be on the move. If they are moving slow, they will not reach the quota in time.
​
The game puts pressure on the player to be fast, so having a slow move and a sprint speed would mean 99% of the time the player would be sprinting anyways. We decided to remove this option to make the game less complex.
​
Furthermore, I made the movement responsive by adding faster than normal acceleration/deceleration, but still keeping it feeling somewhat natural.
Fig. 2, shows the next mechanic that I implemented which was the jump. The jump was again designed to be responsive, instantly launch the player into the air. The high gravity leaves the jump feeling natural, without the usual 'float'.
Fig. 2
​Dash:
The dash is a common mechanic seen in most movement-focused games, and here is no exception. Again we used Ghostrunner as reference for this:
Fig. 3, shows how the dash works within Ghostrunner. It is short, snappy, and always goes the same distance. However, when developing this I initially did not pay attention to that final factor. I found my first implementation being inconsistent.
Fig. 3
The main issue that I encountered with the dash was getting it to be consistent from the ground to the air. The ground friction was making the dash go less distance when the player dashes on flat ground. Whereas, if the player jumped, and then dashed - they would go flying!....
​
I tried to fix this in a couple of ways:​
​
1. Adjust the ground friction:
​
​
​​
​
2. Apply less force in the air:
​​


Setting the movement mode to flying ignored gravity and ground friction, however, this still did not end up being consistent and felt unnatural.
Adding a multiplier based on whether the player is in the air or ground. Again this didn't work as the player might start on ground, but may end in the air if they dash off of an edge.
I then took a step back to realise that I was 'defensively' programming whatever issues came my way. I then re-looked at the Ghostrunner reference I had collected, and noticed that the dash was always consistent no matter what.
​
This made me reevaluate my blueprint, and I realised that I was doing the dash via additive velocity. This was leading to inconsistency with friction, input, drag, etc. The fix to this was to do a direct set of the velocity within a Timeline. This lead to a much more controlled and consistent dash, which I had intended for in the first place.
One bonus note is that the dash can slice through enemies. See this... AWESOME!
​Crouch:
Crouching is a common mechanic in general, however Ghostrunner did something different with it which I loved, a crouch-slide!
​
If stationary, crouching will do a normal crouch leading to a lower walk speed, however crouching while moving will do a crouch slide that slows down with the friction over time. To take this even further (arguably the best part), if the player crouches while moving down a slope, all of the player's momentum will be conserved sending the player rapidly down the slope.​​​​​​
Fig. 4
Fig. 5
Fig. 4 and Fig.5, show the comparison of the crouch slide mechanic. I think I made it pretty accurate, however, there were some unseen complications along the way.
​
1. Detecting when the player is going down a slope:​



As you can see from the trio of blueprint screenshots above, there are a lot of edge cases to check that I didn't initially account for. The player could be facing down the slope but moving backwards!
​
​
2. Allowing the player to hold crouch before landing, so that they can go straight into a crouch slide from falling.
​
This was as simple as adding a boolean for "IsPlayerCrouchedInAir?", then upon landing if this is true then call the crouch event I made. This again was an issue I didn't initially account for, and I'm starting to see the point about "How do you design a door?". Everything situation needs to be considered in the design of the mechanic.
​
We did add mechanics such as wall-running and surfing, however there weren't too many issues encountered when implementing those.
Game Feel
Another core feature of the game other than the movement was the card slicing mechanic. This mechanic had to feel great as it is essentially the games combat.
​
I watched several videos on game feel, and deepened my knowledge on topics such as sound effects, particles, and camera shake. I implemented all of these 'juice' features, but my colleague said to me 'the slice camera shake is not it'.
​
I was quite taken aback by this because I thought it felt good, however he showed me the way the camera shakes/wobbles within the game when the character slices with the Katana. Fig. 6 is the reference I was shown:​
As you can see in Fig. 6, the camera lerps to the wind up location, and then to the swings end location. This creates a real feeling of momentum and impact in each swing.
Fig. 6
Below, Fig. 7, and 8, showcase the comparison of Ghostrunner to our games camera wobble during the swings. I feel that I have replicated this system quite well and the combat now feels 10x more satisfying.
Fig. 7
Fig. 8
Fig. 9. Shows the combat in action, you may also notice small additions like particles, a hit flash, and sound effects that also enhance the games feel.
Fig. 9
There are even more additions I have added for this section but this page would become to long, to summarise:
-
Input Buffering: The attacks were feeling disjointed and unresponsive so I added an input buffer system for the player to easily chain attacks
-
Camera FOV changes: Added to dash for the illusion of an increase in speed.
-
Card Slicing (added by one of my colleagues)
Card Combination System
The card combination system/poker hand detection system is by far the most complex system I have had to develop for Kardtana.
​
To summarise:
- The player can have 5 cards in their deck
- There are poker hand combinations, if the player's cards achieve a combination they will gain a cash-out multiplier
- The player's deck will "cash-out" adding its value to the player's current money ​​

Fig. 10, shows a list of poker combinations.
​
As you can imagine, this detection system will be quite complicated.
Fig. 10.
Since the start, the design has changed drastically. Fig. 11, shows the original system:​
So as a card gets added to the deck, a timer starts. Once this timer runs out, the player's deck is "cashed-out". If a card is sliced within this time that has a valid possible combination, it will be added to the deck and the timer will reset. This encourages players to again move quickly and be strategic with what cards they slice.
Fig. 11
We then made the design decision to account for what cards are currently in the level. If there are not the required enemies in the level for a specific combination then it will not be counted as possible, and won't be recommended to the player. That's what the two combination sets are below the deck in the top right - possible combinations that we decided to recommend to the player in case they forget what combinations exist in such a fast-paced game.
​
After building out this whole system we realised that we had a few issues that we needed to account for in a re-design session:
-
​If you slice a card, and there is no possible combination available in the level, the deck would instantly cash-out. This felt really abrupt, confusing, and that the player had little control over it.
-
The player might not know what combinations are best, and all of the possible ones they can currently make, as only two are shown.
-
How do you decide what to display in the possible combinations section, should it be ease of achieving, highest cash-out multiplier, etc?
​
​
During our weekly meeting, we redesigned this entire system. The new system has these changes:
-
There is now a cheat sheet that can be accessed during game, that slows down time when open, giving the player a moment to view what combinations are in the game, and are currently possible.
-
The player can now more clearly see a list of all currently possible combinations based on what cards are currently in the level and the state of their current deck.
-
The time dilation gives less experienced players a chance to check/learn what various combinations the game has, without being punished.
-
The recommended combinations have now been removed, these may return in the future based on playtest feedback​
-
​​​
-
The player's deck will no longer cash-out if there are no possible combinations available, it will still automatically cash-out when the timer completes, but now the player can also manually cash-out at the press of a button.
-
​The manual cash-out gives the player more control and power over how they want to strategically collect these cards.
-
This system feels a lot less abrupt
-
However, this required a lot of re-programming
-
One final thing to mention how the combination system programming changed. Initially, I had all of the combinations in a data table, and each one has the variables seen in Fig. 12. This used a boolean system to allow the designer to make various combinations easily with just a few booleans. ​
​
​
​
To me this seemed simple, but to my team this made no sense, and later I discovered it wasn't possible to use this system for combinations such as a "Full House". So now I have transitioned to a system that is a data table of just combination names, and based on those I have a switch node that does it's own custom detection for each combination.
​
This means everything is under the hood, and a lot less cluttered for the designers. It has the disadvantage of not being easily expandable though - as any new combinations we add will need their own custom detection functionality.
​​​​

Fig. 12