DEV Community

Cover image for Ball physics in GOALS
Göran Syberg Falguera for GOALS Engineering

Posted on

Ball physics in GOALS

Title image credit: Midjourney

Introduction

When creating the ball for GOALS we realized fairly quickly that using Unreal’s off-the-shelf physics will not suffice for our ball. Footballs behave in peculiar ways when forces are applied and when they are deformed. We want a really configurable and realistic looking ball trajectory. But at the same time, we want to be able to leverage Unreal's built in physics for collisions and interactions with the rest of the world. The current solution uses different approaches depending on which state the ball is in and we will describe each of them in this article.

The different states of the ball

The ball will be in six distinct states and different calculations are applied in each of them. Starting with ball being possessed by one of the players:

Shot with debug info

  1. Dribbling - One of the players (or the AI) is performing dribbling animations that effect the ball.
  2. In air predicted - One of the players is about to shoot and all parameters are known.
  3. In air simulated - The ball now leaves the player and it's parameters are calculated each game update in our custom ball physics simulation.
  4. On ground simulated - As soon as the ball hits something, like the frame of the goals, the ground or another player, we let Unreal physics take over and manage the ball according to it's physical properties like weight, material, size, etc.
  5. On ground predicted - For players and AI to be able to intercept the ball, without it looking strange, we need to predict the ball path.
  6. Once ball is at rest, it is just considered a plain old static mesh with physics in Unreal.

Dribbling

This is when one of the players is possessing the ball. In this state, the ball movement is dictated by designer controlled parameters that gives the ball a physical impulse depending on the stats of the player. This way we can vary the control the player has with the impulse. As we progress to more advanced dribbling, we may have to add more sophisticated ball control mechanisms.

Image description

In air predicted

To be able to put other players in the right state, i.e. getting ready for a volley shot etc. but also to adjust aiming, we need to know where the ball will end up (if it does not get intercepted on the way).

We do this by emulating Unreal Chaos physics and create a path from where the ball is to where it would land unobstructed. This is all done in the frame (game loop update) where a player lets go of one of the shooting buttons. We now know which type of shot the players used as well as the power and the aim, we also know how much we need to adjust the shooting angle for the player to hit the intended target.

All this is now plugged into the actual shooting function.

In air simulated

Once ball is let go, at each game update we considers several forces that impact the trajectory; speed, air drag, spin force, gravity to create a natural feeling during game play. But we also make sure that the ball in this state is regular AStaticMeshActor so that we can have it collide with and bounce of things in the world without having to implement this ourselves. We have built a set of development tools for engineers and designers to see exactly how the ball behaves with different parameters set. In this image we see the spin of the ball illustrated on the ball bath as well as spin force, spin speed, drag and ball speed plotted on screen.

Illustration of debug

High quality ball simulation is accomplished by updating physics at a fixed 128 Hz rate on the server. To minimize client-divergences we use sub-stepping, a technique to decouple physics simulation rate from frame rate, so that even players with hardware that fail to render the game at 128 frames per second will update physics in roughly the same rate as the server.

On ground simulated

From our perspective, this is the simplest case as we let Unreal engine physics handle most of it for us. We will get physical properties while the ball interacts with the worlds for free and we can leverage Unreal material properties for friction etc. The thing we apply ourselves is drag force that is also applied when in air. We do this with a manually adjusted curve based on research on ball behavior.

Image description

In this short GIF we can see how the ball is sliding slightly before friction is enough for it to start rolling. Then after a while the ball comes to rest.

Rolling ball

On ground predicted

To be able to steer AI and different lock-on scenarios, we need to be able to predict where the ball is going. Otherwise the players will just keep updating where they are going and create the strange round path shown in the image below.

With and without predition

The trick in this scenario, is figuring out what Unreal physics will be doing to the ball (remember that when we are in air we are controlling physics so we can more easily predict it). Up until now, we have used a simple constant deceleration to model the behavior but as we increase the quality this is not enough anymore. We are currently testing different models and will update this section once implemented.

Configuration and shot types

The system is built to be highly configurable and extendable by the game designers and adding new shot types is just a matter of configuration and adjusting some curves. Here is an example of a curved shot. The amount of curvature does not only depend on the input of the controller but also on the stats of the current player:

Curved shot

Networking the ball

The ball is simulated on the server as well as on the client. To ensure fair play, the server is authoritative and any client divergence will be smoothly corrected.

At the time of writing, we use off-the-shelf Unreal movement component to network the kinematics of the ball. One big task for GOALS is to find a way to make this component more streamlined and optimized for GOALS use case as networking the ball takes up most of our network resources.

Top comments (0)