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 machine yaml 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.