Skillshot adding additional light targets on second and third balls

116 views
Skip to first unread message

Bowman9

unread,
Jul 7, 2026, 12:52:56 AMJul 7
to MPF Users
Having a little issue with this skill shot tutorial
https://missionpinball.org/latest/cookbook/skillshot_with_auto_rotate/

This tutorial was originally written for 5-drop targets, but tweaked it for my 5 top rollover lanes.
My code will be below.

All testing is being done virtually in MPF.
mpf                 0.56.2
mpf-mc              0.56.1
mpf-monitor         0.56.1

On the first ball it works fine showing just one light moving left to right, on plung the light stops and flashes like it should. If the flasing shot is hit your awarded with skillshot value and it goes back into base/regular play, if not it goes into base/regular play.

The problem happens with the second and third balls.
On the second ball skill shot there now two lights moving left to right and on the third ball skill shot there are two or sometimes three lights moving left to right.

I have no clue what I screwed up. Anybody else have a clue?
If anyone knows of a skillshot or similar mode that scans back and forth requiring to hit a lit/flashing target please let me know,

Thanks,
Bowman

My yaml/code

#config_version=5

mode:
  start_events: ball_starting
  stop_events: stop_mode_skillshot
  priority: 1000

event_player:
  timer_skillshot_rotate_stopped:
    - advance_skillshot_01{device.shots.skill_rollover_01.state==1}
    - advance_skillshot_02{device.shots.skill_rollover_02.state==1}
    - advance_skillshot_03{device.shots.skill_rollover_03.state==1}
    - advance_skillshot_04{device.shots.skill_rollover_04.state==1}
    - advance_skillshot_05{device.shots.skill_rollover_05.state==1}
  skillshot_hit: stop_mode_skillshot
  playfield_active: stop_mode_skillshot|2s

shot_profiles:
  skillshot_profile:
    advance_on_hit: false
    states:
      - name: off
        show: off
      - name: on
        show: on
      - name: lit
        show: flash    
       
variable_player:
  skill_rollover_lanes_lit_hit:
    score: 10000
 
sound_player:
  skill_rollover_lanes_lit_hit:
    attract_voice: # pulling from a sound pool
      action: play
      loops: 0 # -1 will make the sound loop not need here
      volume: 0.5

show_player:
  skill_rollover_lanes_lit_hit:
    rollover-flash:
      speed: 10
      loops: 5
      priority: 1

shot_groups:
  skill_rollover_lanes:
    shots:
      - skill_rollover_01
      - skill_rollover_02
      - skill_rollover_03
      - skill_rollover_04
      - skill_rollover_05
#    disable_rotation_events: s_plunger_lane_inactive
#    rotate_left_events: s_left_flipper_active
#    rotate_right_events: s_right_flipper_active
    rotate_right_events: timer_skillshot_rotate_tick

timers:
  skillshot_rotate:
    tick_interval: 1s  # tick intervals can 0.5s, 1s, 1.5s whatever is needed for your specific mode
    start_running: true
    control_events:
      - event: s_plunger_lane_inactive
        action: stop

shots:
  skill_rollover_01:
    switch: s_rollover_01
    advance_events: mode_skillshot_started, advance_skillshot_01
    profile: skillshot_profile
    show_tokens:
      light: l_top_rollover_light_1
  skill_rollover_02:
    switch: s_rollover_02
    advance_events: advance_skillshot_02
    profile: skillshot_profile
    show_tokens:
      light: l_top_rollover_light_2
  skill_rollover_03:
    switch: s_rollover_03
    advance_events: advance_skillshot_03
    profile: skillshot_profile
    show_tokens:
      light: l_top_rollover_light_3
  skill_rollover_04:
    switch: s_rollover_04
    advance_events: advance_skillshot_04
    profile: skillshot_profile
    show_tokens:
      light: l_top_rollover_light_4
  skill_rollover_05:
    switch: s_rollover_05
    advance_events: advance_skillshot_05
    profile: skillshot_profile
    show_tokens:
      light: l_top_rollover_light_5

slide_player:
  mode_skillshot_started:
    widgets:
      - type: image
        image: blank-bg

widget_player:
  mode_skillshot_started: ### trigger
    shoot_skillshot_widget: ### widget defined on widgets yaml
      action: add
      widget_settings:
        z: -1 # this places the widget above all other slides      
  skill_rollover_lanes_lit_hit:  ### trigger
    shoot_skillshot_widget:
      action: remove
    award_skillshot_widget: ### widget defined on widgets yaml
      action: add
      widget_settings:
        z: -1 # this places the widget above all other slides
#  skill_rollover_lanes_unlit_hit:  ### trigger
#    shoot_skillshot_widget:
#      action: remove
#    missed_skillshot_widget: ### widget defined on widgets yaml
#      action: add
#      widget_settings:
#        z: -1 # this places the widget above all other slides

Bowman9

unread,
Jul 7, 2026, 11:34:39 PMJul 7
to MPF Users
A little update, it seems that the skillshot mode is not completely resetting between balls.
I added a skillshot countdown timer (30 to 0) and noticed that when the next skillshot mode starts the timer briefly shows where the previous timer left off before resetting to 30.

