Bram Stoker's Dracula¶
Comprehensive VPW build of Williams' 1993 Bram Stoker's Dracula, from initial mod through full toolkit release. BSD is notorious for its difficulty (often considered the hardest WPC game) with lightning flippers, tight shots, and a huge flipper gap. The project features extensive work on physical trough implementation, VUK periscopes, magnet wormdrive setup, and Blender toolkit integration. Key contributors include stavcas, sixtoe, apophis79, iaakki, niwak, kevv, fluffhead, frank_enste1n, and others.
Build Notes¶
Replacing Physics Objects (Walls to Primitives)¶
Replace wall-based posts/pegs/sleeves with primitives for accurate nFozzy physics:
- Star post 1-1/16" = 32.3 VP units with rubber (0.0572 feet)
- Standard sleeve 1/2" OD = 20.6 VP units (0.0365 feet)
- Add physics prims to
dPostsanddSleevescollections - Posts/pegs use
zcol_RubberPosts, sleeves usezcol_Sleeves - Sizing calculation: 50 VP units = 1.0625 inches (pinball diameter)
Physical Trough Implementation¶
When implementing a physical trough:
- Strip old ballstack code (
cvpmBallStack) - Create balls in trough kickers at
Table_Init - Set controller switches for trough positions
- Handle drain separately from trough release
Set BSDBall1 = sw41.CreateSizedballWithMass(Ballsize/2,Ballmass)
Controller.Switch(41) = 1
gBOT = Array(BSDBall1,BSDBall2,BSDBall3,BSDBall4)
Common errors: CreateSizedBallWithMass undefined (missing kicker object), division by zero (missing CorTracker.update in timer), balls auto-firing (incorrect switch setup).
VUK Periscope Method¶
For complex ball trajectories (Asylum, wire ramp feeds):
- Create collidable primitive tube in Blender (approximately 60 VPU inner diameter)
- Flip normals inward (
Alt+Nin edit mode) - Export as OBJ, import to VPX
- Tune kicker angle, force, zlift, randomness
Square tubes are easier to model than cylinders (fewer polys). Ensure the tube does not narrow on curves. Add deflector plates at hole entrances to prevent rejections.
Playfield Dimension Correction¶
BSD table was built 0.25" too wide, propagating to Blender. Fix VPX playfield dimensions first, realign all objects, then rebuild Blender from corrected VPX export. Validates the importance of accurate playfield dimensions early in build.
Aligning Table to New Playfield Scan¶
When replacing the playfield with a new scan: lock all objects, split into layers, use playfield holes as alignment reference, create blueprint overlay in GIMP. BSD manual blueprints were inaccurate -- always prioritize scan holes over blueprint. Workflow: align rubbers, then inserts, then lights, then targets, then kickers, then ramps.
Ramp Height Measurements¶
From kevv's real BSD table measurements: big ramp top surface is flat/parallel to PF at graveyard, right ramp has flat section then steep drop then shallow drop then flat, graveyard base slants upward toward back. Standard ramp gutter depth is approximately 53 VP units (ball = 50).
Williams Lightning Flippers¶
BSD uses Williams Lightning Bolt flippers (1/8" shorter than normal 3"). Same as Fish Tales. Copied flipper setup from Fish Tales -- works perfectly. Makes game harder than normal 3" flippers. Real tables often converted to normal flippers for easier play.
Ramp Entry Bounce Fix¶
Balls bouncing at ramp entrance (vertical bounce not visible in cab/DT mode). Caused by steep entry angle (flat PF to 20-degree ramp). Fix: make entry more gradual/rounded, reduce ramp material elasticity. Test in F5 mode with camera angle to see the vertical bounce.
Ramp Material Physics¶
Left ramp too slow compared to real machine. Default zCol_Ramp friction = 0.1 but real BSD ramps are very smooth. Test friction down to 0.03 for closer feel. Also check ramp entry angle and reduce elasticity.
Slingshot Physics Refinement¶
Add control points at top/bottom of sling face, make middle section "big" (active sling zone). Prevents ball firing off top of sling. Add small walls near sling corners to prevent ball traps.
Ramp Roof Clearances¶
BSD has 3 ramp layers (PF, middle, top). Green ramp has roof where it passes under blue ramp. Top ramp approximately 150 VP units high, green ramp approximately 55-60 VP units high. Use standoffs for ramp roofs on sharp corners.
Outlane Post Adjustment¶
Outlane difficulty setting moves the post that the entire rubber wraps around. Rubber must be a "movable" primitive in Blender -- treat like slingshot rubber (separate object).
Scripting¶
FastFlips Upper Flipper Conflict¶
Tables that repurpose upper flipper memory addresses (e.g., BSD Mist ball gates) require disabling FastFlips for upper flippers:
Prevents flipper button from triggering non-flipper solenoids when FastFlips is enabled.
Magnet Wormdrive Setup¶
Magnet on wormdrive requires limit switch setup at Table_Init:
Controller.Switch(81) = 1 ' Left limit (position < 10)
Controller.Switch(83) = 1 ' Right limit (position > 490)
SetMagnetPosition(500) ' Initial position
Wormdrive has 500 steps along travel path. Strength = 1 to 3 (3 too strong, drags nearby balls). Catch ball option should be off for realistic Newton's cradle effect. Requires closing/reopening VPX between tests.
SolCallback2 Stutter Fix¶
VPX 10.8 introduced SolCallback2 to avoid stutters from FastFlips. Requires VPX 10.8.0-1904+ and VPM 3.6-862+. Timer optimization: move animations from 10ms timer to FrameTimer (-1) to prevent "catching up" stutters.
Timer Best Practices¶
Fixed-rate timers (10ms, etc.) can cause "catching up" stutter if processing takes longer than interval. Solutions: use FrameTimer (-1) for visual updates, keep fixed timers >30ms interval, or use variable-speed simulation. FrameTimer just runs once per frame without catching up. Cor.Update stays on 10ms timer (physics critical).
Flipper Trigger Masks (nFozzy)¶
Flipper physics masks must be 23 VP units from flipper swing edge. Use 11.5 radius star trigger to check clearance all the way around flipper arc. Sticky flippers = incorrect mask distance. Not well-documented in physics guide.
Flipper Primitive Tracking¶
When using flipper primitives instead of real flippers, update primitive angle in FrameTimer (not MotorSwitch or RealtimeUpdates). Track real flipper .RotZ position. Timer-based updates can cause stutter -- FrameTimer sync is better.
PlaySoundAt Requirements¶
PlaySoundAt requires an object with .x and .y properties. Ramps and walls do NOT have these properties. Use switch, lamp, trigger, or kicker instead.
Castle Lock Post Timing¶
Castle lock post must stay down approximately 300ms to release one ball but keep others locked. ROM timing is not accurate enough alone -- use manual timer in script.
Lampz 3D Insert Setup¶
Cut inserts from playfield (mask image, alpha = 1), place insert prims at height 0 (not 50), set insert text layer height to 0, import insert text as separate transparent PNG, use mass assign in Lampz for naming.
3D & Art¶
Playfield Mask Workflow (Toolkit)¶
Create two masks for toolkit inserts:
- Insert mask: Black/white, shows insert holes only (block playfield, expose inserts)
- Text mask: Shows text in inserts (semi-transparent for light bleed-through)
For covered inserts (like Dracula's face): use translucency mask on playfield material, which holds out black more than colors.
Depth Bias Management¶
When objects flicker or ball disappears, check objects at same Z height and adjust depth bias (more negative = closer to camera).
Live Adjustment
In F5 mode, press D and type plastic001.depthbias = -800 to see changes immediately. This does not work in F6 mode.
Wire Ramp Modeling¶
Wire ramp creation using parametric CAD to Blender: model in CAD with parametrics for easy adjustment, gutter depth approximately 53 VP units, bottom wires longer than top (pass under acrylic ramp). Parametric allows real-time adjustment as measurements are refined.
Polycam 3D Scanning Tips¶
- Use Lazy Susan for rotation (auto-photo mode)
- Lots of diffused daylight (not direct)
- Plain background or graph paper for contrast
- iPhone XR works well (LIDAR not required)
- 1000 photos max, quality is 1 out of 3 attempts
Object Space Normal Maps¶
Use object space normal maps (not tangent space) for easier VPX setup. Set image type to "non-color" in Blender. Bake normals from high-poly to low-poly in one step.
Texture Projection¶
For toy model texturing: use telephoto/far distance for top-down photos (avoid perspective distortion), texture projection from photos onto high-poly mesh, paint details in Substance Painter. Eliminates need to remove toys from machine.
Copy Center Scanning Quality¶
Consumer flatbed scanners are often out of focus for plastics. Copy center commercial scanners are much better -- worth paying for professional scans. Night/day difference in sharpness.
Blender Toolkit Parts Library¶
Use pinball parts library (vbousquet/pinball-parts): metal walls, wire ramps pre-optimized, standard parts accurate to spec. Works with Blender 4.1+.
Troubleshooting¶
VPX Script Editor Window Lost¶
When script editor opens off-screen after monitor changes, delete WindowPosX and WindowPosY from registry:
Alternatively: hover over VPX in taskbar, right-click editor window preview, select "Move," then press arrow keys.
Invisible Ball After Kicker¶
Ball fading/disappearing after kicking from trough: check playfield mesh depth bias, try renaming playfield_mesh to test, check apron/trough graphic depth bias, ensure drain kicker is at bottom of trough.
Stuck Ball on Ramp¶
Ball stuck between visual and physical ramp during multiball: likely misalignment between primitive and collision ramp. Ensure collision ramp matches visual placement.
Light Bleed Under Plastics¶
Check plastic depth bias and ensure bottom edges are aligned with playfield properly in Blender.
B2S DLL Registration¶
Multiple B2S DLL registry entries cause confusion. Deregister old DLLs before updating. See: https://github.com/vpinball/b2s-backglass/wiki/DeRegister-dll
Plunger Lane Sound¶
Plunger lane sounds "like ripping velcro" in VPX. Real table has a plastic ramp but sounds normal/quieter. Reduce ramp roll sound volume for the plunger lane.
Game Knowledge¶
BSD Difficulty¶
Considered one of the hardest WPC games: huge flipper gap, small lightning flippers (2-7/8"), tight shots. Asylum often ejects to outlane (ROM ball save feature exists). Backhand shots to left/right ramps are generally not possible (insufficient speed), but coffin lock backhand is possible.
VP Units Conversion¶
VP units = inches x 800 / 17. Ball diameter: 1-1/16" = 50 VP units (1.0625"). Dimension manager floors decimals -- use manual conversion for precision.