A Podball game is made up of two teams with a variable number of players (called pods) and the ball. Pods and ball are modeled as circular objects that glide over the playground. They are characterized by their mass, position, velocity and forces acting upon them.
The pods and ball obey to the fundamental rules of physics, i.e. inertia, conservation of momentum, friction etc. We think of the pods having a thrust engine that enables them to accelerate in any given direction in the plane. (The third dimension is not modeled).
Pods can pick up the ball. They do this automatically when they collide with the ball. A pod holding the ball has a reduced top speed (i.e. an increased friction).
The game arena is a rectangle. All dimensions are configurable, but typically the arena width is set as 1.0 in arbitrary length units. The origin of the coordinate system is in the center of the rectangle. The goals are along either sides of the arena borders, centered around the origin on the y-axis. The width of the goals is configurable.
Figure: Typical dimensions and coordinate system of a Podball arena.
The game arena is closed, i.e. neither pods nor the ball can leave it. (There's no "Off"). The borders are perfectly reflecting (i.e. incident angle = exit angle).
The Podball engine simulates discrete time steps, called ticks. There is absolutely no correlation between a tick and physical time in seconds or minutes. It's up to the client (of the Podball engine) to clock the engine at the desired rate. The tick being the time unit of the engine means that all velocities are expressed in length units per tick.
NOTE: For performance reasons, pod control modules are only called every ENGINE_CTRL_STEP ticks. This has to be taken into when extrapolating pod actions into the future.
The pods are considered of perfectly circular shape.
Movement
There is no special heading direction. Pods can accelerate in any direction at any time. However, since there is inertia, the movement (i.e. the velocity vector) does not follow the acceleration immediately. Instead the pods drift around. There's also friction, which is proportional to velocity, and which rapidly decelerates them down when they don not accelerate. The friction also limits the velocity of the pods to a maximum value.
Picking up and shooting the ball
Pods automatically pick up the ball (from any direction), as soon as the ball collides with the pod. However this works only if the relative velocity between ball and pod is below a certain threshold (BALL_PICKUP_VELOCITY). Otherwise the ball bounces back from the pod.
When a pod has picked up the ball, it owns it, that is the ball is sticky to the pod and moves along with it. Pods carrying the ball have increased mass (sum of pod and ball mass) and higher friction coefficient. Thus they have less acceleration and lower top speed. A pod keeps the ball until...
The pods may shoot the ball in any direction, independently of the direction in which they're currently heading. The power of the shoot is variable from zero to a maximum value (SHOOT_FORCE), defined by the engine. When shooting, the pod notices a recoil, which depends on the shoot force and the mass ratio between ball and pod.
Pods automatically loose the ball if the total force acting upon them exceeds a certain limit (COLLISION_FORCE_LIMIT). Forces include own thrust, and forces experienced during collisions.
Once a pod has picked up the ball, it may keep the ball only for a limited amount of time (BALLKEEP). When this time runs up, the ball is automatically released again.
Whenever a pod has lost the ball (for whatever reason), it cannot pick it up again during a limited amount of time (BALLDENY). During this time, the pod is transparent for the ball, i.e. the ball goes straight through it.
The ball's size, mass and friction coefficient are usually lower than that of the pods. Apart from that, the ball obeys the same rules of physics (with respect to inertia, friction, collisions).
At any given time, the ball is in one of the following states:
The Ball moves freely. It can be picked up by a pod.
The ball is being carried by a pod.
When the ball is shot, its initial velocity will be that of the carrying pod plus ball.f / ball.mass, where f is the actual force with which the ball is shoot (0..SHOOT_FORCE).
ball.v(0) = pod.v + SHOOT_FORCE * a / ball.mass
Where pod.v is the velocity of the shooting pod and a the shoot vector returned by the control module.
While in free motion, the ball is only subject to friction.
Its motion equation is
d(ball.v)/dt = - ball.v * BALL_FRICTION / ball.m
Hence
ball.v(t) = ball.v(0) * exp(-lambda * t)
With lambda := BALL_FRICTION / ball.m
The distance traveled by the ball as a function of time after shooting is
s(t) = Integral( ball.v(t) dt ) = ball.v(0) / lambda * (1 - exp(-lambda *t))
Especially, for t->infinity, we get the maximum distance the ball will travel as
s_max = ball.v(0) / lambda = SHOOT_FORCE / BALL_FRICTION * a
(neglecting initial pod velocity)
Lets see how much time it takes for the ball to decelerate to half of its initial velocity.
We search t2 so that
ball.v(t2) = 1/2 * ball.v(0)
This yields
t2 = -1/lambda * log(1/2)
The distance the ball has traveled in this time is
s(t2) = 1/2 * 1/lambda * ball.v(0) = 1/2 * SHOOT_FORCE / BALL_FRICTION * a
Physical units used by the Podball engine:
The Podball game engine is in one of the following modes at any given time:
Normal game mode. Time counting is enabled. In all other modes, time counting is suspended:
These are the modes active before a game is kicked-off for team 0 or team 1, respectively. Pods and ball are already on the field and the ball can already be picked up. But the game is in a save mode: No goals can be scored and both teams are confined to their respective halves of the field. More precisely, team 0 is confined to x coordinates lower than -CENTER_KEEPOFF and team 1 is confined to x coordinates greater than CENTER_KEEPOFF. The center keep-off line is reflecting for both the pods and the ball during this phase.
The meaning for this mode is for the teams to move to appropriate startup positions before the game is kicked-off.
These are the modes after team 0 or team 1 have scored a goal, respectively. The game is in suspended state, i.e. time counting is disabled.
This is a general suspended mode, where time counting and goal scoring are disabled, to be used as appropriate for the engine clients.
The width of the goals is configurable. The goal line is reflective for the pods, i.e. pods cannot cross the goal line.
Goals can only be scored in the MODE_RUNNING game state. In all other states the goal line is reflective for the ball as well.
A goal is scored when the center of the ball has crossed the goal line. Game mode switches accordingly to MODE_GOAL_TEAM_0 or MODE_GOAL_TEAM_1, depending on the side where the ball has entered the goal.
Note that it is irrelevant which pod has carried the ball before, meaning that it is possible for pods to score against their own team.
As of version 2.5 (2018-03), a new feature has been introduced, called the goal exclusion area.
This is an area in form of a semicircle around the center of each goal.
Its radius can be defined by the game settings ARENA_GOAL_EXCLUSION_RADIUS.
If ARENA_GOAL_EXCLUSION_RADIUS is not defined or set to zero, no exclusion area will be used and the same behavior as prioir to version 2.5 is applied.
The rule is this: Only one single pod of the defending team is allowed to enter that region. All other pods (both teams) are not allowed to enter and the circle is reflective for these pods.
As there is no particular role for pods, the first pod of the defending team entering the area gets access. This doesn't necessarily need to be the same pod every time and throughout the game. Whenever the area is free of pods, it is again the first pod (of the defending team) entering the area that is allowed to enter.
Caveat: As the attacking team is not allowed to enter the exclsuion zone, it is technically possible for a defending team to keep the ball in the exclusion zone and thus block the game. This should be regarded as unsportsmanlike conduct and can easily be detected automatically by the metrics discussed below.
Usually, a game is divided into periods (usually two, as in soccer). The number of periods, as well as the total playing time and the times before kick-off and after goals are configurable via the match.info configuration files.
Besides the obvious final score, additional metrics have been introduced to the game as of version 2.5 (2018-03) that can be used to assess performance of the teams and automatically detect unsportsmanlike conduct. They are discussed hereafter:
The ball is said to be possessed by a team as soon as that team gets the ball and until the opposing team gets the ball again. That is, even during the time the ball is rolling free, possession still counts for the team that had the ball prior to shooting it.
Ball possession is expressed as percentage of time the team possesses the ball compared to total match time.
The phase when the ball is free after kick-off is not counted for either team. This means that ball possession times for both teams dont necessarily add up to 100%.
As of version 2.6, the time the ball spends in the goal exclusion zones is NOT taken into account.
We measure the area of the rectangle spanned by all pods of a team. That is, we look for the pods with lowest and highest x- and y-coordinates. The area thus measured is expressed as a percentage of the entire game arena area and averaged over the time of the match.
The time the pods spent in the upfield (the half of the playing field of the opposing team) compared to the time the pods spent in the downfield (their own half of the playing field). An attack ratio of zero is a good way to indentify camping teams. Those should be disqualified.
Coming soon:
Number of times an attacking pod shot the ball in the direction of the opposing team's goal, with an angle and velocity such that it could have passed the goal line.