Role: Gameplay Programmer
Engine: Unreal Engine 5
Team Size: 10
Time Frame: 4 Weeks
Bonkers is a physics-based multiplayer game in which players battle against each other by attempting to knock their opponents off the map. Players can earn coins through fighting and use them to purchase upgrades. The goal is to be the last player standing.
The game was developed during a 4-week project at FutureGames, during which time we prototyped various physics mechanics and came up with three different gameplay ideas. We ultimately chose to create a 3D party fighter game, drawing inspiration from the damage system in Super Smash Bros. In Bonkers, everything from movement, attacks, and level elements is based on physics, resulting in chaotic and exciting gameplay with various upgrades and stat boosts that significantly impact the outcome of the game.
This game is not yet uploaded to Itch.io Once it is I will add a link to it.
For this project, I was responsible for creating a physics-based character movement system. During the prototyping phase, I explored different methods including physical animation and active ragdoll movement. Ultimately, we decided on a force-based movement system with a sphere trace to maintain a consistent character ride height. As this was my first time working on player movement in a group project, I made sure to devote a significant amount of time to refining the system to ensure it was smooth and enjoyable to use. The prototyping phase played a significant role in this project, and I would like to share the entire process leading up to the final results. If you want to skip to the final results, you can click the link below.
As mentioned earlier, during the prototyping phase we had not yet determined a specific movement system. However, we wanted the game to have a humorous feel to it. I began by experimenting with physical animations, which have a ragdoll-like feel but still allow for the use of all animations. To use physical animations, you open the physics asset of the skeletal mesh and create a new physical animation profile, assigning all the bones to that profile. By enabling the profile on BeginPlay(), the skeletal mesh can interact with the environment and other physical objects.
By adjusting the six different strength variables for each bone in the profile, you can achieve a more customized appearance for the player. For example, making the lower bones of the mesh strong but the upper half weak gives a more cartoonish feel.
The issue with physical animations was that they work well with complex skeletal meshes with many bones, but the low poly player models we intended to use only have four bones.
Active ragdoll movement
I then attempted active ragdoll movement. There was some interest in movement similar to Gang Beasts or Human: Fall Flat within the group, so I explored this option. I found a helpful video that discusses the theory behind different types of active ragdoll movement and provided me with ideas on how to create my own.
I began by creating a new pawn with a camera, a sphere as the body/head, and two spheres as legs. I added physics constraints between each leg and the body, adjusting the number of degrees and distance each leg could move and rotate. I applied an upward force to the body and a downward force to the legs. By adjusting these forces and physical constraints, I was able to make the ragdoll stumble around as it moves, attempting to balance itself and falling over when colliding with something. I added WSAD movement based on force, as well as a jump and sprint. I was happy with the simple prototype and enjoyed experimenting with it.
I made some modifications to the active ragdoll, and once I had a better understanding of how to create a more complex one, I created a new pawn with more body parts and joints. This version was closer to what we were interested in, but as we later decided on the type of game we wanted to create, the slow and clumsy movement did not fit with our desired quick and snappy feel.
We ultimately went with a more responsive and adjustable movement system in the game, as opposed to the randomness of the previous prototypes. The character is now a floating capsule that uses a sphere trace to maintain a specific distance above the ground. When the sphere trace detects the ground and the capsule's distance to the ground, force is applied to keep the player grounded while still hovering the desired distance above the ground. This resolves issues with step-ups/downs, ground clearance, uneven surfaces (slopes), and removes friction with the ground.
The character's movement is achieved by applying force in the desired direction. One challenge of using force for movement is that it is additive, leading to the potential for increasing acceleration indefinitely. To address this, I introduced a MaxAccelerationForce variable and included it in the ApplyPlayerMovement() function. This function compares the player's current velocity to the MaxAccelerationForce and limits the applied force to maintain the desired maximum velocity. When the player is in the air, a reduced amount of force is applied compared to when they are on the ground.
The movement variables and forces are highly adjustable and scalable to achieve the most desirable movement feel. I am satisfied with the final result and proud that I managed to implement this type of movement.
What I learned
Through this project, I gained a deeper understanding of movement and physics. I also discovered the value of rapid prototyping in the development process. Creating rough prototypes helped me visualize and test various mechanics and ideas for the game, leading to a more enjoyable gameplay experience. I also learned new techniques such as active ragdolls and physics animation. This was my first time developing a multiplayer game, so ensuring that characters could interact and attack each other as intended was a valuable learning experience. Overall, this project allowed me to acquire new knowledge and generate new ideas for future projects.