-
Notifications
You must be signed in to change notification settings - Fork 63
Porting an existing Visual Pinball PinMAME game
Game logic for many Visual Pinball tables is done using VBScript. A table contains a script that references other scripts that are included with a Visual Pinball installation. The scripts all work together and connect the playfield to a game controller such as Visual PinMAME.
Out of the box, Visual Pinball Engine can do a lot without any scripting at all!
This guide will show how to port an existing "Terminator 2: Judgement Day" VPX table to Visual Pinball Engine.
For most of the setup, we can refer to this page.
Make sure you are using Unity 2020.3.11f or greater.
Install the following packages:
-
VisualPinball.Engine
(0.0.1-preview.46 or greater) -
VisualPinball.Engine.PinMAME
(0.0.1-preview.42 or greater) -
VisualPinball.Unity.Hdrp
(0.0.1-preview.58 or greater)
Setup the VPE scoped registry:
Clone the repositories:
git clone https://github.com/freezy/VisualPinball.Engine
git clone https://github.com/VisualPinball/VisualPinball.Unity.Hdrp
git clone https://github.com/VisualPinball/VisualPinball.Engine.PinMAME
Build the PinMAME Unity Plugins:
The PinMAME libraries are large and change often, so they are not stored in the git repo. We only need to do this once.
cd VisualPinball.Engine.PinMAME
git checkout feature/audio
cd VisualPinball.Engine.PinMAME
dotnet build -c Release
Verify the plugins have been created by looking in the Plugins/<RID>
folder:
You will need to find an existing Terminator 2 L8
ROM. (Not sharing where to find one)
- If you are on Windows, make sure you have a working install of VPinMAME. Place the ROM in the VPinMAME's
roms
folder:
- If you are on MacOS or Linux, make a
.pinmame/roms
folder in your home directory and place the ROM here:
The service manual contains switch and solenoid location information. This information is important when configuring switches in the Switch Manager, and coils in the Coil Manager. Service manuals are available at IPDB
Create a new Basic Indoors (HDRP)
Scene and save it as T2VPE
Select the Main Camera
, and set Post Anti-aliasing
to SMAA
Select the Plane
, and change the Transform Y Position
to -0.1
You will need to find an existing "Terminator 2: Judgement Day" VPX table. (Not sharing where to find one)
In the Visual Pinball
menu, select Import VPX
, and open the "Terminator 2: Judgement Day" vpx file.
We will need to refer to the table script when configuring the table.
- If you are on Windows and have Visual Pinball installed, view the script using the
Script
command in theView
menu.
- If you are on MacOS or Linux, use the
VisualPinball.TableScript
command line tool which is part of the VisualPinball.Tools project. You can download it here.
Extract the table script:
VisualPinball.TableScript "Terminator 2: Judgment Day (Williams 1991).vpx" .
Note: If you are on MacOS and have issues running the utility, run the following:
chmod +x VisualPinball.TableScript
xattr -d com.apple.quarantine VisualPinball.TableScript
The table also uses other scripts that are part of a Visual Pinball installation:
Now that we have everything we need, let's start porting!
Whenever a table is imported, a Default Game Logic
component is automatically added:
Remove it by selecting Remove Component
in the Table Inspector under Default Game Logic
:
Add a PinMAME Game Logic
component by selected Add Component
and searching for PinMAME
:
In the PinMAME
Inspector, set the following values:
Game: Terminator 2: Judgement Day
ROM: L-8
The PinMAME Game Logic
component can automatically configure switches, coils, and lamps per game. While this feature is not complete, it provides a good start in setting up the table.
Select Populate Hardware
and then click Yes
when prompted:
Confirm that the Switch and Coil Managers have been updated:
To add a DMD (Dot Matrix Display), select Create Displays
:
Save the scene.
Click the Play button.
If this is the first time running the ROM, the DMD will cycle between
BOOKKEEPING
TOTALS CLEARED
and
FACTORY SETTINGS
RESTORED
Press 7
to continue initializing the ROM.
Click the Stop button.
Next, we need to configure the Trough.
Refer to the Service Manual to find the Switch and Solenoid locations:
When the ball enters the outhole, it actives Switch 18 (Outhole). The CPU activates Coil 3 (Outhole) which kicks the ball in the trough. If all three balls are in the trough, then Ball 3 activates Switch 15 (Trough Left), Ball 2 activates Switch 16 (Trough Center), and Ball 1 activates Switch 17 (Trough Right).
When the player hits the Start button (Switch 13), the CPU activates Coil 4 (Trough) which moves Ball 1 into the Shooter Lane. Ball 1 then activates Switch 78 (Shooter). When the player presses the Grip Trigger (Switch 34), the CPU activates Coil 9 (Plunger) which launches the Ball 1 around the playfield.
In the Table Hierarchy, search for Trough
.
In the Trough Inspector, set the following values:
Type: Two coils multiple switches
Ball Count: 3
Switch Count: 3
Has Jam Switch: [ ]
Roll Time: 300
Playfield Links
Input Switch: Drain
Exit Kicker: Ball Release
In the Switch Manager, configure the Trough switches:
15, Trough Left, Device, Trough - Ball 3 (entry)
16, Trough Center, Device, Trough - Ball 2
17, Trough Right, Device, Trough - Ball 1 (eject)
18, Outhole, Device, Trough - Entry Switch
In the Coil Manager, configure the Trough coils:
3, Outhole, Device, Trough, Entry
4, Trough, Device, Trough, Exit
Save the scene.
Click the Play button.
Once the ROM finishes initializing, press 5
to add coins. Press 1
to start the game.
The ball never makes it into the shooter lane.
Click the Stop button.
To see what is happening, turn off the apron Primitive 68
and shooter cover Primitive 45
.
Click the Play button.
Once the ROM finishes initializing, press 5
to add coins. Press 1
to start the game.
Now we can see the ball move, but it doesn't have enough power to make it into the shooter lane:
Click the Stop button.
We need to review the table script to see how the trough was set up. Search the table script for Trough
.
bsTrough
is defined as a cpvmBallStack
object:
In Core.vbs, find the cvpmBallStack.InitKick
function:
Public Sub InitKick(aKicker, aDir, aForce)
Set mExitKicker = aKicker : mExitDir = aDir : mExitForce = aForce
Set mSoundKicker = aKicker
End Sub
The parameter names aDir
, and aForce
hint they are related to direction and force.
Activating BallRelease
will kick a ball 90
degrees with a force of 8
.
If we search the Table Hierarchy for BallRelease
, we see the following values:
Default Angle: 90
Default Speed: 3
Update the values to:
Default Angle: 90
Default Speed: 8
Save the scene.
Click the Play button.
Once the ROM finishes initializing, press 5
to add coins. Press 1
to start the game.
The ball now enters the shooter lane!
Next, we need to configure the Plunger.
From the Service Manual, we know that the table uses a solenoid, Coil 9 (Plunger), for launching the ball into the playfield.
If we search the Table Hierarchy for Plunger
, select Plunger1
.
Notice that Plunger1
is located on the left side of the playfield:
Plunger1
must be Coil 8 (Kickback), and was NOT what we were looking for.
Review the table script and search for SolCallBack(9)
.
SolCallBack(9)
references bsShooter
. bsShooter
is defined as a cpvmBallStack
object:
In Core.vbs, find the cvpmBallStack.InitSaucer
function:
Public Sub InitSaucer(aKicker, aSw, aDir, aPower)
InitKick aKicker, aDir, aPower : mSaucer = True
If aSw Then mSw(1) = aSw Else mSw(1) = aKicker.TimerInterval
End Sub
The parameter names aSw
, aDir
, and aPower
hint they are related to switch, direction, and power.
Shooter
is connected to switch 78
. Activating Shooter
will kick a ball 0
degrees with a power of 50
.
In the Switch Manager, set switch 78
to Shooter
:
78, Shooter, Playfield, Shooter
In the Coil Manager, set coil 09
to Shooter
.
09, Plunger, Playfield, Shooter
Save the scene.
Click the Play button.
Once the ROM finishes initializing, press 5
to add coins. Press 1
to start the game.
When the ball enters the shooter lane, press Enter
to launch the ball.
We see the ball move slightly and it appears the CPU activates Coil 9 several times.
Click the Stop button.
If we search the Table Hierarchy for Shooter
, we see the following values:
Default Angle: 90
Default Speed: 3
Update the values to:
Default Angle: 0
Default Speed: 50
Click the Play button.
Once the ROM finishes initializing, press 5
to add coins. Press 1
to start the game.
When the ball enters the shooter lane, press Enter
to launch the ball.
The ball now exits the shooter lane and onto the playfield!