Skip to content

Earthshaker

Earthshaker is a Williams System 11 table built by VPW over 3+ years, featuring a complete Blender Toolkit pipeline with scanned playfield, complex stacked ramp systems, and the prototype Earthquake Institute moving building mechanism.

Build Notes

Playfield Dimensions and Scanning

The Earthshaker playfield measures 20.25" x 46" (standard non-widebody Williams), which translates to 952.941 x 2164.706 VP units. The original VPX file had incorrect dimensions (964 VP units wide instead of 953) -- only a ~1% error but it caused cumulative misalignment on the right side. The VPX "Dimension Manager" is famously inaccurate and should not be trusted. To verify: set width to 20.25" and confirm bumper holes render as perfect circles.

The team used a brand new CPR (Classic Playfield Reproductions) unpopulated playfield for scanning. Scanner recommendation: HP ScanJet 4670 or 4600 (flatbed-style portable scanner placed face-down on playfield). Scan settings: 600 DPI, always TIFF format (never JPG). Scan rows left-to-right with significant overlap, include wood edges. ClarkKent performed professional stitching of scan segments.

Collidable Primitive Strategy

After testing full-primitive collidables from Blender (used in Haunted House), the team reverted to VPX walls for most physics objects.

Blender collidables pros: Perfect alignment with visual meshes, reduced VPX setup work.

Blender collidables cons:

  • Very difficult to tweak during physics tuning (requires round-tripping through Blender)
  • Hard to identify ball flow issues and fill gaps for ball traps
  • Reversed normals let balls pass through (red face = passable)
  • Most physics contributors can't easily work with primitives

Decision: Keep primitive collidables for ramps (where visual-physical alignment matters most), revert everything else to VPX walls. Collidable primitives must be grouped by physics material type because VPX applies one physics material per primitive. Groups: Posts, Pins/Pegs, Rubber band middles, and Sleeves. Posts should be modeled at the final rubber diameter, not bare post diameter. Slingshot walls must remain as VPX wall objects because they trigger leaf switches.

Spiral Ramp Heights

Earthshaker has a complex stacked ramp system. Key measurements:

  • Wood sidewalls: ~50 VP units high
  • Bottom ramp sits just above plastics, nearly flush
  • Top spiral ramp on top of bottom ramp with minimal clearance (~ball diameter + small gap)
  • Ball diameter: 27mm; ramp walls ~30mm
  • Total height above bumpers: approximately 70mm (30+10+30)
  • The spiral ramp literally scrapes the pop bumper top (decal damage visible on real machines)

Principle: Get the ramp entrance heights right first since they affect physics; the descending portion matters less.

BallSize Convention

VPX scripts should use BallSize = 50 (standard). If an older script uses BallSize = 25, change it to 50 and divide affected constants by 2. The BallSize parameter is expected to be 50 in other parts of the nFozzy script.

Earthquake Institute Moving Building

The moving building was a prototype feature cut from production but scripted in the ROM (solenoid 9). Implementation details:

  • Building modeled as a Blender Toolkit movable, baked with building in UP position
  • Lightmaps from building lights dimmed proportionally as building descends (10% brightness when fully down)
  • The clear ball-guard plastic over the diverter must be hidden when the mod is active (it physically blocks the building's descent)
  • The building doesn't cast light behind itself (confirmed by reference videos)
  • Light linking in Blender 4.0 could solve the shadow issue but wasn't compatible with toolkit at the time

VLM Material Assignment

After importing a Blender Toolkit batch, VLM materials must be assigned to all baked primitives in VPX. Without them, everything appears pink.

  • Layer 0, 1, 2, 3 and playfield: VLM.bake.active material
  • Remaining objects: VLM.bake.solid
  • All VLM.Lightmaps primitives need an active material assigned
  • Materials can be imported from another VPW toolkit table as a one-time setup

Blueprint Generation

The Blender Toolkit includes a built-in blueprint generation button that creates a top-down reference image. Press the "Blueprint" button in toolkit, then find the generated image in Blender's Image Viewer dropdown (it doesn't appear automatically). Export as PNG and import into VPX as a reference layer to align VPX physics objects. Generate separate blueprints with and without ramps for different alignment tasks.

Flipper Tuning

The FlipperCradleCollision value of 2.5 has been standard for VPW tables since flipper tricks were implemented. Lowering it to 0 makes flippers snappier but adversely affects flipper tricks (tap passes, post passes). Drop catches feeling "insanely tough" was likely a VPX RC3 change rather than table-specific.

File Size and Performance

