Tales from the Crypt (Data East 1993)¶
Landmark VPW build that invented the three-layer insert technique, the GI on/off doubled primitive system, and RTX ball shadows. The most technically foundational table in VPW history, establishing patterns used across dozens of subsequent builds.
Build Story¶
TFTC was built by flupper1 (3D/inserts), iaakki (scripting/lighting), sixtoe (physics/VR), wylte (RTX shadows/optimization), g5k (textures/compression), and apophis79 (physics). The table went through RC1-RC3 before final release. TFTC established many of the techniques that became VPW standards: the three-layer insert system, doubled primitives for GI fading, per-material fade curves, and the RTX ball shadow system.
Table-Specific Details¶
Mechanisms & Hardware¶
- 2-stage Data East flippers: The upper flipper is intentionally weaker than the lower, protecting drop targets and upper playfield mechanisms. Set different flipper strength/elasticity values -- upper max velocity should be ~70-80% of lower.
- VUK implementation: Two approaches tested: trigger + ball.velz assignment (simpler) and kicker object (more reliable capture/release). Ball getting stuck on geometry ledge near VUK entrance was a recurring issue -- ensure the kicker is positioned below nearby primitive geometry.
Art & Visuals¶
- Three-layer insert technique (invented here): OFF layer (DB=1000, DL=1), ON layer (DB=1100, DL=0, controlled via BlendDisableLighting), BULB layer (DB=1200, DL=1, DisableLightingFromBelow=1, Z=-3). The VPX light is purely for ball reflection. This became the standard VPW insert system documented in the insert lighting guide.
- Insert ON color values: Never use pure RGB. RGB(255,32,0) instead of RGB(255,0,0) so DisableLighting increases produce warm highlights. Red intensity lower than other colors (bleeds through more); blue needs higher intensity.
- Normal maps on insert trays: Must use tangent space, not object space. Object space breaks in VR. See insert normal maps.
- GI on/off doubled primitive system (invented here): ON primitives (Layer 7, DB=0) and OFF primitives (Layer 9, DB=30), both with static rendering unchecked. Script toggles visibility. Each physical object has two copies with different baked lighting. See GI on/off fading.
- Per-material GI fade curves (invented here): Cabinet/wood:
aLvl^5, Plastics:aLvl^3, Metal:aLvl^2, Bulb glass:aLvl^0.5. Tuned against real machine GI dimming. See per-material fade curves. - Playfield GI overlay: GI-OFF image as default playfield, additive flasher on top with the difference image. Single PF texture, smooth fading via flasher opacity.
- DL=1 for all baked primitives: Set DisableLighting=1 on all primitives using baked textures. Without it, VPX's built-in lights wash out the baked highlights and shadows.
- 6K playfield resolution: Render at 6K to preserve insert text edge sharpness, downscale to 4K for release.
- WEBP compression: Converting PNG to WEBP significantly reduced table file size (discussion referenced ~150MB after conversion). Keep normal maps and alpha masks as PNG -- WEBP lossy compression introduces artifacts on precision data.
Physics & Gameplay¶
- RTX ball shadow system (invented here): Script-driven flasher manipulation -- not related to GPU ray tracing. For each ball, shadow flashers positioned based on GI light locations. Opacity inversely proportional to ball-light distance. Multiple shadows per ball. See GI ball shadows.
- RTX shadow distance optimization: Replaced expensive
(x^2+y^2)^0.5with fast approximation1/max(abs(x),abs(y))for ~5% script execution reduction. - RTX shadows unplayable in VR: The per-frame flasher manipulation is too expensive for VR's dual-render requirement. Default to disabled in VR mode.
- GetBalls removal from update loop: Calling
GetBallsevery frame was expensive. Fix: store in globalgBOT, update only on ball creation/destruction. See ball tracking. - InRect for switch detection: Replace inconsistent VPX trigger hit/unhit events with manual rectangular bounds checking in the update loop.
- Ball shadow limiter: Max 3 balls for RTX shadows during multiball. Skip shadows for balls under the apron via InRect bounds check.
- Division-by-zero in nFozzy: Same flipper trigger fix as documented across multiple tables.
Known Issues¶
- Doubled primitive fading limitation: The ON/OFF pair can only show one fading transition at a time. Cannot simultaneously fade both GI and flasher illumination on the same primitive.
- VR HDR blue hue: Color space mismatch between HDR images and VPX's VR renderer. Adjust white balance before import.
- Flasher bloom line artifacts: Flasher edges aligned with screen-space pixel boundaries produce bright lines. Small Y offset (1-2 units) eliminates it.
Techniques Developed Here¶
- Three-layer insert technique -- foundational VPW insert system
- GI on/off doubled primitives -- standard pre-toolkit GI approach
- Per-material fade curves for realistic GI dimming
- RTX ball shadow system -- script-driven dynamic shadows
- GetBalls optimization via gBOT pattern
- WEBP texture compression for VPX tables
See Also¶
- Insert Lighting -- three-layer technique, color management
- GI and Flashers -- doubled primitives, fade curves, RTX shadows
- VBScript Patterns -- gBOT pattern, timer management