# Step 2: Config and Machine YAML files

Page content

## Understanding the config.yaml:

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 machineyaml file:

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
PRGame:
machineType: wpc   # hardware platform
numBalls: 3
PRFlippers:
- flipperLwR      # flippers in this machine, requires switches and coils to be defined
- flipperLwL
PRBumpers:
- 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
- jetB
PRSwitches:
# **** Format ****
# name:
#   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)
flipperLwR:
number: S11      # switch at column 1, row 1
ballsearch: stop # stop: this switch prevents the ballsearch timer from even starting
flipperLwL:
number: S12
ballsearch: stop
coinL:
number: SD1     # a "direct switch": manual shows it to the left of the first column
coinR:
number: SD3
exit:
number: SD5
down:
number: SD6
up:
number: SD7
enter:
number: SD8
startButton:
number: S13   # Switch column 1, row 3
tilt:
number: S14
trough1:
number: S15
ballsearch: reset # reset: this switch resets a ballsearch timer to occur X-seconds after this was seen
trough2:
number: S16
ballsearch: reset
trough3:
number: S17
ballsearch: reset
outhole:
number: S18
ballsearch: reset
slamTilt:
number: S21
coinDoor:
number: S22
PRCoils:
flipperLwRMain:
number: FLRM    # Flipper Lower Right Main
flipperLwRHold:
number: FLRH
flipperLwLMain:
number: FLLM
flipperLwLHold:
number: FLLH    # Flipper Lower Right Hold
flipperEnable:
number: G08    # T2 is pre-fliptronic, an enable relay is at G08
ballPopper:
number: C01
gunKicker:
number: C02
outhole:
number: C03
pulseTime: 30   # the duration of the pulse, in ms.  Default is 32ms
ballsearch: True   # fire this coil during a ball search
trough:
number: C04
ballsearch: True
slingR:
number: C05
slingL:
number: C06
knocker:
number: C07
PRLamps:
mult2x:
number: L11    # Column 1, Row 1
mult4x:
number: L12
holdBonus:
number: L13
mult6x:
number: L14
mult8x:
number: L15    # Column 1 Row 5
shootAgain:
number: L16


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: self.game.lamps.mult2x.enable()

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 trough1 through 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).

1. config/machine.yaml

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 trough1, trough2, .. troughN where N==num trough switches. OR your switches should be tagged as ’trough’ as shown here tags: trough
• your start button should be called startButton or tagged start_buton
• your shooter lane switch should be called shooter
• your (bob) tilt switch should be called tilt
• your slam-tilt switch should be called slamTilt
• 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 (a P3-ROC w/ PDB16, 8x8, etc), you can use the example pdb.yaml to get you started. On a P3-ROC, it is imperative that you set your machine type to pdb! Also, forum user JoeShabadu has written an amazing getting started guide that includes a post getting your machine yaml right for custom P3-ROC machines (Page 1). The whole thread documents his P3-ROC wiring and first steps programming his custom machine is a really good read if you’re starting from scratch on a P3-ROC custom machine. Joe’s P3-ROC wiring/getting started tutorial Page 2, Page3 , Page 4, Page 5, and Page 6).

## 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.

try: import procgame.game import pinproc game = procgame.game.GameController(machine_type=pinproc.MachineTypeWPC) game.load_config(‘machine.yaml’) game.enable_flippers(enable=True) game.lamps.somelamp.schedule(schedule=0x00ff00ff, cycle_seconds=0, now=False) game.log(“FLIPPERS SHOULD BE LIVE!”) game.run_loop() except Exception, e: print(e)
input(“Press Enter to continue…”) raise e

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.