I am wondering if this is also happening with the rollover lights.
Is there a way to start a (skillshot) mode "clean" every time ?

thanks

Ben Tripoli

unread,
Jul 8, 2026, 11:49:00 PMJul 8
to MPF Users
reset_events: is your friend here on shots and shot groups. Timers I use a action: reset 

Alex L

unread,
Jul 10, 2026, 4:59:04 AMJul 10
to MPF Users
Also look into shot:persist_enable, which defaults to true and keeps shot state across balls.

https://missionpinball.org/latest/config/shots/#persist_enable

Bowman9

unread,
Jul 10, 2026, 9:50:45 PMJul 10
to MPF Users
Ben and Claude AI were right. I needed the correct reset events

Thanks for the help.

shot_groups:
  skill_lanes:
    shots:
      - skill_01
      - skill_02
      - skill_03
      - skill_04
      - skill_05
    reset_events:
      - ball_started
      - mode_skill_shot_testing_stopped # this was set wrong
    rotate_right_events: timer_skillshot_timer_tick  

shots:
  skill_01:
    switch: s_rollover_01
    profile: skillshot_profile
    show_tokens:
      light: l_top_rollover_light_1
    reset_events: ball_started      
  skill_02:
    switch: s_rollover_02
    profile: skillshot_profile
    show_tokens:
      light: l_top_rollover_light_2
    reset_events: ball_started      
  skill_03:
    switch: s_rollover_03
    profile: skillshot_profile
    show_tokens:
      light: l_top_rollover_light_3
    advance_events: mode_skill_shot_testing_started
    reset_events:
      - ball_started
      - mode_skill_shot_testing_stopped  
  skill_04:
    switch: s_rollover_04
    profile: skillshot_profile
    show_tokens:
      light: l_top_rollover_light_4
    reset_events: ball_started      
  skill_05:
    switch: s_rollover_05
    profile: skillshot_profile
    show_tokens:
      light: l_top_rollover_light_5
    reset_events: ball_started  

Bowman9

unread,
Jul 17, 2026, 11:30:14 PMJul 17
to MPF Users
I encountered a new wrinkle when calling up a widget in this skillshot mode.

As seen below:
If skill_lanes_lit_hit the widget player plays award_skillshot_widget
If playfield_active the widget player plays missed_skillshot_widget

However, the shot/switches in my skill_lanes shot_groug are tagged as playfield_active in my switches.yaml, so both widgets will play.

Is there a way define the same roll over switches with two different tags to avoid this?
Or is there another solution I'm not seeing?

widget_player:
  skill_lanes_lit_hit:  ### trigger shot group

    shoot_skillshot_widget:
      action: remove    
    award_skillshot_widget: ### widget defined on widgets yaml
      action: add
      widget_settings:
        z: -1 # this places the widget above all other slides
  playfield_active: ### trigger
    shoot_skillshot_widget:
      action: remove

    missed_skillshot_widget: ### widget defined on widgets yaml
      action: add
      widget_settings:
        z: 10

Anthony van Winkle

unread,
Jul 22, 2026, 12:55:24 PMJul 22
to MPF Users
Using playfield_active is risky because there are also built-in events to trigger it, but a different approach may help.

One option would be, assuming the skillshot shots are in a group, using the unlit state event to trigger the "miss" action (e.g. skill_lanes_unlit_hit) and using a timeout to disable the skillshot after a few seconds, in the event the player misses the rollover lanes entirely.

Another option would be to set a variable skillshot_hit and make it true when the skill_lanes_lit_hit is hit, and then the "miss" widget only appears if that variable is false.

Bowman9

unread,
Aug 8, 2026, 12:29:29 AMAug 8
to MPF Users
Just in case some else is reading this in the future looking for an answer, most likely AI

In my switches.yaml I added the tag "skill_shot_cancel " to all the switches that would be used to cancel the skill shot

examples
  s_bullseye_target:
    number:
    tags: playfield_active, skill_shot_cancel
  s_spinner_target:
    number:
    tags: playfield_active, skill_shot_cancel

in my skillshot.yaml I added "sw_skill_shot_cancel_active" to the event player as a reason to end the skillsot

example
mode:
  start_events:
    - ball_started
    - mode_bonus_stopped
  stop_events:
    - skill_success
    - skill_failed
  priority: 400

event_player:
  timer_skillshot_timer_stopped: skill_failed|1.25s
  skill_lanes_lit_hit: skill_success|1.25s
  skill_lanes_unlit_hit: skill_failed|1.25s
  sw_skill_shot_cancel_active: skill_failed|1.25s

I also updated my widget player using "sw_skill_shot_cancel_active"

example
widget_player:
  mode_skill_shot_testing_started: ### trigger
    shoot_skillshot_widget: ### widget defined on widgets yaml
      action: add
      widget_settings:
        z: 100 ### -1 would place this widget above all other slides

  sw_skill_shot_cancel_active: ### trigger
    shoot_skillshot_widget:
    action: remove
    missed_skillshot_widget: ### widget defined on widgets yaml
      action: add
      widget_settings:
        z: 50 ### -1 would place this widget above all other slides

this appears to be working correctly when testing virtually 
Reply all
Reply to author
Forward
0 new messages