Kick Ball Action

devices kicker ball actions

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_ballkick_ball
Use caseTrough/launcher: a new ball enters playGate/kicker: an already-held ball fires out
Ball creationCreates a new ballFires the existing ball; creates nothing
Ball-in-play countIncremented automaticallyUnchanged — increment it yourself if needed
Physics parametersOn the action block (angle, strength)On the device settings { kick_angle, kick_strength }
Empty deviceCreates a ball regardlessNo-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.