F-14 Tomcat¶
F-14 Tomcat is a Williams table with a scripting-heavy VPW build featuring Flupper-style flasher domes, Octane-rendered wire ramps, nFozzy physics, and a themed VR room with animated F-14 models. Development involved 6+ contributors across physics, 3D art, and scripting.
Build Notes¶
nFozzy Rubber Dampening¶
The nFozzy rubber dampening system implements a precise elasticity curve. Objects are separated into two collections: aPhysicsRubberPosts and aPhysicsRubberSleeves. Sleeves have lower elasticity than posts. Bands use standard VP settings and are not part of the dampening system.
Sub dPosts_Hit(idx)
RubbersD.dampen Activeball
RubbersHit
End Sub
Sub dSleeves_Hit(idx)
SleevesD.Dampen Activeball
RubbersHit
End Sub
Flipper Calibration¶
Flipper length should be approximately 147 VP units. When changing flipper length, also adjust the endpoint primitives for trajectory correction. All flippers should use consistent end radius values (11.5). Flipper power: lower flippers 3000, upper flippers 2200.
Staged flipper support was added in VPW version 013 by Primetime5k, enabling partial flipper shots and more nuanced ball control.
Kicker Hit Height for Saucers¶
Instead of using enable/disable code for saucers, set the kicker's hit height to 8. This prevents the kicker from grabbing the ball until it has actually fallen into the saucer. Combined with properly sized playfield mesh holes (wider than 50 VP units), this is more reliable than the older velocity-checking method.
VUK Curved Ramp Technique¶
To create a smooth curved ball path for a VUK, rotate a standard VPX wire ramp on its side, align it to the desired profile, then export as a mesh/primitive. Cyberpez created the mesh by stripping the relevant section from the actual ramp object.
Blender Pivot Point¶
The pivot point for VPX meshes exported from Blender is at XYZ coordinates 0,0,0 in Blender. Setting the mesh origin to (0,0,0) ensures the pivot imports correctly into VPX without manual adjustment.
VR Room Setup¶
F14 implements a 3-way VR room switch: desktop/cabinet mode, plane VR room (with animated F-14 models by DJRobX), and minimal VR room. All VR room geometry is set non-visible when VR is off for zero performance overhead.
For VR room performance: reduce texture sizes, keep the VR room bundled with the main table, and make all VR geometry non-visible when not in VR mode. A simple inverted sphere with a texture works well for minimal rooms.
Scripting¶
Flipper Polarity / Trajectory Correction¶
The AddPt "Polarity" code controls flipper trajectory correction:
AddPt "Polarity", 0, 0, 0
AddPt "Polarity", 1, 0.05, -5
AddPt "Polarity", 2, 0.4, -5
AddPt "Polarity", 3, 0.6, -4.5
' ... continues to tip
AddPt "Polarity", 12, 1.1, 0
Position 0.4 is a shot from cradle. This tuned version drops correction faster near the tip to widen shot trajectories.
BlendDisableLighting for Collections¶
Sub DisableLightingColl(coll, DLintensity, ByVal aLvl)
for each p in coll
DisableLighting p, DLintensity, aLvl
Next
end Sub
Usage with NF Lampz callback: Lampz.Callback(110) = "DisableLightingColl ColTest, 25,"
Ball Shadow Improvements¶
BallShadow(b).X = BOT(b).X - (TableWidth/2 - BOT(b).X)/20
BallShadow(b).Y = BOT(b).Y + 10
If BOT(b).Z > 22 and BOT(b).Z < 35 Then
BallShadow(b).visible = 1
Else
BallShadow(b).visible = 0
End If
Dividing by 20 instead of 7 reduces lateral shadow offset at table edges. The Z-range 22-35 hides the shadow when the ball is in a kicker or airborne.
Flipper Coil Ramp-Up Modes¶
Two modes: (0) Static -- recommended for underpowered systems. (1) Dynamic -- better tap pass simulation, requires a fast system. VolFlip controls flipper sound volume. ReflipAngle (set to 20) determines the threshold for reflip vs full attack sounds.
Flupper FlasherFlash Timer¶
Sub FlasherFlash14_Timer()
FlashFlasher(14)
pBulbTest.BlendDisableLighting = 25 * ObjLevel(14)
End Sub
VUK Kicker Code with Animation¶
Sub sw24_hit()
Controller.Switch(24) = 1
End Sub
Sub SolTopHole(Enabled)
If Enabled Then
sw24.Kick 0,50,1.50
sw24.timerinterval = 10
sw24.timerenabled = 1
sw24.uservalue = 1
End If
End Sub
The timer sub uses a step counter (Case 0-10) to animate the kicker primitive's TransY. Sound effects should be in Case 1, not Case 0, because Case 0 may not re-trigger on subsequent kicks.
Relay-Driven GI with PWM¶
F14's GI is relay-driven (on/off). For the VPW update, the old Lampz-based GI was replaced with PWM-compatible code using SolModCallbacks.
Ramp Sound Entry/Exit Pattern¶
Sub Ramp1_Enter_Hit
If activeball.vely < 0 Then WireRampOn False
End Sub
Sub Ramp1_Enter_UnHit
If activeball.vely > 0 Then WireRampOff
End Sub
Fires "on" sound only when ball moves upward, "off" sound only when ball moves downward. Prevents false triggers.
Options Menu¶
Configurable defaults include: intro music toggle, plastic decal visibility, VR room mode, savage kicker strength, and F14 toy plane visibility.
3D & Art¶
Transparent Flasher Domes (Flupper Rig)¶
Flupper's flasher dome rig uses textures that always face the player/camera. When making domes transparent: delete the back faces so texture doesn't tile onto the rear, and the lit mesh should be slightly larger than the base mesh. A separate filament mesh inside uses BlendDisableLighting to simulate glow.
Wire Ramp Rendering with Octane¶
The F14 wire ramps were rendered using Blender with Octane, producing high-quality metallic reflections.
Global GI Technique (Giant Overhead Flasher)¶
A large overhead flasher tied to the GI circuit creates global illumination dimming. Does not interfere with player-applied LUTs (unlike LUT-based GI dimming). F14's 12 domes create significant combined flood effect.
Troubleshooting¶
LUTs in VR¶
LUTs apply to the entire VR room, not just the playfield. The global GI flasher technique is preferred for VR.
Playfield_Mesh Case Sensitivity¶
playfield_mesh is case-sensitive. Naming it Playfield_Mesh causes VPX to fall back to a flat surface. VBScript in general is not case-sensitive, making this a special case.
Wall SideImage Limitations¶
Programmatically changing .Sideimage applies the image as "world" coordinates instead of "wrap." Workarounds: multiple wall objects with visibility toggling, flasher objects, or UV-mapped primitives.
PWM UseVPMModSol=2 DOF Issues¶
UseVPMModSol = 2 causes erroneous DOF solenoid activation at startup. Switch to UseVPMModSol = 1. Diverter solenoids should be removed from DOF configs. Use MAX duration values (e.g., S5 MAX100) as safety measures.
VPX Save Corruption¶
Save corruption during crashes causes FPS drops and broken collections. Check: collections for incorrect object membership, VR room objects being rendered when hidden, playfield reflection values.
Game Knowledge¶
Crosshair Insert Correction¶
The large crosshair insert is white, not green. The green appearance comes from green rubber bulb covers on the GI bulbs underneath. When white flasher bulbs fire, they obliterate the green. This error dates back to the JP Salas VP9 version.
Resources¶
- F14 development pioneered the VPW check-in/check-out workflow system
- Version control with 6+ contributors and frequent WIP exchanges