Earthshaker reached 520MB at 4K bake (vs 308MB for RCT, 251MB for TZ). Analysis:

  • 2.8M polygons total vs TZ's 1.1M
  • 2.3M of those polygons were in lightmaps alone
  • Images consumed 279MB in VPX file, 2294MB in GPU memory
  • 10 dome lights plus numerous inserts created exponentially more lightmap renders
  • Insert lights accounted for ~82% of total renders
  • Real performance offenders: COM objects, VPinMAME-to-B2S registry data path, scripting overhead
  • Reducing flasher power in Blender reduced lightmap count and file size

Solenoid Stutter Fix

Persistent micro-stutters traced to the solenoid callback method in core.vbs. Fix: use VPX native solenoid callback handling instead of core.vbs wrapping. Requires VPX 10.8.0-1904 and VPinMAME 3.6-862 or later. This was described as a dragon "chased for years" that was finally killed.

3D & Art

Plastic Tracing Workflow

Technique for creating accurate plastic meshes in Blender:

  1. Layout all plastic scans in a single image at consistent DPI (e.g., 300 PPI at 35"x35")
  2. In Blender, set the reference image to the same dimensions as the source image
  3. Trace plastic outlines using scans as background reference
  4. Create a big square outline (same size as reference image) and merge with all traced shapes
  5. Project UV to bounds -- the UV of traced shapes aligns exactly with the reference image
  6. Apply plastic modifiers, then split shapes apart

Insert Text Recreation

For playfield insert masks, recreating text from scratch using matched fonts produces sharper results than cutting from scans. For Earthshaker, "5X" text matched "Arial Black" with -50 tracking. Add a noise layer to recreated text to prevent it looking too "clean." The insert mask only needs to cut out the insert shapes with text visible -- wood holes are modeled in 3D in Blender.

Insert Text Sharpness

Insert text on playfield flashers appearing too thin can be fixed by duplicating the flasher and overlaying the copy -- this doubles the visual density. Alternative: use a VPX ramp object for insert text overlay instead of flashers for the most opaque result.

Nestmap Resolution

Key findings on optimal playfield render resolution:

  • Each object is rendered separately at its configured resolution, then packed into nestmap images (max 8K per nestmap)
  • AI upscaling (chaiNNer with models like realesrgan-x4plus-anime, UltraMix_Restore) can improve nestmap quality post-render with no FPS impact
  • VPX auto-downsizes textures if they exceed GPU memory limits
  • WebP format limits sides to 16384px max
  • Consensus: try 3000+ pixel wide playfield renders on final bakes

Apply Transformations

When baked objects appear rotated or misaligned in VPX after toolkit import, "Apply All Transformations" (Ctrl+A) in Blender fixes the axis relationship without changing visual position. Quick iteration: create a temporary collection outside VLM.Bake, move everything except test objects out, run a fast batch on just the problematic pieces.

Troubleshooting

Under-Playfield Graphics Bleed

Graphics under the playfield "bleed" through in both desktop and VR modes. Solution: place a basic six-sided oblong primitive block under the playfield. In VR this is essential. Sixtoe builds this into the cabinet model and leaves it enabled in all modes.

Z-Fighting Ball Shadows

Ball shadow primitives placed at Z=0 cause Z-fighting (flickering) with the playfield surface. Fix: adjust the Z height of all ball shadow primitives to 1.01.

Transparent Plastic Double-Face Rendering

Specific transparent plastics showed decal imagery printed on both top and bottom faces, causing blurred/doubled appearance. Root causes included misaligned lightmaps and objects imported into Blender rotated (needing "Apply All Transformations"). The transparent layer separator mask in the toolkit had duplicate material nodes that needed remapping (Niwak's fix: use Outliner > Blender File view > right-click duplicate > "Remap Users").

Zone 5 Saucer Ball Rejection

Ball sometimes passes through Zone 5 saucer without locking, especially from right flipper shots. Real machine investigation confirmed this happens on real machines too (~1 in 8 powerful shots). The deflector is intentionally split (half the upright cut away) because a full deflector causes kicked balls to deflect back into the saucer.

Development History

The build spanned 3+ years with distinct phases:

  1. Lite build (Apr-Dec 2021): bord1947 started with rubber dampeners, sixtoe added VR room/physics objects, uncle_paulie95 wired up alphanumeric DMD
  2. Scan acquisition (Nov 2022-May 2023): friscopinball arranged CPR playfield scan, ClarkKent stitched scans
  3. Blender Toolkit build (Sep 2023-Apr 2024): tomate80 modeled entire table (50-80 hours), benji084 traced plastics, redbone615 created insert masks
  4. Script and physics (Dec 2023-Apr 2024): TastyWasps handled nFozzy/Fleep scripting, apophis79 managed script integration
  5. Testing and polish (Feb-May 2024): 53+ versions before approaching release