Skip to content

Commit

Permalink
test: add more multiball testing
Browse files Browse the repository at this point in the history
  • Loading branch information
unRARed committed Dec 23, 2024
1 parent b38a0af commit 93af37b
Show file tree
Hide file tree
Showing 13 changed files with 133 additions and 49 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ graph TD
BASE -- fuel up --> GREEN_FLAG[/"Green Flag Mode"/]
GREEN_FLAG -- make 3 laps --> RANDOM1{"Random<br>Event"}
GREEN_FLAG -- make 10 laps --> GL_MODE[/"Grooveline Mode"/]
GREEN_FLAG -- grand prix sequence --> GP_MODE[/"Grand Prix Mode"/]
RANDOM1 -- fuel -->
PIT_CHECK{"Fuel, Oil or Tires need attention?"}
RANDOM1 -- tires --> PIT_CHECK
Expand All @@ -36,8 +37,8 @@ graph TD
PIT_CHECK -- yes --> BASE
PIT_CHECK -- no --> GREEN_FLAG
GL_MODE --> GL_MULTI("Grooveline Multiball")
GP_MODE --> GP_MULTI("Grand Prix Multiball")
GL_MULTI -- make 3 laps --> GL_MULTI_ADD_BALL("Add a Ball")
```

### Production Machine Setup
Expand Down
5 changes: 3 additions & 2 deletions config/common/ball_devices.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

ball_devices:
bd_trough:
#debug: true
ball_switches:
- s_trough1
- s_trough2
Expand All @@ -11,13 +12,13 @@ ball_devices:
- home
- drain
auto_fire_on_unexpected_ball: false
debug: true
eject_coil: c_trough_eject
eject_coil_jam_pulse: 15ms
eject_targets: bd_shooter_lane
eject_timeouts: 1s
jam_switch: s_trough_jam
bd_shooter_lane:
ball_switches: s_shooter_lane
mechanical_eject: true
eject_timeouts: 3s
eject_coil: c_auto_kicker
player_controlled_eject_event: s_launch_active
10 changes: 4 additions & 6 deletions config/common/coils.yaml
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
#config_version=6

coils:
c_auto_kicker:
number: 5-3
default_pulse_ms: 20
c_trough_eject:
number: 0-2
default_pulse_ms: 40
default_hold_power: 0.1
c_plunger_lane:
number: 0-3
default_pulse_ms: 40
default_hold_power: 0.1
default_pulse_ms: 20
c_flipper1:
number: 4-0
default_pulse_ms: 35
Expand Down
9 changes: 8 additions & 1 deletion config/common/switches.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ switches:
s_start:
number: 2-30
tags: start
s_launch:
number: 2-31
# UNUSED 2-31

####################
Expand Down Expand Up @@ -154,4 +156,9 @@ switches:
number: 5-29
tags: right_flipper
# UNUSED 5-30
# UNUSED 5-31

# NOTE: this is a dummy switch for use in testing
# without side effects
s_activate_playfield:
number: 5-31
tags: playfield_active
4 changes: 2 additions & 2 deletions config/production/hardware.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ hardware:
segment_displays: mypinballs

opp:
debug: true
#debug: true
baud: 115200
ports: /dev/ttyACM0

mypinballs:
debug: true
#debug: true
#port: /dev/ttyAMA0
port: /dev/ttyACM1
17 changes: 13 additions & 4 deletions modes/grooveline/config/grooveline.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,25 @@ mode:
start_events:
- logicblock_grooveline_counter_complete
stop_events:
- multiball_grooveline_ended
- multiball_grooveline_multiball_ended
restart_on_next_ball: false
priority: 200

# TODO: May not need this
coil_player:
s_shooter_lane_active: c_auto_kicker

multiballs:
grooveline:
grooveline_multiball:
debug: true
ball_count: 1
ball_count_type: add
shoot_again: 15s
start_events: mode_grooveline_started
shoot_again: 10s
add_a_ball_shoot_again: 0
start_events:
- mode_grooveline_started
stop_events:
- multiball_grooveline_multiball_ended
# Making 3 laps adds 1 ball
add_a_ball_events:
- player_grooveline_counter_count{current_player.grooveline_counter_count == 3}
32 changes: 16 additions & 16 deletions monitor/monitor.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,9 @@ switch:
s_flipper2_eos:
x: 0.34903583411314903
y: 0.9198250728862974
s_fuel:
x: 0.7246294946550048
y: 0.4562682215743441
s_grand_advance:
x: 0.5797035957240039
y: 0.5349854227405249
Expand All @@ -265,13 +268,19 @@ switch:
x: 0.5962129617730444
y: 0.7142857142857143
s_inlane2:
x: 0.8963566167886318
x: 0.8963566167886317
y: 0.7186588921282799
s_launch:
x: 0.972097303206997
y: 0.9664723032069972
s_oil:
x: 0.8640864917395531
y: 0.2099125364431487
s_outlane1:
x: 0.5622600596219599
y: 0.7142857142857143
s_outlane2:
x: 0.9275932867676294
x: 0.9275932867676295
y: 0.7186588921282799
s_podium_advance1:
x: 0.6658387998056365
Expand All @@ -294,15 +303,6 @@ switch:
s_prix_hole:
x: 0.9228771865889214
y: 0.4708454810495627
s_fuel:
x: 0.7246294946550048
y: 0.4562682215743441
s_oil:
x: 0.8640864917395531
y: 0.2099125364431487
s_tires:
x: 0.6412287414965987
y: 0.2142857142857143
s_service_back:
x: 0.41016763848396504
y: 0.6180758017492711
Expand All @@ -316,13 +316,13 @@ switch:
x: 0.47442723517978624
y: 0.6355685131195336
s_shooter_lane:
x: 0.968336769348931
x: 0.9683367693489311
y: 0.8440233236151604
s_slingshot1:
x: 0.641030792612476
y: 0.7128279883381925
s_slingshot2:
x: 0.8569712502933736
x: 0.8569712502933737
y: 0.7186588921282799
s_spinner:
x: 0.8627192662779398
Expand All @@ -333,6 +333,9 @@ switch:
s_tilt:
x: 0.0665476882161257
y: 0.6530612244897959
s_tires:
x: 0.6412287414965987
y: 0.2142857142857143
s_trough1:
x: 0.765977472528467
y: 0.9067055393586007
Expand All @@ -342,6 +345,3 @@ switch:
s_trough3:
x: 0.8352413929166795
y: 0.8790087463556852
s_trough_jam:
x: 0.8556131342073302
y: 0.9373177842565598
Binary file modified monitor/playfield.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 20 additions & 1 deletion tests/death_save.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def _assertIncrement(self, var, switch, value):

def _start(self):
self.assertEqual(3,
self.machine.ball_devices.bd_trough.balls)
self.machine.ball_devices["bd_trough"].balls)
self.assertModeRunning('attract')
self.assertModeNotRunning('base')
self.hit_and_release_switch("s_start")
Expand All @@ -40,6 +40,11 @@ def _start(self):
self.advance_time_and_run(4)
self.assertEqual(1, self.machine.playfield.balls)

def _start_and_expire_ball_save(self):
self._start()
self.hit_and_release_switch("s_activate_playfield")
self.advance_time_and_run(15)

# assumes base mode is running (game started)
def _start_green_flag(self):
# Player must "fill up" to start racing
Expand All @@ -64,3 +69,17 @@ def _start_grooveline(self):
self.advance_time_and_run(1)
self.advance_time_and_run(4)
self.assertModeRunning("grooveline")

# assumes green_flag mode is running
def _start_grand_prix(self):
self.machine.events. \
post("logicblock_grand_prix_counter_complete")
self.advance_time_and_run(1)
self.advance_time_and_run(4)
self.assertModeRunning("grand_prix")

# From https://github.com/missionpinball/mpf/blob \
# /dev/mpf/tests/MpfGameTestCase.py#L141
def _drain_one_ball(self):
drain = self.machine.ball_devices.items_tagged("drain")[0]
self.machine.default_platform.add_ball_to_device(drain)
9 changes: 9 additions & 0 deletions tests/death_save_game_testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,20 @@ def _assertIncrement(self, var, switch, value):
def _start(self):
death_save._start(self)

def _start_and_expire_ball_save(self):
death_save._start_and_expire_ball_save(self)

def _start_green_flag(self):
death_save._start_green_flag(self)

def _start_grooveline(self):
death_save._start_grooveline(self)

def _start_grand_prix(self):
death_save._start_grand_prix(self)

def _complete_lap(self):
death_save._complete_lap(self)

def _drain_one_ball(self):
death_save._drain_one_ball(self)
2 changes: 1 addition & 1 deletion tests/test_general.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ def test_game_start(self):

def _machine_boots(self):
self.assertEqual(3,
self.machine.ball_devices.bd_trough.balls)
self.machine.ball_devices["bd_trough"].balls)
self.assertModeRunning('attract')
self.assertModeNotRunning('base')

Expand Down
20 changes: 20 additions & 0 deletions tests/test_grand_prix_mode.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,15 @@ def test_qualification(self):

self.assertModeRunning("grand_prix")

def test_multiball(self):
self._start_multiball()

# Player launches the ball
self.hit_and_release_switch("s_shooter_lane")
self.hit_switch_and_run("s_podium_advance2", 4)
self.assertEqual(2, self.machine.playfield.balls)


def _light_grand(self):
for i in range(5):
self.hit_and_release_switch("s_grand_advance")
Expand All @@ -66,3 +75,14 @@ def _light_prix(self):
self.machine.counters["grand_counter"].enabled)
self.assertEqual(False,
self.machine.counters["prix_counter"].enabled)

def _start_multiball(self):
self._start_and_expire_ball_save()
self._start_green_flag()
self._start_grand_prix()
self.assertEqual(2, self.machine.playfield.balls)
# A ball is ejected to the shooter lane
self.assertEqual(1,
self.machine.ball_devices["bd_trough"].balls)
self.assertEqual(0,
self.machine.ball_devices["bd_shooter_lane"].balls)
50 changes: 35 additions & 15 deletions tests/test_grooveline_mode.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,30 +52,48 @@ def test_qualification(self):
self.assertEqual(
0, self.machine.game.player.grooveline_counter_count)
# And grooveline mode begins (multiball)
self.assertEqual(True, self.machine. \
multiballs["grooveline_multiball"].enabled)

def test_multiball(self):
self._start_multiball()

# Player launches the ball
self.hit_and_release_switch("s_shooter_lane")
self.hit_switch_and_run("s_podium_advance2", 4)
# Second ball already in play
self.assertEqual(2, self.machine.playfield.balls)
self.assertEqual(1,
self.machine.ball_devices["bd_trough"].balls)
self.assertEqual(0,
self.machine.ball_devices["bd_shooter_lane"].balls)

# ensure add a ball time has expired
self.advance_time_and_run(15)
# A lot of time passes - should have
# exceeded the shoot again period
self.advance_time_and_run(30)

# ball drains
self.hit_switch_and_run("s_trough1", 4)
self.hit_and_release_switch("s_shooter_lane")
# Ball drains
self._drain_one_ball()
self.advance_time_and_run(4)

# Bug here? Shoot again should have expired, but ball
# still kicked out to shooter lane - tried numerous
# ways to fix - maybe bug in MPF
self.assertEqual(1, self.machine.playfield.balls)
self.assertEqual(1,
self.machine.ball_devices["bd_trough"].balls)
self.assertEqual(1,
self.machine.ball_devices["bd_shooter_lane"].balls)

self.assertModeRunning("grooveline")
# After the NEXT drain, the mode and multiball
# ends as expected
self._drain_one_ball()
self.advance_time_and_run(4)
self.assertModeNotRunning("grooveline")

def test_add_a_ball(self):
self._start_multiball()

# Player launches the ball
self.hit_and_release_switch("s_shooter_lane")
self.hit_switch_and_run("s_podium_advance2", 4)
self.hit_switch_and_run("s_activate_playfield", 4)
self.assertEqual(2, self.machine.playfield.balls)

# Player completes 3 laps
Expand All @@ -85,21 +103,23 @@ def test_add_a_ball(self):
# Another a ball is added
self.assertEqual(0,
self.machine.ball_devices["bd_trough"].balls)
self.assertEqual(1,
self.assertEqual(0,
self.machine.ball_devices["bd_shooter_lane"].balls)

# Player launches this ball, too
self.hit_and_release_switch("s_shooter_lane")
self.hit_switch_and_run("s_podium_advance2", 4)
self.hit_switch_and_run("s_activate_playfield", 4)
self.assertEqual(3, self.machine.playfield.balls)

def _start_multiball(self):
self._start()
self._start_and_expire_ball_save()
self._start_green_flag()
self._start_grooveline()
self.assertEqual(1, self.machine.playfield.balls)
self.assertEqual(2, self.machine.playfield.balls)
# A ball is ejected to the shooter lane
self.assertEqual(1,
self.machine.ball_devices["bd_trough"].balls)
self.assertEqual(1,
self.assertEqual(0,
self.machine.ball_devices["bd_shooter_lane"].balls)
self.assertEqual(True, self.machine. \
multiballs["grooveline_multiball"].enabled)

0 comments on commit 93af37b

Please sign in to comment.