Congo (Williams 1995)¶
VPW Lite build that documented the standard flasher exponential decay pattern, playfield mesh implementation gotchas, POV calibration workflow, and SolCallback vs SolModCallback behavior. Built collaboratively by iaakki, sixtoe, apophis79, and o0skitso0o, with significant version control lessons learned.
Build Story¶
Development ran from April 2021 through January 2026 including post-release maintenance. The build suffered notable version merge disasters -- apophis79's sound fixes in v024 were lost when sixtoe created a different v024 from an older base, leading to adoption of the VPW Bot checkout system. Congo used early nFozzy prototype code (predating the standardized implementation), which required careful migration to the flasher timer fading pattern.
Table-Specific Details¶
Mechanisms & Hardware¶
- SolModCallback behavior: Even with modulated solenoids, actual output values during gameplay are unpredictable. Congo's Sol17 showed erratic output levels (27, 72, 109, 36) with varying intervals (56ms to 3023ms). Best practice: use per-flasher timers with exponential decay regardless of modulation support.
- Light system evolution: Congo used a prototype mixing three systems:
nFadefor insert lamp fading,nModLight/nModLightmfor modulated solenoid flashers, and proto-ModLampz for GI. This evolved into the standardized ModLampz/Lampz system. - Kickback: Regular VPX plunger intermittently failed -- replaced with impulse plunger for instantaneous force rather than spring-loaded pull-and-release.
Art & Visuals¶
playfield_meshmust be imported at position 0,0 with scale 100. Any area with no faces becomes transparent automatically. If accidentally nudged from 0,0, all inserts and lights misalign. The mesh is rendered as Static, meaning BlendDisableLighting must be set in editor (not at runtime).- Ramp geometry cleanup in Blender: merge by distance, remove internal faces, add bevel BEFORE subdivision. VPX-exported ramp geometry always has unmerged vertices.
- LUT saturation philosophy: build assets with full saturation, use LUTs to reduce. Cannot expand dynamic range after baking.
- WPC ROM audio distortion at maximum volume (level 31). Fix: reduce to 30.
Physics & Gameplay¶
- nFozzy right flipper angles: Must use negative values (e.g., -122) rather than equivalent positive (238). Positive values cause live catch and nudge tricks to stop working entirely.
checklivecatchmust be explicitly called fromflipper_collidesubs -- if missing, trick shots will not register.
Known Issues¶
- Playfield mesh causing balls to hover at mid-flipper height when mesh edges intersect flipper swing arc. Remove/simplify mesh geometry in flipper zone.
- Version control: sequential version numbering with manual communication repeatedly failed before the checkout system was adopted.
Techniques Developed Here¶
- Flasher exponential decay pattern --
FlashLevel * 0.93 - 0.01with cubic function, became VPW standard - SolCallback vs SolModCallback behavior documented here
- Playfield mesh implementation gotchas -- position, naming, static rendering constraints
- POV calibration workflow for cabinet users, including coin-on-glass trick
- Anti-ball-stretch configuration -- checkbox alone is not sufficient, must enter aspect ratio
- Ramp geometry cleanup in Blender workflow documented here
- Version control checkout system adoption prompted by merge disasters here
See Also¶
- GI and Flashers -- flasher decay, SolCallback/SolModCallback
- 3D Art Pipeline -- playfield mesh, ramp cleanup
- Physics Tuning -- nFozzy angle conventions
- Best Practices -- POV calibration, version control, LUT philosophy
- Troubleshooting -- ball hover, playfield mesh misalignment