Dev Log
Making Mini-Golf More Fun: Taking Advantage of the Digital Medium
While prototyping the character controller for our upcoming action-adventure game where you play as a golf ball, the first thing I went to was the built-in Unity physics components. With a simple rigidbody and a quick script to set the velocity when you hit the ball, the prototype was working, but with some problems... This led to the difficult but eventually beneficial task of building a custom physics engine with the goal of being more fun and consistent than regular mini golf.
The Problems with A Simulation-Based Approach
A pure physics simulation is great when you need to make things act as they would in real life on their own. However, the more control you try to take of the simulation, the messier it gets. One of the biggest problems was working around the rolling of the ball. If we allowed the ball to roll in the simulation, it brought with it some of the worst parts of real-world mini golf. These included the ball jumping when hitting a wall, picking up unwanted spin, and changing velocity inconsistently when on non-flat surfaces. To try to fix these problems, I tried to prevent the ball from rolling in the simulation, instead just using velocity and friction to control the ball’s movement. This solution felt much better to play with on flat ground, however, this resulted in different problems arising. These included the ball acting inconsistently and unrealistically on slopes, where it would just bounce off even mildly abrupt changes in angle, along with being difficult on slopes in general, lacking the ability to slide down a slope like the rolling ball would. After trying all different kinds of combinations of the rotation limiting, ball mass, ball friction, and more variables, I concluded that our desired controller feel would not be possible with a pure physics simulation. These prototypes proved that we could make mini-golf more fun than real life by building a custom system that mitigates the biggest pain points, even if it is technically unrealistic.
Ramp Comparison
Rolling Enabled
Rolling Disabled
Custom Physics Engine
Flat Ground Comparison
Rolling Enabled
Rolling Disabled
Custom Physics Engine
How a Custom Controller Could Fix the Problems
I concluded that, on top of basic ball physics, this new controller needed:
· Accurate slope transitions, even on abrupt angle changes – not all our slopes will be smooth curves
· A great feeling deceleration curve
· Consistent bouncing off walls
The focus of my custom controller would be “consistency,” making sure that when a player wanted to do something, the game responds accurately and consistently to their input. The physics simulation versions of the controller often resulted in my shots going way off course, making me as a player mad at the game. The word “consistency” guided most of my technical design decisions, making it so that if I hit a wall at a 45-degree angle, then I’ll come off it the other way at a 45-degree angle, or that if I hit a ramp, I will travel up it at the same velocity I entered it at. The value of “consistency” was especially important to our game as players will be expected to make many shots in quick succession, with a focus on quick decision making. If inconsistency is thrown into the mix, players’ quick decisions will be harder to make and frustration will quickly ensue.
How I Made the Custom Controller
The driving variable behind my custom controller is a “velocity” variable, similar to any physics simulation. However, I have complete control over this velocity, and it’s reaction to interactions with the world are now up to me.
The first step that I worked on for the controller, is getting the shooting, friction, and deceleration feeling great. The shooting part is easy, as whenever the player shoots in a direction, the ball’s velocity is set to the strength of the shot in the direction that they shot it. Then, the ball must slow down, as if it has friction acting upon it. This will be a theme throughout this process, making my own forces that act close enough to real physics, but more fun. This friction is applied almost exponentially, where it reduces the velocity more when it’s at its fastest and reduces it less when its slower. This results in a short burst of max speed, and then more time spent at the end of the shot, where it is just gently rolling, ready to be shot again. This decision was driven by the addition of “bullet time” to the game, which slows the game down while players are aiming their shots. This makes shooting while moving possible, and even encouraged, especially when the ball is moving slowly. However, this friction should only be applied when the ball is on the ground, and maybe the player shouldn’t be able to hit their ball while in the air (let’s help out the level designers), so the next step was to add a “grounded” check. With a collision check just below the ball, I can now know all sorts of information about the ground, including whether the player is touching it, or what angle the ground is.
Now the ball was moving, but it was able to fly right through walls. The next step was to make the ball bounce, so when the ball would hit a wall (which is classified as anything steep in relation to the ball’s current velocity), I just reflect the ball’s velocity off the wall. To make this feel a bit more realistic and less pinball-y, I added a custom slow-down factor, which scales based on the approach angle to the wall – if the wall is hit head on, it slows down a lot, but if it just glances off it at a shallow angle, the resultant speed is barely affected. Again, an example of getting the physics close enough to real life to feel right but designing it with the intention of being more fun and consistent.
The controller felt great at this point, bouncing off walls at the expected angle every time and overall feeling amazing to control, however, angled surfaces weren’t considered yet. This was one of the first moments where I realized the scale of the task I had taken on, and all of the potential edge cases that are usually handled by a full physics simulation. Soon, with a solution that is close enough to real physics, I had the ball transitioning to ramps and rolling down them beautifully. This was accomplished by projecting the balls velocity along the surface its currently over, ensuring that when the ball transitions to a ramp, it keeps its same velocity and keeps travelling in the expected direction. Then, due to a scaled gravity effect based on the ground’s angle, the ball will begin to lose speed and eventually start rolling down the ramp, back onto level ground, where friction will take over and eventually bring the ball to a stop.
These main basic elements of the controller make up 95% of player interactions with the world, where the ball now acts consistently.
Basic Velocity
Wall Bouncing
Process work for ramped surface caluclations
Final result on ramped surface
Next Steps
As mentioned above, a custom solution like this brings with it many potential edge cases that haven’t been designed for. These edge cases will continue to pop up, where I will come up with a design solution, and will then implement the new feature into the character controller. Some of the edge cases I’ve already solved for are inversely ramped surfaces (don’t ask) and holes in the ground. Some that we’ve discovered but haven’t solved yet include steep ramped surfaces and inconsistent bounce directions on moving objects, which are next up on the to do list.