Hook¶
Hook (Data East 1992) is a complete VPW table build covering physics, lighting, ramp engineering, plastics, inserts, AO workflow, Fleep sounds, flasher systems, skull primitive fading, and performance optimization. A highly collaborative effort across iaakki, sixtoe, benji084, skitso, tomate80, cyberpez, sheltemke, and oqqsan.
Build Notes¶
Playfield Material Setup¶
The playfield material must be set to "active" with opacity around 0.99 for objects beneath the playfield to render correctly. Without an active material, under-playfield elements like inserts and kickers become invisible.
AO Baking Workflow¶
The Ambient Occlusion workflow renders a separate AO pass image, multiplied over the playfield image at around 80% in Photoshop/GIMP. Rendering AO at 2K resolution is sufficient since slightly fuzzy shadows help realism. The team found that baking AO into the playfield produces more consistent results than a separate flasher layer, because two alpha layers stacking produces incorrect rendering in VPX.
Fleep Sound Integration¶
Fleep integration requires assigning each collidable object to the correct sound collection by material type (metal, rubber, plastic, wire). Invisible collidable objects don't export from VPX to 3D apps, making it difficult to trace collision paths. One approach: open the table in a 3D app and move the camera through like the ball.
Arch Sounds
In Fleep sound packages, "arch" sounds are specifically for the ball hitting and rolling along the top metal arch after the plunge. Assign to the metal arch collection, not general "metal walls."
Ramp Collidable Primitives vs VPX Ramps¶
VPX native ramps allow per-section friction settings (e.g., 0 at entrance, 0.3 at top), critical for fine-tuning. For ramps that barely accept the ball (like Hook's main ramp), the VPX ramp approach with per-section friction is preferred despite geometry approximation.
Solenoid Callback Mapping¶
When the manual doesn't list flasher solenoid numbers, circuit diagrams are the primary reference. Lamp numbers above the matrix range in scripts are arbitrary assignments by previous authors. Use vpmTimer.PulseSw <number> to trigger switch events for testing.
Falloff Power for Ball Reflections¶
Falloff power directly controls ball reflection strength. For inserts with low intensity (~5), use falloff power 2-3. For brighter lamps (intensity ~50), use falloff power 1 or less.
Scripting¶
Skull Primitive Fading¶
For translucent objects like the Hook skull, duplicate the primitive at slightly smaller scale inside the original. The inner primitive uses higher DL values. A timer-driven fading function uses cubic easing (flashLevel^3) to smoothly fade both primitives' BlendDisableLighting. Incorporate the GI level variable to prevent apparent size changes with GI state.
Custom Dampener for Plastic Collisions¶
For lane guides with plastic walls, create a custom Dampener that copies rubber coefficients but scales them down (e.g., 95%). Gives more realistic bounce off plastic surfaces.
Ramp Speed Propulsion Hack¶
When ramp geometry prevents completing a shot at realistic flipper strength, add a small speed propulsion at a trigger point. Check if VelY is within a range and apply a multiplier (e.g., 1.15x) capped at max speed. Avoids changing flipper strength globally.
FadeDisableLighting Pattern¶
Parameters: lamp number, primitive, LIT DL value, UNLIT DL value. Actual lit value is LIT + UNLIT (additive). Must not set FadingLevel to 0 or 1 prematurely.
GI-Driven Ramp DL Fading¶
Minimum DL of 0.03 when GI is off (ramp shape remains visible), ramps up to 0.15 when GI is fully on.
Diverter Animation¶
Uses two separate timer subs (DivOpen/DivClose) rotating a primitive by steps (e.g., 9 degrees per tick). Closing is delayed using vpmTimer.addtimer 1500, "DiverterTimer.enabled = 1'".
Warning
Timer interval matters critically: changing from 10 to 100 makes the animation appear as a slideshow.
3D & Art¶
Insert Cutout Edge Overlap¶
Insert cutout edges should overlap slightly into the playfield image to prevent visible seams. Playfield alpha mask value (typically 0.99 opacity) controls insert light bleed-through.
Skitso-Style 3D Inserts¶
Created by editing the playfield image around insert areas for a dimensional appearance. Quality depends heavily on playfield image resolution.
UV Map Quick Fix¶
For primitives with incorrectly mapped faces, select the bad faces in the UV editor and drag them outside the texture area to a 40% opaque gray region.
Troubleshooting¶
Ramp Roof Gap¶
When a ramp has a "roof" primitive, the gap must exceed ball diameter (50 units). A 45-unit gap causes the ball to move as if through glue. Roof friction should never be 1.
VPX Lamp Fading Speed¶
Fading speed is linked to intensity. Higher intensity lamps fade more slowly. 1990s-era inserts should fade slowly like incandescent bulbs.
Duplicate Rubber Objects¶
Duplicated slingshot rubbers on different layers silently break sound effects. The duplicates lack collection assignments, so VPX hits them first without triggering sounds.
Material "Active" Flag¶
Non-active materials cause primitives to not respond to BlendDisableLighting changes from GI scripts. Setting back to active restores correct DL behavior.
Triggers on Ramp Surfaces¶
A trigger's center point must be within the ramp boundaries when its surface is assigned to that ramp. Otherwise it takes height from the playfield instead.
Light Clipping from GI Overlap¶
GI lights with very high intensity that overlap cause additive clipping, turning areas black. Use small falloff areas with high falloff strength rather than high intensity.
Game Knowledge¶
Data East ROM Volume¶
Press 7 to enter audits, continue pressing 7 until "Expand Adjustments" appears, press 1 to change to Yes, then continue to "Volume Adjustment." Alternative: VPinMAME hidden menu via tilde (~).
EOS Return Values by Era¶
EOSReturn values: 0.055 for EMs, 0.045 for late 70s to mid-80s, 0.035 for mid-80s to early 90s, 0.025 for mid-90s+.
Resources¶
Performance Tips¶
- Timer interval -1 = "once per frame" (not every millisecond)
- Moving cor.update from 1ms timer to frametimer recovered 20-30 fps
- Disable reflections on non-visible objects to recover 20-30 FPS
- Remove unused full-res images to save 50MB+ per image
- F11 shows script performance metrics
- Stop major changes after Release Candidate to prevent regression