Cirqus Voltaire¶
VPW lite conversion of the 1997 Bally WMS classic, featuring nFozzy physics, Fleep sounds, and smooth GI fading implementation.
Build Notes¶
Flipper Trigger Margins for nFozzy Physics¶
Flipper trigger margins must be set to 23 VP units all around (top, bottom, left, right) for nFozzy physics. The margin must be less than 25 VP units or the physics will malfunction. HayJay set all four margins to 23 as the standard configuration during initial CV VPW lite conversion.
Fleep Sound Metal Wall Hit Threshold¶
For Fleep sound implementation, the metal wall hit threshold should be set to 2 (not the default higher value). When set too high, the ball hitting metal walls produces a "crunchy" sound effect that doesn't sound right.
ROM Selection¶
Cirqus Voltaire uses ROM cv_20hc (home version with coins). This requires the parent ROM cv_14 to be present in the ROMs folder. The "hc" suffix denotes the home/coins variant.
Slingshot Threshold Tuning¶
Rothbauerw recommended lowering the slingshot threshold to 1.5 (from the default higher value) to make slings more responsive and reactive to ball contact, matching real machine behavior more closely.
Scripting¶
VPX 10.8 Opacity Bug Workaround¶
In VPX 10.8, the .opacity property on primitives/flashers does not work at runtime if the material's opacity amount is set to exactly 1.0 in the editor.
Workaround: Set the material opacity amount to 0.999 (or any value less than 1) in the VPX editor. Then .opacity can be controlled normally via script.
VR Cab Mode Visibility Fix¶
When hiding desktop-only elements, use the check:
The RenderingMode = 2 check prevents VR cab mode from incorrectly hiding elements that should be visible in VR.
GI Fading with Ramp BlendDisableLighting¶
To make plastic ramps respond to GI state changes, tie the ramp's BlendDisableLighting property to the GI level.
Formula: ramp.blenddisablelighting = factor * gilvl + base
For CV, iaakki used: ramp_right_on.blenddisablelighting = 0.5 * gilvl0 + 0.2 where gilvl0 is the right-side GI string level, giving a range of 0.2 (GI off) to 0.7 (GI on).
GI Smooth Fading Timer Implementation¶
ROM GI uses 8-step callback (callback2), which produces visible flickering. To create smooth GI fading:
- In the GI callback, only update target levels for each GI string
- Create a 16ms fading timer that interpolates current levels toward target levels
- Add an efficiency check to disable the timer when current equals target
This separates the ROM's discrete steps from the visual output, producing smooth lighting transitions. Performance note: the 16ms timer adds some CPU load.
Solenoid Callback Optimization (UseSolenoids=0)¶
Updated solenoid handling to not use core.vbs (set UseSolenoids=0). Instead of relying on core.vbs solenoid routing, use direct solenoid callback arrays. This produced noticeable performance improvements by reducing scripting overhead.
Critical: When using custom solenoid callback methods (bypassing core.vbs), FastFlips were inadvertently disabled, causing noticeable flipper lag. Niwak identified and committed a fix to the VPX codebase. Users needed the latest VPX build for the fix.
Live Debug of BlendDisableLighting Values¶
To fine-tune BlendDisableLighting values without repeatedly editing and reloading the table, use the VPX debugger. Open the debug editor during gameplay and paste commands like ramp_right_on.blenddisablelighting = 10 to see immediate visual results.
Troubleshooting¶
Post Pass Tuning via Cradle Wall Geometry¶
To fix post pass behavior without moving posts (which can break other ball paths), adjust the cradle wall geometry instead. Apophis79's technique: add or extend a wall segment near the flipper cradle area that catches the ball before it can escape around the post.
Menagerie Ball Cage Escape Prevention¶
The menagerie (green) ball would occasionally escape its cage during gameplay.
Fix: Add a wall 150 VP units above the playfield mesh and 0.2 VP units below the playfield mesh surface to contain the ball vertically. This creates a thin containment zone that prevents the ball from popping out.
Ball Stuck on Platform Fix (InRect Pattern)¶
For balls stuck on elevated platforms (like the Ringmaster platform), use an InRect check with a velocity nudge.
Pattern from Pinbot: Define a rectangular region covering the platform, check if the ball is within it for too long, then apply a small vely nudge to push it toward the drain direction.
Ball Stacking in Plunger Lane Fix¶
Multiple balls stacking in the plunger lane was caused by quick-launching the ball just before the auto-plunger activated.
Fix: Increase the size of the plunger lane switch so it detects the ball's presence earlier, preventing the auto-plunger from activating when a ball is already in the lane. Also fixed buy-in conflict where plunging added an extra player.
Plastic Ramp Trigger Placement and Pitch¶
Plastic ramp triggers were placed incorrectly, causing inconsistent ramp entry/exit detection and excessively loud ramp sounds. Fix involved repositioning the triggers to better match the ball's actual path on the ramp and adjusting the pitch of the ramp sound effects.
POV Import Overwrites Environment Settings¶
Importing a POV file in VPX overwrites more than just camera angles. It also changes: Day/Night slider, AO (ambient occlusion), SSR (screen space reflections), anti-aliasing, and other environment light settings.
Solution: Take screenshots of your POV settings before importing, or manually enter real-life measurements into the new POV system instead of importing files.
Playfield Reflection Probe with Physics Mesh¶
When a table uses a separate playfield_mesh primitive for physics, adding playfield reflections requires creating another visible primitive with the playfield image and reflection probe assigned.
Initial attempt caused the top 1/4 of the playfield texture to stretch across the entire primitive - this was a UV mapping issue requiring the texture to be remapped in Blender.
3D & Art¶
Refraction Probe Settings for Plastic Ramps¶
For plastic ramp refraction probes, use a thickness value of 8. This produces realistic light bending through the plastic material without over-distorting the image beneath the ramp.
Post Rubber Height: Visual vs Physics Separation¶
Toolkit (Blender) posts should have accurate rubber heights matching real-life measurements, but the physics primitives should keep rubber height at 25 VP units (the midpoint of the ball).
For visual/toolkit upgrades: raise the visual post rubber height to match reality, but leave the invisible physics collision primitives at 25 VP units.
Game Knowledge¶
Playfield Dimensions and VP Unit Conversion¶
Standard Bally/Williams playfield width is 20.25 inches (51.5 cm), equivalent to approximately 952 VP units.
VP unit conversion: 50 VP units = 1.0625 inches (the standard pinball ball diameter of 27mm). A standard regulation pinball ball is 1-1/16" (27mm) diameter.
Orbit Geometry Tuning from Real Machine Comparison¶
TastyWasps reported that on a real CV machine, balls exiting the right orbit do NOT hit the stand-up target, contradicting the VPX behavior.
After verification, HayJay tweaked the back wall geometry to correct the orbit flow so balls exit down the right hand side without hitting the stand-up target. Released in v1.0.5.
Flipper End Angle Impact on Ball Control¶
A 75-degree flipper end angle is approximately 5 degrees lower than most tables, making ball control significantly harder (more "slippery" flippers). TastyWasps noted that nFozzy flippers generally feel easier to control than real machines, but CV's real machine had notably difficult ball control.
Resources¶
WebP Image Format for Texture Optimization¶
WebP image format can be used for texture optimization in VPX tables, reducing file size compared to PNG while maintaining visual quality.
DMD External Frame Customization¶
Custom external DMD frames can be created by exporting the table's DMD cover images and building a matching frame texture.
Configuration: Place the frame PNG in vpinmame/dmdext/textures/frames/, add a style section to dmddevice.ini with the frame path, then add virtualdmd style = cv to the ROM-specific section (e.g., [cv_20h]) of dmddevice.ini.
Version History¶
v1.0 (initial release with nFozzy/Fleep) → v1.0.1 (VR cab fix, ball rolling sounds) → v1.0.2 (RM kick tuning, popper kickout) → v1.0.3 (plunger ball stacking fix, sling threshold 1.5) → v1.0.4 (GI fading rework by iaakki) → v1.0.5 (orbit geometry fix from real machine feedback) → v1.0.6 (outpost difficulty, standalone backglass fix) → v1.0.7 (new flipper physics standard) → v1.0.8 (solenoid callback update by apophis) → v1.0.9 (start/end angle readjustment) → v1.1.0 (RM magnet fix, duplicate function removal) → v1.1 (public release with NVRAM).