Skip to content

Tommy (The Who's)

A very active VPW development project for this Data East classic, with extensive work on scripting, physics tuning, VLM baked lighting, VR features, and real-machine-referenced accuracy. Wylte's acquisition of a real Tommy machine was a turning point for the project's fidelity.

Build Guide

Playfield Mesh and Holes

For VUK/scoop holes causing ball suspension issues (wylte, bord):

  • Minimum subway depth should be lower than -75 (playfield is ~24 units deep, needs room for a 50-unit ball)
  • Use legacy mode for kicker settings
  • Lower the subway height at the bottom
  • Ball hanging before hitting the kicker means insufficient depth or a kicker configuration issue
  • Avoid sharp mesh edges where two meshes meet -- use shaped walls below the bevel instead

Physical Trough Implementation

When adding a physical trough (apophis79):

  • Remove all GetBalls calls, replace with a global gBOT array
  • Ensure all code references gBOT instead of BOT
  • Ball count: Tommy uses 6 balls total plus 1 captive
  • Update to the latest ball/ramp rolling scripts and physics scripts when implementing

Wire Ramp Modeling

Wire ramp texture options come in medium, high, and very high contrast versions (tomate80). Higher contrast produces a shinier appearance. Generally "very high" is preferred for a new/clean look. Ramps can be remodeled to match reference photos (gap width, slot depth, asymmetric cutouts).

Mirror Mechanism

Tommy's mirror assembly requires careful modeling (tomate80, wylte):

  • Separate mirror from frame for independent animation
  • Mirror = metal sheet with reflective sticker (not glass)
  • Frame = matte black plastic
  • Both move together for up/down, independently for impact wobble
  • Mirror bottom should be more parallel (flush from player perspective)
  • Frame only moves on hard hits; mirror moves on all hits

Bumper Sensitivity

Early Data East machines have less sensitive bumpers by design (wylte). When implementing:

  • Don't set threshold too low expecting modern sensitivity
  • Add bumper skirt animation for visual feedback
  • Adjust hit size along with sensitivity (visual primitive size vs collision size)
  • Reference real machine behavior rather than assumptions

Screw and Nut Placement

Document screw and nut placement from the real machine for 3D modeling accuracy (wylte). While a minor detail, it contributes to overall realism. Create a reference image showing all screw locations on the playfield and rails.

Table Slope and Flipper Power

When adjusting slope and flipper strength (wylte):

  • Increase both together (steeper slope = stronger flippers needed)
  • Wire ramps need friction retuning after slope/power changes
  • Bumper force may need increase to compensate for faster play
  • Slings may need falloff adjustment
  • Autoplunger power scales with slope changes
  • Min slope adjustment affects all difficulty settings

Warning

Test extensively after any slope modification -- it cascades to multiple systems.

Reference Photo Technique

For playfield and plastic reference photos (wylte):

  • Remove glare with multiple lighting setups, shoot from different positions
  • Camera settings: Low ISO (320) and slow shutter (1/50) to avoid blown highlights
  • Shoot both with phone and DSLR for options
  • Take RAW (.dng) files when possible for post-processing flexibility
  • Multiple angles of the same feature help overcome perspective distortion
  • Telephoto lens reduces distortion vs wide-angle for flat subjects

Tommy-Specific Mechanical Details

Verified details from the real machine (wylte):

  • Outlane post has 3 positions (easy/medium/hard)
  • Wire guide by skillshot was previously unmapped in VPX versions
  • Fly ball protector walls need proper collision
  • Launch lane arch wall commonly protrudes into ball path
  • Right ramp has an angled post and clear plastic at entry (difficult to model due to ramp tolerances)
  • Real table has circular rollover wires (not flat triggers)
  • Plastics have a specific hole for VUK above the upper flipper

Scripting

Fast Flips (Data East)

Tommy requires specific code to enable fast flips (wylte, sixtoe). Add to Tommy_Init:

Sub Tommy_Init
    vpminit me
    vpmFlips.FlipperSolNumber(2) = 47

This reduces flipper response from 18ms to 2ms. Solenoid 47 is specific to Data East Tommy (not the standard Williams 22).

nFozzy Flipper Setup

When implementing nFozzy flippers, line 798 must be commented out (fluffhead35). This is a common mistake that prevents flipper tricks from working. Always verify comment status of initialization code.

CoRTracker Out of Range Error

The "Out of range" error in CoRTracker is caused by a missing cor.update on a 10ms timer (apophis79). Always verify cor.update is called regularly. Also ensure all Fleep/Physics collections have "Fire events for this collection" checked and objects have hit events enabled.

Slingshot Animation Speed

Set LeftSlingShot and RightSlingShot timerinterval to 10 for proper animation speed (sixtoe). The slingshot animation derives timing from this timer property. Default may be too slow for realistic play.

GI Relay Integration with Lampz

Moving GI lights into Lampz (instead of manual subs) produces much smoother fading (apophis79). Reference the Jokerz table for implementation. Results in significantly better visual quality for GI transitions.

Slingshot Physics

Optimal slingshot correction angle: 6-7 degrees, settled on 6 after video analysis (apophis79). Slings should use _slingshot subs instead of solenoid callbacks for animation. This prevents timing issues with ROM solenoid delays. Values were matched against multiple Data East gameplay videos.

Narnia Ball Recovery

A ball location checker to catch balls that fall off the playfield (apophis79, nFozzy):

  • Monitor ball Z position continuously
  • If ball starts falling into the abyss, teleport to a useful location (e.g., left VUK)
  • Reference implementation: LOTR table
  • For testing with thrown balls: use getballs instead of gBOT array in CoRTracker update sub (test mode only)

Staged Flipper Implementation

To fix staged flipper integration with nFozzy physics (apophis79):

  1. Add LFPress = True and RFPress = True flags to flipper key down subs
  2. Set flags to False in key up subs
  3. Use flag in RightFlipper_Collide: If RFPress Then CheckLiveCatch...

This enables flipper tricks to work with staged flipper buttons.

VR Light Height for Ball Shadows

In VR, elevated lights for ball shadows cause unnatural movement when moving your head (wylte, Rawd, sixtoe). Solution: drop shadow-casting lights to playfield height via script for VR mode only:

If VRRoom > 0 Then
    ' Set all shadow-casting lights to pf height
    light.Height = 0
End If

Desktop/FS keeps lights elevated.

VR Backglass Flickering TOMMY Lights

The real Tommy backglass has TOMMY letter lights that flicker/dim based on playfield insert load (leojreimroc, wylte). Implementation:

  • Track number of lit inserts with a counter variable (increment on light on, decrement on off)
  • Timer checks each insert's intensityscale > 0 with a flag to prevent double-counting
  • Adjust TOMMY light opacity inversely: opacity = 100 + inslvl where inslvl decreases as more lights turn on
  • TOMMY lights are lamps 1, 10, 19, 28, 37 (in pairs), NOT on the GI string
  • Optional: add 2 self-blinking 455 bulbs

Performance impact is minimal when implemented efficiently.

VR Button Code for Staged Flippers

VR staged flipper button positioning can drift due to controller offset (retro27, wylte). Solution: store initial button positions as values, then reference those for any position calculations rather than reading current position. Also add proper sound triggers for upper flipper activation in VR mode.

Lane Exit Randomization

A lane drop randomizer (from Bride of Pinbot) adds variety to rail exits (wylte). Modify slightly to give more variety when returning from VUK, not just inlanes. Prevents predictable/boring returns from scoops and ramps.

Standalone VPX Compatibility

Include jsm174's script fixes for VPX Standalone compatibility (clarkkent9917). Critical for tables to work in standalone mode. Check for these updates before release.

Flipper Polarity Code

Updated flipper polarity code eliminates endpoint collision issues (wylte). This is a standard update to the nFozzy flipper implementation that should be incorporated when modernizing tables.

Physics

Flipper Bounce and Rubberizer Settings

Rubberizer 1 vs 2 (iaakki, apophis79):

  • R1: Slower micro-bounces, ball takes longer to settle. When collision < 10, increases bounce. When < 2, reverses spin. Needs tuning per table.
  • R2: Faster micro-bounces, ball settles quicker. Reverses spin for all bounces < 10. Includes random factor (harder to test).
  • Not about bounciness alone -- affects spin and settling behavior
  • Table slope 5.4-5.5 recommended for Tommy (verified with real machine owner)
  • Adjust multipliers if too bouncy (R1 has larger multipliers for small impacts)

Slope Settings

Verified Tommy slope range (from real machine owner):

Setting Degrees
Easy 4.5
Standard/good setup 5.4-5.5
Hard 5.6
VPX default 5.5-5.75 (settled on 5-6 range, default 5.75)

Rubber Types

Real table rubber condition affects physics significantly (iaakki):

  • New Titan rubbers recommended before capturing reference behavior
  • Rubber age, type (red vs standard), and condition create huge variance
  • Flipper angle changes invalidate rubberizer tuning
  • Reference: thisweekinpinball.com/pinball-flipper-rubber-comparison/
  • Black rubber has much less bounce than Titan red
  • Tilt test can measure static friction

3D & Art

Metal Ramp Materials

Enable "Metal Material" checkbox in material properties for metal ramps (sixtoe, wylte). Without this, metal ramps render as plastic/white instead of proper metallic appearance. Simple fix with dramatic visual improvement.

Insert Darkness

Green inserts on Tommy are the darkest 3D insert type despite being on the same bulb board as adjacent inserts (wylte). The plastic itself is very dark. Real machine owner ordered green LEDs specifically to compensate. Factor in plastic opacity/darkness when tuning insert appearance, not just bulb power.

Blender GI Bulb Power

Incandescent bulb power settings for Blender (tomate80, wylte, niwak):

  • #47 bulbs: Only 5% of power becomes light (47.25 mW light from 945 mW total)
  • #44 bulbs: 78.75 mW light from 1575 mW total
  • Eyeball adjustment in Blender: ~200-250 mW produces a realistic look
  • Color temperature: #44 ~2700K, #47/#86 2500-2600K
  • Spotlights: 750 mW
  • Use quadratic falloff, world lights OFF for hard shadows
  • Less light is better for shadows in an enclosed cabinet (light bounce acts like ambient)

Real-world verification photos at ISO 320, 1/50 shutter recommended for reference.

Blender Shadow Accuracy

For accurate shadows in Blender (iaakki, tomate80):

  • Shadow softness is determined by light size (bulb radius)
  • Multiple light sources in an enclosed space create light bounce = less contrast
  • Solution: use less light to preserve shadow definition
  • Turn off all world/AO/ambient lights for hard, long shadows
  • Check that elements like sling switches aren't set to height 0 (causes light to pass under)
  • Two bulbs near each other will fade the center shadow between them (realistic behavior)

VLM Integration Process

VLM integration workflow (apophis79, tomate80, wylte):

  1. Use BBB (Big Buck Bunny) table as reference for latest Lampz implementation
  2. Follow VLM helper script provided by Tomate (included in batch)
  3. Delete flashers, make GI invisible but keep for ball reflections (use HideLightHelper)
  4. Create array combining all bakemaps for room darkening (manual step)
  5. Set up movables using helper script arrays (one-time job, copy-paste for future batches)
  6. Set bloom strength to 0 for baked lighting
  7. Export VLM batch to latest stable physics version (not WIP versions)

The helper script streamlines later batches once initial setup is complete.

Cabinet and Backglass Art

High-resolution cabinet side art available (HauntFreaks, Rawd). For VR implementations:

  • Straight-on photos with no flash/reflection ideal for stitching
  • Multiple angles help cover the full cabinet
  • HauntFreaks maintains hi-res resources (side_full.png and variants)
  • Cabinet art should be cleaned up and centered properly for VR use

Troubleshooting

Bumper Sound Null Crashes

Bumper sounds giving "Null" crashes in Fleep implementation means missing or incorrect sub calls (apophis79). Verify RandomSoundBumper subs match the example table exactly. The issue is often in the sound effect call structure, not the sound files themselves.

Balls Stuck Behind Bumpers

Balls getting stuck between playfield elements and bumpers (wylte):

  • Usually caused by playfield warp in scans (real tables have slight warp)
  • Solution: turn up bumper thresholds by 1
  • Alternative: add invisible blocker posts in problem areas
  • Can occur in the gap between the top bumper and an adjacent post/wall

Left Inlane Ball Acceleration

If the left inlane accelerates the ball unnaturally (bountybob):

  • Check spin limiters/randomizers configuration
  • Verify inlane guide geometry isn't creating a physics glitch
  • May be related to rubberizer or material friction settings
  • Test with ball control to isolate the cause

Altsound 2.0 INI Compatibility

Altsound not working after the 2.0 update: old altsound.ini files from early 2.0 testing are not backwards-compatible with the release version (primetime5k). Solution: delete the old altsound.ini and let the system regenerate a fresh one. Only affects early 2.0 testers.

Software Setup

ROM Selection

tomy_400: Official ROM, more stable, fewer bugs. Blinder (fan) only comes out during Tommy MB super jackpot and wizard mode.

tomy_500: Custom ROM by Soren with scoring improvements and more blinder use. More fun/engaging but has bugs (modes not ending, endless shield).

Tip

Default to tomy_500 for casual play (more fun), provide tomy_400 as an option for competition/bug avoidance. See pinballcode.com/tommy5 for the full change list.

Playfield Sources

EBisLit maintains a playfield repository at ebislit.com with high-quality scans (apophis79, EBisLit). The Tommy playfield available there is higher resolution and less distorted than some table versions.

Best Practices

Example Table is Authority

Use the Example Table (not the guide) for code snippets (apophis79). Many small issues have been solved there that haven't made it into documentation. Example Table code is more current and reliable than written guides.

Real Machine Reference

Having real machine access enables direct measurement, material reference, lighting reference in controlled conditions, sound recording, mechanical behavior verification, and texture reference for wear patterns (wylte, tomate80). Tommy development improved dramatically once wylte acquired the real machine.

Real Table Photos for Development

When working on table projects, request top-down photos of flippers in both up and down positions from anyone with access to a real machine (apophis79). Critical reference for later development phases.

Inlane Difficulty

Default inlane post setting matters significantly (pinstratsdan, wylte):

  • Easy: too forgiving, reduces strategy
  • Hard (factory): more challenging, forces better play
  • Recommendation: default to factory/hard (const InlaneDifficulty = 1)

Players can adjust if needed, but shipping on "easy" undermines table design.

Ramp Rolling Sounds

Best reference for ramp rolling sounds: Star Wars Data East table (fluffhead35). Includes ramp roll amplification. Pull RampRoll sound logic from there rather than Goonies (which is an older implementation).

Version Naming for VLM Branches

When working on baked lighting (tomate80, wylte, apophis79):

  • Create a separate branch: "VLM branch" with version like "1.1.11 - VLM"
  • Export to latest stable release version, not WIP versions
  • Maintain parallel development: standard lighting and baked lighting versions
  • Include helper scripts in RAR file for integration reference