Austin Powers¶
Deep technical VPW build of Stern's 2001 Austin Powers table, featuring extensive VPX modding techniques including custom insert systems, Flupper flasher integration, nFozzy physics with performance compensation, and photogrammetry-captured toys. Development spanned August through November 2020 with contributions from iaakki, Benji, sixtoe, tomate80, djrobx, and others.
Build Notes¶
Playfield Rework from Low-Quality Source¶
The original Austin Powers playfield was created from vectors and random bitmaps rather than proper scans. Stern's original print quality was very poor (~50dpi equivalent). The team's approach:
- Used Marco Specialties reference images for warp adjustment
- EBisLit provided actual playfield photos/stitches later, confirming the real print quality was indeed low
- Decision: create an improved version "in the spirit of the original" rather than authentic reproduction
- Desaturated colors and added proper shadows for depth
- Final hybrid combined EBisLit scan sectors for natural wood grain with original vector work for sharper character graphics
Key insight: For Stern 2000s tables (LOTR, Ripley's, Austin Powers), remastering graphics to higher quality than the source is better than authentic reproduction of low-quality printing.
Flupper Flasher System Integration¶
Flupper Domes 2.2 flasher system was implemented with a custom dual-layer approach:
- Kept Flupper dome flashers for precision hotspots
- Added second "objbloom" flasher set for wide area effect
- Introduced 3 brightness levels at heights 50, 100, 200 for bumper flashers
- Everything adjustable from script for easy tuning
Hotspot intensity was reduced from 1.0 to 0.1 after testing. Flashers can be tied to GI state for automatic dimming. The result is flashers that light the entire table with proper falloff, not just localized circles.
Ramp Physics Tuning¶
Left ramp was modeled too steep at entrance -- 80% of shots failed. Reducing ramp friction from 0.3 to 0.2 solved the issue without remodeling.
Right ramp was discovered to be twice as steep as the real machine, with different ramp segments having different friction values (some at 0.8, essentially "velcro"). The unified solution:
- All ramp sections use the same material (0.2 friction)
- Adjustable globally via material settings
- Design principle: ramp should require momentum from proper flipper technique, but if the ball reaches the "point of no return" it should complete
Stand-Up Target "Kick Back" Physics¶
The 500-6138-04 stand-up targets around the Time Machine ramp were implemented using wrd1972's Funhouse technique with randomized Z-velocity multipliers (0.7 to 1.55) for varied ball response. Targets now bounce the ball back realistically with visual animation syncing with physics impact.
Cabinet-Friendly Sidewalls¶
A CabinetMode script option hides desktop rails (which don't align with screen edges) and scales side panels 2x taller for improved depth illusion. VR compatibility uses a three-mode check: 0=Desktop, 1=Cabinet, 2=VR.
Time Machine Ramp Hump¶
Initially assumed to be an FP/VPX error, reference photos confirmed the ramp hump is authentic to the real machine. As djrobx noted: "I had no idea the ramp bump was real." The feature was poorly executed in the real machine, so it looks wrong even when modeled correctly.
Scripting¶
VBScript Sub Name Collision Bug¶
Critical Integration Issue
VPX doesn't throw errors for duplicate Sub names -- the last definition silently wins.
When integrating nFozzy physics, Fleep sounds, or any modular code, duplicate sub names cause silent failures:
' Sound code defined first:
Sub LeftFlipper_Collide(parm)
PlaySound "fx_rubber_flipper", 0, parm / 10, -0.1, 0.15
End Sub
' nFozzy physics code defined later (OVERWRITES sound code):
Sub LeftFlipper_Collide(parm)
CheckDampen Activeball, LeftFlipper, parm
CheckLiveCatch Activeball, LeftFlipper, LFCount, parm
End Sub
Fix: Combine both into a single sub, or rename the duplicate to remove the underscore.
Live Catch with Performance Compensation¶
nFozzy live catch has an 8ms timing window. On slower PCs, script execution lag makes this window impossible to hit. iaakki developed a dynamic compensation system:
Const LiveCatch = 16 ' Expanded from 8ms base
Sub CheckLiveCatch(ball, Flipper, FCount, parm)
LiveCatchSubDelay = (GameTime - FCount) + LiveCatch
If GameTime - FCount < LiveCatchSubDelay Then
LiveCatchBounce = Abs((Gametime - FCount) - (LiveCatchSubDelay/2))
If LiveCatchBounce < (LiveCatchSubDelay/4) Then LiveCatchBounce = 0
If ball.velx * Dir > 0 Then ball.velx = 0
ball.vely = LiveCatchBounce * 2
ball.angmomx = 0 : ball.angmomy = 0 : ball.angmomz = 0
End If
End Sub
Result: perfect catch in 8ms center window (zero bounce), partial catch with small bounce in 16ms total window, adapts to PC performance automatically.
Insert Material Configuration (FadingDL)¶
Insert lighting used FadingDL function with specific configuration:
- Insert off tray blocks light completely when bulb is off
- Insert on tray allows light transmission through texture
- Bulb height sweet spot at -3 (range -6 to -1)
- Both on/off textures need contrast reduction
- Blue bulb added to purple inserts for proper hue
Ball Drop Sound Implementation¶
Ball drop sounds added to the RollingUpdate sub with Z velocity threshold (< -1), height range 28-55, volume scaled by ABS(velocity)/17, and 3 random drop sound variants for variety.
Flipper Nudge / Flip Fanning¶
Rapidly flipping the opposite flipper while the ball rests on one flipper creates subtle vibration that slows the ball. Implementation uses velocity divisor of 1.7 and must iterate through ALL balls (BOT array), not just activeball -- the original using activeball caused velocity swapping in multiball.
Timer Consolidation for Performance¶
Multiple separate timers impact VR performance. Consolidating into a single FrameTimer reduces overhead and is critical for VR where every performance bit helps.
GI-Linked Primitive Brightness¶
Ramp primitives dim when GI turns off via BlendDisableLighting values: 0.2 (GI on, bright) and -0.1 (GI off, dim but not black). Same technique used for cannon, metal ramps, and decorative primitives.
3D & Art¶
Photogrammetry Workflow for Small Objects¶
The Mr. Bigglesworth cat figurine was captured using iOS photogrammetry with the Qclone app ($15 for export):
- Print grid mat OR display grid on iPad screen, place object on it
- App creates sphere grid showing required capture angles
- Capture 360-degree photos following grid prompts
- Flip object, repeat capture from opposite side
- App merges both capture sets automatically
Best practices: object must remain stationary, even shadowless lighting, ~30-40 photos minimum per side, keep camera distance consistent.
Blender to VPX Import - Pivot Point Issues¶
Pivot point often wrong when importing OBJ to VPX, breaking animations and positioning. For insert trays (Flupper style), pivot should be at the TOP surface so Z-scale adjustments don't require repositioning. Use different handle shapes (square for off tray, hash for on tray) to enable easy selection in the editor.
Metal Material Configuration¶
Round-tripping geometry (export VPX wall to 3D app, import as primitive) improves rendering even with the same VPX material applied. Beveled/rounded edges create subtle specular highlights versus the harsh lines of sharp edges, making metal objects look significantly more realistic.
Side Panel Texture Upscaling¶
tomate80 created high-resolution side panel textures by redrawing all flowers as vectors in Photoshop for clean edges, with gaussian blur applied to the background for depth. A script option toggles between flower panels and original metallic panels.
VR¶
Ramp Texture Issues with Pre-Baked Lighting¶
Benji's rendered ramp textures with baked lighting look fantastic in cabinet mode but wrong in VR where the POV changes constantly. Pre-baked highlights appear to "float" incorrectly. Solution: provide two texture options -- full rendered for cabinet mode, plain transparent (diffuse only) for VR mode.
VR-Specific Issues Checklist¶
Common VR issues identified by sixtoe:
- Geometry: Lights/flashers sticking out of cabinet, primitives not flush, missing objects not visible in desktop
- Lighting: Lights need trimming to table boundaries, some need conversion to flashers with angle adjustment
- Rendering: Depth bias much more sensitive, baked reflections look wrong, viewport-based effects only work from fixed POV
Troubleshooting¶
Ball Stuck Under Ramps¶
Missing rail/guide at ramp edge. Solution: add a collidable rail primitive along the ramp entrance curve. Check reference photos for ALL rail/guide hardware -- VR especially exposes missing collision geometry.
AO Shadow Layer Blocking Holes¶
AmbientOcclusionShadow flasher rendered solid black at hole locations. Fix: edit AO shadow texture to erase the area where holes are located. AO is a dark overlay applied to the entire playfield; if not cut out at holes, it blocks visibility of 3D elements beneath.
Primitive_Hit Event Not Triggering¶
Stand-up target hit events fired inconsistently. Moving the primitive position slightly resolved the issue. Likely floating point precision or collision mesh complexity. Moving an object a few VPU often resolves hit detection edge cases.
Insert Text Blocking Light¶
"VIRTUCON" insert barely visible when lit because text overlay was completely opaque. Fix: make text layer semi-transparent (~30-50% light transmission) in the insert text texture file.
Resources¶
- FlupperDomes2.2.vpx - Contains instructions/template for flasher system
- BallDropFX.rar - Ball drop sound WAV files
- PinAffinity - CPU affinity management tool: http://mjrnet.org/pinscape/PinAffinity.html
- Qclone - iOS photogrammetry app for small object capture
- 3DF Zephyr - Alternative photogrammetry software for processing photos