Kick Ball Action
Kick Ball
The kick_ball action fires a ball that is already held by a kicker device — without adding a new ball to the playfield or changing the ball-in-play count. Use it for gate-to-kicker flows where a ball is captured and then launched back into play.
It is the counterpart to eject_ball, which creates a new ball for trough and launcher flows.
How to use it
Put kick_ball in an actions { } block and point it at the kicker device by name:
event_handler "gate_hit" {
event = device.Gate1.cleared
actions {
kick_ball { device = Kicker1 }
increment = "balls_in_play"
start_mode = "multiball"
}
}The action takes only device. The physics of the kick — angle and strength — live on the kicker’s device declaration, not on the action. If you need the ball-in-play count to change, set it explicitly, as the increment above does; kick_ball never touches it on its own.
Kicker physics settings
Angle and strength are physics-abstract values that each driver interprets with its own model, so they belong on the device rather than the action. Declare them in a settings { } block on the kicker:
device "switch" "kicker" "Kicker1" {
id = 41
settings {
kick_angle = 190
kick_strength = 10
}
}This mirrors the flipper settings pattern:
device "flipper" "standard" "left_flipper" {
id = 1
hardware {
coil = "C01"
switch = "S01"
}
settings {
strength = 75
hold_time = "250ms"
}
}Any driver — Visual Pinball, a physical machine, or the virtual driver — reads these values and applies its own physics.
If a kick_ball action targets a kicker that is not currently holding a ball, the kick is a no-op and a warning is logged; no ball is created.
kick_ball vs eject_ball
eject_ball | kick_ball | |
|---|---|---|
| Use case | Trough/launcher: a new ball enters play | Gate/kicker: an already-held ball fires out |
| Ball creation | Creates a new ball | Fires the existing ball; creates nothing |
| Ball-in-play count | Incremented automatically | Unchanged — increment it yourself if needed |
| Physics parameters | On the action block (angle, strength) | On the device settings { kick_angle, kick_strength } |
| Empty device | Creates a ball regardless | No-op — nothing to fire |
eject_ball carries its physics on the action because each launch can differ:
event_handler "drain_auto_serve" {
event = device.Drain.activated
actions {
eject_ball {
device = BallRelease
angle = 90
strength = 7
}
}
}The two are orthogonal: use eject_ball to add a new ball to the playfield, and kick_ball to fire a ball already held by a kicker.