Nicholas Junkas
SoulSync City
ㅤㅤㅤㅤ
Platform:
Windows PC, Mac
Engine:
Unity
Language:
C#
Duration:
August 2023 – Present
Team Size: 7
Role:
Programmer, Game Designer
Overview:
Armed with a kinetic pistol in one hand and a shape-shifting traversal gadget in the other, SoulSync City immerses you in a thrilling first-person shooter experience. As the protagonist on a solo mission, your objective is clear: locate and obliterate all generators that maintain an AI overlords control over a dystopian city. As you navigate through various sectors of the cityscape, you’ll confront various types of robot enemies and tackle a series of parkour challenges, all leading up to the ultimate showdown against MODULUS. Get ready for an adrenaline-fueled journey through a city teeming with danger and high-stakes action.
Responsibilites:
Player Movement:
- Designed and implemented all aspects of base player movement (run, jump, ledge climb, sliding, etc)
- Integrated a control scheme with both keyboard and controller support
Combat And Enemy Design:
- Designed and implemented various AI behaviors
- Designed and implemented enemy arena structure
- Helped with enemy placement and coherence around the map
Game Optimizations:
- Optimized the game map performance by adding occlusion culling
- Improved performance by employing game programming patterns
(such as object pooling)
Player Movement:
In my experience across various projects, I’ve found few things as fundamental as a player movement system. Given the nature of SoulSync City as a movement shooter, the
significance of implementing this aspect correctly was further amplified.
In this project, my primary responsibility entailed implementing and polishing the core movements of the player, including walking, running, jumping, slope climbing and mantling. Drawing from past experiences, I’ve come to understand the two key qualities that define an exceptional player movement system: responsive inputs and intuitive design to help with accessibility to all players.
During the experimentation phase, it became evident that the player movement lacked the desired level of responsiveness required for the fast-paced gameplay intended for the game. Initially, I incorporated a slight acceleration and deceleration mechanic when transitioning into the player’s sprint. However, through extensive playtesting, it became apparent that this approach resulted in a disjointed experience, frustrating players who sought immediate speed.In response, I opted to remove the acceleration mechanic entirely,allowing the player to maintain a constant sprinting state. This decision aligned more closely with the game’s emphasis on swift reaction times.
Additionally, I purposefully added a stronger gravity force to the player, as keeping it too low invoked an undesirable floaty or “moon-walking” feeling to the player.
1. Running And Jumping:
2. Slope Climbing and Sliding:
3. Mantling:
Implementing the player mantling functionality proved to be the most challenging aspect of the base movement implementation. The introduction of mantling aimed to provide players with a safety net in case of falls and facilitate smoother transitions onto elevated
surfaces. Initially, my approach, involved only a few basic raycasts and relied on basic colliders being used for the world structures. However, complications arose when the development team opted to utilize Unity’s mesh collider for building colliders. This decision posed a significant obstacle, as raycasting against mesh colliders proved to be computationally intensive, lacking the ability to access collider information internally. In the end, I was compelled to devise a workaround solution involving a combination of raycasts to overcome this limitation.
Enemy Design Process:
In addition to player movement, another significant aspect of my role involved designing and implementing various enemy types within the game. I have contributed to the creation of three distinct enemy types: the grunt, shielder, and drone.
To streamline the design process and ensure clarity in implementation, I utilized tools such as spreadsheets and enemy state flowcharts. These aids provided a structured framework for defining enemy behavior and interactions.
As for implementation of the enemies, I initially adopted state machine architecture to better organize the functionality of each action the enemy may take. However, as the complexity of enemy behaviors increased, managing the codebase became challenging, leading to both issues with readability and debugging. Recognizing the need for a more efficient approach, I transitioned to a visual behavior tree system.
The adoption of visual behavior trees not only helped to organize and optimize the enemy AI but also facilitated communication among team members. This system enabled not only programmers but also fellow enemy designers to easily identify and address any errors or unintended functionalities in the AI behavior. By leveraging visual representations of enemy behaviors, I was able to enhance collaboration and ensure cohesive enemy implementation.
1. Grunt:
2. Shielder:
3. Drone:
4. Assassin:
The assassin enemy is another fast enemy, but without any ranged attacks. Instead, it can swiftly dash toward the player or move in a pattern, aiming to attack up close with its daggers.