Skip to content

Jokerz!

Jokerz! (Williams 1988) is a premium VPW table build based on the jpsalas VPX table, featuring a full lifecycle from early Blender modeling through release and post-release patches. The build covers 3D modeling, physics tuning, GI systems, flasher implementation, ramp mechanics, and a unique raising center ramp mechanism.

Build Notes

Playfield Dimensions and Scanning

The playfield was scanned from a hard top overlay ($350, resellable for $200-250) at 20.25"x42" at 150dpi. The scan revealed that the previously used redrawn playfield had alignment issues -- top and bottom aligned but middle sections were off. Working with scanned playfields is significantly easier than redraws because everything matches when aligning Blender models.

The playfield needed to be extended at the top because the center ramp passes behind the backwall in the real machine. To do this: increase the table height in "Dimensions and Slope," then add blank/black space to the top of the PF image. The PF image aspect ratio must exactly match the VPX playfield aspect ratio.

nFozzy Physics Setup

For late 1980s tables (Jokerz, 1988), use era-appropriate values: gravity consistency 0.97, gameplay difficulty 56, min/max slope 6/7 or 6/6. Right flipper angles must be the negative values of left flipper angles (needed for flipper tricks code). Real Jokerz flipper angles are less dramatic than typical pinball (~75-80 degrees), keeping shot aiming harder.

Zero Physics Materials

If imported physics materials (zCol objects) show zero values, they need to be reimported. VPX can silently drop material values during copy operations. Use F11 dotted ball to visualize ball spin for debugging.

Development Workflow

No source control (VPX files are binary blobs). Contributors "claim" the file by announcing they're working on it. Files shared via Google Drive/Dropbox. Standard naming: TableName_VPW_001, incrementing per version with changelogs.

Playfield Mesh

A playfield mesh (PF mesh) is critical for correct lighting. Without it, the playfield appears washed out. Adding a PF mesh with disable_lighting values between 0.75 and 1.0 dramatically improves the look, restoring highlights under plastics.

VPX Collisions and Normals

VPX collisions only happen when the ball hits a face with an outward-facing normal. The ball passes through the backface. If an object needs to be hit from all sides, the mesh needs thickness with all normals facing outward.

Scripting

Raising Center Ramp

The center ramp mechanism: switch 52 is "RAMP RAISE", solenoid 15 activates the ramp motor, switch 15 is "RAMP IS UP", switch 16 is "RAMP IS DOWN". The motor is a one-way stepper on a cantilever. The VPX script must model the motor as continuously running while enabled, with switches at top and bottom telling the ROM the position. A raising ramp can be implemented using a series of VPX ramps that become collidable in sequence.

GI Fading

Avoid setting GI lamp states directly in the SolGI sub -- all swaps and fades should happen through Lampz and the GIUpdates sub. A "nudge" artifact at the end of GI fade was caused by forcing opacity to fade between 0.25-1 instead of 0-1.

Flasher Dome Implementation

Requires code in three places: where the flasher is set visible, where opacity and speed are affected, and where flashers are set non-visible. For Jokerz, a custom "ramp up" code simulates slow filament heating. Dome color changes require: set color in script, create RGB values, color-shift base/lit textures, and add a new color entry in definitions.

Flasher Brightness Balancing

FlasherX.opacity = (100 - 30*gilvl) * ObjLevel(nr)

Max opacity is 70 when GI is ON and 100 when GI is OFF, preventing blowout when all flashers fire simultaneously.

Ball Brightness and GI

Ball brightness must be connected to GI level. Add ball brightness variable initialization, update GI brightness numbers, and add logic to the GI update sub.

Multi-Ball Drain Fix

If balls fight each other in the drain saucer at end-of-ball, add a delay (e.g., 100ms) before kicking the ball out. Solved in LOTR and applied to Jokerz.

KeyDown/KeyUp Ordering

The vpmKeyDown(keycode) / vpmKeyUp(keycode) line must be the LAST line in the sub, not in the middle. Having it in the middle can cause button animations to not work.

Desktop vs Cabinet Mode

The Not operator doesn't work on non-boolean VBScript variables. If Not DesktopMode fails when DesktopMode is an integer. Fix: use If cabinetmode = 1 Then.

3D & Art

Blender OBJ Import Settings

For VPX primitives: X size 1000, Y size 1000, Z size 1000, RotX 90, RotY 180. Normals must point outward for collidable primitives.

Playfield Rendering

Rendered textures should be neutral/flat -- contrast/brightness adjustments should be done in VPX using LUTs, not baked into the render. Blown-out whites cannot be recovered. For blackening playfield holes/inserts for rendering: manually black out all holes and inserts so the render comes out clean.

Bumper Cap Baking

Bake the cap in "off" state (no internal bulb), then light the internal bulb separately for refractions only. Subtract off-state from lit version to get an alpha mask that can overlay the off primitive. Allows changing bumper color via script.

Flasher Texture Baking

Ensure you're creating a light layer (bright on dark background), not a shadow layer (dark on bright background). If the baked image appears very dark in the image viewer, it's likely a shadow layer.

Exporting Individual Primitives

Click on the prim, use "export" in the option menu. This preserves original coordinates, unlike exporting the whole layer which converts to VPX coords (all zero positions, size 1).

Troubleshooting

Material "Active" Checkbox

If a primitive with dynamic materials stops working, check that the material's "active" checkbox is enabled and opacity is set to 1.

Ramp Switches at Wrong Height

VPX ramp switches positioned too high will never trigger. If rollovers aren't activating, check their Z height.

VPX Tilt Threshold Corruption

If a table tilts and the user quits/crashes, VPX saves the threshold value (set to 100 during tilt) and it persists. Fix: redownload or reset values. Prevention: set all thresholds at Table_Init.

Ball Sinking at Flipper

Ball appearing to sink into the playfield at the flipper is the ball falling into a primitive playfield mesh. Fix: add a wall at -0.02 under the primitive near flippers.

Texture Alpha Flickering

Edges of transparent plastics can flash black during GI transitions. Caused by alpha mask issues. Fix: resave textures using GIMP (not Photoshop), adjust alpha mask value to 20 (170 is too aggressive).

Game Knowledge

Sound System

Jokerz uses a custom System 11 sound board with stereo capability (unique to this game). VPinMAME doesn't support this and runs it in mono.

Fleep Sound Compatibility

Pinbot recordings cover coil assemblies identical to Jokerz, Taxi, Cyclone, and many other System 11A/B tables. Motor sounds need to be fabricated.

PWM Update

PWM (VPM 3.6) update for v1.2.1+ required commenting out vpmNudge.TiltObj for slings and bumpers to work with new PWM support.

Resources

  • Monitor refresh rate significantly affects physics repeatability (144Hz >> 60Hz for flipper tricks)
  • VPX resolution can be set via registry: HKEY_CURRENT_USER\SOFTWARE\Visual Pinball\VP10\Player
  • Full ROM reset: delete nvram, launch, quit, launch again, wait for attract, quit, exit VPX, then play
  • VPinMAME "Skip startup test" checkbox suppresses splash screen despite poor naming