A PyProcGameHD/SkeletonGame ‘game’ will look for a file called ‘config.yaml’ when it launches to try to load some environment-wide and game speciifc settings. Your ‘config.yaml’ can exist in the same folder as your game code, if it isn’t found there the system will check for it in a folder called ‘.pyprocgame’ in your user folder. Chances are, if you are running your game from a different folder than the one your game is in, it will rely on that fail-safe location.
It defines the paths to the asset files your game will need (images, lampshows, sounds), SkeletonGame specific settings (which modes to enable or disable), DMD specific settings (resolution, fps), window settings (border, scale, dot-effect), whether to connect to the real P-ROC hardware or not (‘FakePinProc’), and finally a mapping of keyboard keys to switch numbers (for testing when the real P-ROC is not connected).
If you open up your
config.yaml file, you will see a very specifically formatted file that defines key/value pairs. The PyProcGame/PyProcGameHD/SkeletonGame code looks for the values of specific keys to set defaults for your game. YAML is a whitespace sensitive format, so the presence or absence of spaces may cause the file to no longer load properly. There’s a good, high-level overview of YAML here: http://docs.ansible.com/ansible/YAMLSyntax.html
The most important line to notice is the line that starts:
pinproc_class: –if this line is present and has a value of
procgame.fakepinproc.FakePinPROC, then the simulator will be used and it will NOT connect to a real P-ROC/P3-ROC. If you place a
# at the start of this line, it will be “commented out” so that the YAML processor ignores it. It is like deleting the line without actually deleting it. When you are ready to connect to a real P-ROC on a real pinball machine, you’ll want to comment out that line.
pinproc_class: procgame.fakepinproc.FakePinPROC # comment out this line when using a real P-ROC.
Understanding the machine
Once you have your
config.yaml the way you like it –that is, the display resolution has been set, the dot scale, dot effect, folders in which to find sounds and images and things– you need to define a machine configuration
yaml file (or machine yaml file).
Your machine yaml is different from your
config.yaml. A pinball machine is filled with switches, lamps, and coils, and we need a way to refer to them in the code. Identifying them based on their connection to the machine hardware (e.g., location in the lamp matrix, location in the switch matrix or the sw-16 board address and switch number) works, but it would be really cumbersome to write and to later debug. Who want’s to see things expressed in terms of S13, or C04?
This is the primary problem solved by the machine yaml file: you use it to define what components are attached to your machine and the yaml allows you to provide names (aliases) for each of the devices in your machine.
Below is an excerpt of the machine yaml file from the
SampleGame provided with SkeletonGame. The file
config\T2.yaml contains the entire configuration for this machine, which is a Williams Terminator 2. Looking at the excerpt you will see listings for coils, lamps, and switches. Each entry in the list (starting with a dash) is the friendly name for the device found at the corresponding number.
# P-ROC Game Description file for T2
machineType: wpc # hardware platform
- flipperLwR # flippers in this machine, requires switches and coils to be defined
- slingL # this category will auto-fire a coil with this name if a switch with this name
- slingR # is tripped. As such you need to define a switch AND a coil with this name if
- jetL # you place it here. These are P-ROC switch rules and happen within the FPGA
- jetR # so there is essentially no latency for these
# **** Format ****
# number: <number>
# type: <type>
# <number> can be: SFx (Flipper switch, labeled Fx in WPC manual
# SDx (Dedicated switch, labeled SDx in WPC manual
# Sx (Matrix switch, labeled x in WPC manual
# <type> can be: 'NO' (normally open. This is the default; so no need to use this)
# 'NC' (normally closed. Common for optos)
number: S11 # switch at column 1, row 1
ballsearch: stop # stop: this switch prevents the ballsearch timer from even starting
number: SD1 # a "direct switch": manual shows it to the left of the first column
number: S13 # Switch column 1, row 3
ballsearch: reset # reset: this switch resets a ballsearch timer to occur X-seconds after this was seen
number: FLRM # Flipper Lower Right Main
number: FLLH # Flipper Lower Right Hold
number: G08 # T2 is pre-fliptronic, an enable relay is at G08
pulseTime: 30 # the duration of the pulse, in ms. Default is 32ms
ballsearch: True # fire this coil during a ball search
number: L11 # Column 1, Row 1
number: L15 # Column 1 Row 5
In SkeletonGame, it’s recommended that you store your machine config in the config folder.
Later, when you are writing code, you will be able to refer to the machine’s elements by these names. For example:
SkeletonGame adds some additional functionality to the machine yaml when compared to the PyProcGame format, specifically SkeletonGame adds support for the tags on switches/coils related to ball search. In addition, in order to make your life easier, some of the helper modes provided in SkeletonGame require certain switches to have specific names (eg, your ball trough switches must be names
troughN where N is the number of balls held in your trough, and
trough1 is the leftmost switch —
troughN is the switch closest to the shooter lane).
This is the machine definition file. It maps all the switches, lamps and coils in your machine to easier to use logical names. Some samples are available, including the T2.yaml example in the Sample Game
You must adhere to a few naming conventions:
- your trough switches should be named
troughNwhere N==num trough switches. OR your switches should be tagged as ‘trough’ as shown here
- your start button should be called
startButtonor tagged start_buton
- your shooter lane switch should be called
- your (bob) tilt switch should be called
- your slam-tilt switch should be called
- ball search is handled differently! switches and coils should be tagged for ball search, as shown in the example.
defining your own machine yaml
If your game is a retheme/continued, based on an existing Williams or Stern boardset, someone may have already created a yaml file for you. You can check in shared/config for some existing yaml files. These files don’t conform to all of the naming requirements of the SkeletonGame naming convention, but starting from these files will likely make your job much easier. Also bear in mind that you might not like the names defined by someone else, and those names (except for those required by SkeletonGame) are totally at your discretion. If it seems like the name should be something else to you, go for it.
If your machine’s yaml doesn’t exist, you’ll need to grab a copy of the operator’s manual and generate entries for each of the lamps, switches, and coils. It can be helpful to use the machine yaml for another machine from the same manufacturer and vintage (and that machine’s manual) as a reference to get your machine’s yaml started.
For completely custom games running on the PinballControllers controller boards (PDB16, 8×8, etc), you can use the example pdb.yaml to get you started. Also, forum user JoeShabadu has written an amazing getting started guide that includes a post getting your machine yaml right for custom machines. Honestly, the whole thread is a good read if you’re starting from scratch on a custom machine.
sanity checking your machine yaml
This is optional, but a nice progress milestone for the impatient who want their game flipping now🙂
It can be a bit rough to try to get your game code up and running as the first thing you do, since you need to deal with your assets, etc. a good strategy is to use this code for a stripped down “first flips” game. It does nothing but load the machine yaml, initialize some things under the covers, and enable the flippers.
If you save the following into a file called ‘
first_flips.py‘, copy your machine yaml into the same folder as this file (call it
machine.yaml), and ensure that one of your lamps is actually called
somelamp, then running this file (literally just double-clicking ‘first_flips.py’ and running it with Python or the better way, running it from the command prompt via
python first_flips.py then your game should be up and flipping.
game = procgame.game.GameController(machine_type=pinproc.MachineTypeWPC)
game.log("FLIPPERS SHOULD BE LIVE!")
except Exception, e:
input("Press Enter to continue...")
This is NOT a SkeletonGame game, and as such you don’t have any trough support, ball counting, or anything of the sort. It’s just a nice quick way to get your flippers active. If the game won’t run, it’s because your machine yaml is malformed.
If you are having problems with your yaml file, there are several good online yaml file validation sites (like YAMLlint) that can help you find spacing, or other syntax problems. These resources don’t know about the meaning of the specific tags of the machine yaml, so they can’t help you with those things, but for these basic problems (that can be very hard to see), these tools can be indispensable.