Bride of Pinbot¶
VPW build of Williams' 1991 Bride of Pinbot, featuring extensive 3D insert work, Flupper dome flashers, Fleep 2.0 era-based sound cartridges, PROC compatibility, dynamic shadow code, and VR optimization. Development spanned 2020 through 2024 with contributions from wrd1972, iaakki, benji084, cyberpez, sixtoe, fluffhead35, niwak, leojreimroc, robbykingpin, jlouloulou, and others.
Build Notes¶
Playfield Image Resolution¶
Playfield images at exactly 4000px width/height work best. 4096px (power of two) causes mipmapping issues where VPX downscales the image, resulting in blurriness. 6000px showed diminishing returns for the extra file size. The 4K sweet spot avoids the mipmapping threshold while providing sufficient detail.
WPC Playfield Dimensions Correction¶
WPC standard playfield dimensions are actually 20.25" x 46", NOT 20.5" x 46" as commonly listed in the "Dimension Manager" reference. Confirmed by measuring a real Shadow playfield. Most playfields are approximately 51.45cm wide. This measurement error propagated through many VPX tables causing subtle alignment issues.
nFozzy Flipper Physics Update¶
BOP v1.0.5-1.0.7 updated flipper physics based on Fish Tales improvements:
- Flipper swing angle changed to 48 degrees, aligned to playfield mounting holes (the small holes are for inserting a toothpick to set bat position)
- Flipper strength reduced from 2600 to 2400 -- BOP uses medium red FL-11630 coils while Fish Tales uses strong blue FL-11629
- Sleeve friction reduced to 0.3 (matching nFozzy tutorial and Fish Tales)
- Latest nFozzy code with FlipperCradleCollision integrated
- Endpoint triggers removed (not needed with new code)
Flipper Coil Strength by Era¶
Flipper coil strength varies by era: BOP (1991, medium red FL-11630) uses strength approximately 2400, Fish Tales (1992, strong blue FL-11629) uses 2600. The 2000-2600 range uses the same EOS ratio (0.375). EOSReturn is a fudge factor because VPX return strength is based on flipper strength (unlike real life where it is based on return spring).
Version History¶
- WIP027-061: wrd1972 original development with cyberpez, iaakki, benji084
- WIP061-077: ClarkKent playfield scan, iaakki realignment to 20.25x46", fluffhead35 physics/sounds, Fleep 2.0 SSF
- WIP080-098: PROC support, VR room, dynamic shadows, performance hunting
- RC1/v1.0: Release with gate rework, skillshot lights, instruction cards
- v1.0.5-1.0.7: New flipper angles (48deg), nFozzy/Roth physics updates, FlipperCradleCollision
Scripting¶
Lampz Initialization for GI-Tied Primitives¶
When using Lampz to control GI-tied disable-lighting (DL) primitives, Lampz.state(2) = 1 must be called during initialization. Without this, DL primitives linked to GI will not initialize correctly.
VPX Ball Reflections -- 8 Nearest Lights Including Off Lights¶
VPX ball reflections use only the 8 nearest lights, and it does NOT care whether lights are on or off -- it just takes the 8 nearest. Lampz users are less affected because Lampz slides intensityscale to 0 rather than turning lamp state off, but the reflection slot is still consumed.
Black Lights to Block Unwanted Ball Reflections¶
To prevent ball reflections from bleeding into areas where walls should block light (e.g., plunger lane), add lights that cast only black light (zero intensity) in the blocking area. This exploits VPX's 8-nearest-lights reflection system by filling slots with zero-contribution lights.
Dynamic Shadow Code -- Nearest Light Sorting¶
niwak's improved dynamic shadow implementation: instead of relying on collection order, it sorts to find the 2 nearest influencing lights using distance calculation. Applies falloff-based opacity and uses UpdateMaterial with ShadowOpacity*DynamicBSFactor^3 for realistic shadow rendering. Includes an ambient ball shadow that brightens when near a light.
Spinner Shadow with Sine Equation¶
Dynamic spinner shadow using a single line:
Shadow width is 0 at 0/180 degrees and maxes at 90/270 degrees. Minimum should be set to approximately 0.5 rather than 0 for realism.
Flasher Fading Performance Option¶
Script option for flasher fading performance: high-perf system (0) gives smoother fading with approximately 58 steps on drain, low-perf system (1) gives more coarse fading with approximately 38 steps. The fading equation ObjLevel(nr) = ObjLevel(nr) * 0.85 - 0.01 produces approximately 45 events per flasher on drain.
GI Update Optimization -- Separate Subs Per Zone¶
GI updates should use a case statement or separate subs per zone. When all 4 GI channels fire the same GIUpdate sub simultaneously, it runs 4x more than needed. Separating to GIUpdatesPF and GIUpdatesBG reduces unnecessary computation.
SolCallback vs SolModCallback -- PROC Compatibility¶
PROC cannot send leveled (0-255) flasher values -- only binary 0/1. Therefore PROC uses SolCallback while PinMAME uses SolModCallback for flashers. Script option UsePinmameModulatedSolenoids toggles between modulated and binary flasher behavior.
Flasher Relay Sounds -- System 11¶
BOP flasher solenoids do not use "clickish" relay solenoids. In System 11 tables, the clickish solenoids are only for upper GI, lower GI, and A/C solenoid. For modulated solenoid sounds, play the relay sound only when output crosses the 128 threshold.
Fleep 2.0 Sound Cartridges¶
Fleep's sound system uses "cartridges" -- interchangeable era-based sound collections. Williams System 11 tables share similar mechanical sounds. Cartridge sources for BOP include recordings from Whirlwind, Diner, TNA, Theatre of Magic, Who Dunnit, and Pinbot. Matching cartridge to era gives more authentic feel.
SetLocale 1033 for Regional Compatibility¶
Add SetLocale 1033 at the top of the script to prevent VBScript issues with regional decimal separator differences. Some regions use comma instead of period for decimals, which breaks floating-point parsing.
3D & Art¶
Insert LOF (Level of Frost)¶
Insert LOF controls the frosted vs. clear appearance of insert lenses. Debate: some prefer fully frosted for a softer glow, others prefer partially clear to see the bulb filament underneath. The real-world appearance depends on age/wear. BOP inserts kept moderately frosted to match the era.
Insert Text Overlays -- Curved Text¶
For insert text overlays with curved text (e.g., BOP star pattern inserts), Illustrator is the preferred tool. Paint Shop Pro can also be used but may have font rendering bugs. Insert ON textures need careful material settings -- the OFF image may look fine while the ON image shows artifacts.
Blender Boolean Workflow for Gate Brackets¶
Apply the boolean modifier first, then triangulate (at minimum the faces with holes), then unwrap, then export. Bad geometry from boolean operations skews shading.
Screw Thread Faking with Textures¶
Screw threads are extremely high polygon count if modeled geometrically. Instead, render the screw image into the post texture. For translucent posts, this makes the screw visible through the plastic without adding geometry.
Plastic-Shaped VPX Lights¶
A simple way to light up a plastic: create a VPX light object shaped to match the plastic outline. More straightforward than complex flasher setups and gives natural-looking illumination.
Locknuts -- Low Poly Solutions¶
Original locknuts in BOP were 17K polys each -- wildly excessive. Remodeled at 780 polys with good visual quality. niwak's core parts library has even lower-poly alternatives. Key rule: for small hardware like nuts and screws, anything over 1K polys is excessive.
Blender Model Optimization -- Limited Dissolve¶
For reducing polygon count without full remesh: merge by distance, limited dissolve with very low angle, reset normals, clear sharp edges, re-mark edges, small bevel + weighted normals. VPX faces should be flat and convex for best results.
Core Parts Library¶
niwak's core parts library contains 400-500 pinball assets (screws, nuts, posts) with low-poly versions under 400 tris. Setup: Edit > Preferences > File Paths, add root directory as asset library path. All parts modeled in inches.
Flupper Dome Primitive 90-Degree Cut¶
Flupper dome primitives benefit from a 90-degree cut -- splitting the dome into two halves so the texture maps correctly from all viewing angles. Important for tables predating the toolkit era.
Troubleshooting¶
WAV File 32-bit Float Incompatible with VPX 10.7¶
WAV files saved as 32-bit float format do not play in VPX 10.7 final (they work in 10.7.2+). Fix: re-export as 24-bit signed integer using Audacity. Always use 24-bit WAV for maximum compatibility.
VPX Collection Bugs¶
Collections have persistent bugs: incorrect object counts, objects get events from wrong collections, and hit events stop working. Workaround: delete old collections, create new ones, disable/re-enable hit events, and restart VPX between steps.
VR Performance -- Transparent Objects Dominate Frametime¶
Performance profiling showed transparent objects consuming 50-65% of frametime. With 693 primitives, the table is heavy. Removing screws (144 polys each, 78 total) showed significant stability improvement. First-time flasher firing causes texture loading stutter -- a preloader is needed.
B2S DLL vs EXE Mode Causing Ball Stutter¶
B2S backglass server running in DLL mode causes ball stutter on some tables. Switching to EXE mode eliminates the stutter. If experiencing constant ball stutter with solid FPS, check B2S mode first.