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.
1 2 |
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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# 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 trough
N where N is the number of balls held in your trough, and trough1
is the leftmost switch —trough
N is the switch closest to the shooter lane).
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 heretags: 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, 8×8, 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.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
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.