Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Built with Unity 6.5

### Added

- Drop targets can opt into Roth-compatible or finite-mass mechanical physics, including bricks, multi-target bank shots, moving reset contact, backside behavior, and reusable calibration profiles ([#536](https://github.com/freezy/VisualPinball.Engine/issues/536)).
- Make packaging functional ([#557](https://github.com/freezy/VisualPinball.Engine/pull/557))
- New threading model ([#552](https://github.com/freezy/VisualPinball.Engine/pull/552))
- Free transformation ([#500](https://github.com/freezy/VisualPinball.Engine/pull/500))
Expand Down
8 changes: 8 additions & 0 deletions VisualPinball.Unity/Assets/Physics.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions VisualPinball.Unity/Assets/Physics/Drop Target Profiles.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: c2b95ae3618f42e198695c93e407bc69, type: 3}
m_Name: Generic Sliding Blade (Provisional)
m_EditorClassIdentifier:
MechanismName: Generic sliding-blade drop target
Calibration: 0
CalibrationSource: Uncalibrated starting values for evaluation only; do not label as realistic.
Config:
EffectiveFaceMass: 0.2
MinimumFaceImpulse: 0
DeflectionKind: 0
DeflectionAxis: {x: 0, y: 0, z: -1}
DeflectionPivot: {x: 0, y: 0, z: 0}
ReferenceContactPoint: {x: 0, y: 0, z: 0}
LatchReleaseTravel: 2
LatchRelatchTravel: 1
LatchEscapeDrop: 2
RearStopTravel: 4
RearSpringFrequencyHz: 70
RearDampingRatio: 0.25
RearStopRestitution: 0.65
DropMass: 0.2
DropTravel: 52
DropSpringForce: 0.25
GuideDamping: 0.2
GuideFriction: 0.1
GuideVelocityDeadband: 0.001
DownStopRestitution: 0.1
DroppedSwitchTravel: 20
ResetDurationMs: 40
ResetEffectiveMass: 1
ResetOvershootTravel: 10
ResetSettleDelayMs: 20
RaisedSwitchTravel: 2
EnableBacksideRelease: 0
BacksideReleaseImpulse: 0

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
---
uid: drop-target-physics
title: Drop Target Physics
description: Choose and calibrate legacy, Roth-compatible, or mechanical drop-target behavior.
---

# Drop Target Physics

Drop targets provide three physics modes. Existing tables and prefabs remain on **Legacy** unless an author explicitly changes the mode.

## Choosing a mode

| Mode | Use it for | Behavior |
|---|---|---|
| **Legacy** | Existing tables and maximum compatibility | Preserves the original solid-wall hit and animation behavior. |
| **Roth Compatible** | Tables that previously used the common Roth `DTHit`/`DTBallPhysics` scripts | Uses a non-solid front sensor and offset collision wall, with the Roth mass correction, optional brick heuristic, backside threshold, and deterministic optional vertical bouncer. |
| **Mechanical** | New tables and physical calibration work | Simulates a finite-mass moving blade, rear spring and stop, latch release/relatch, vertical guide, switch crossings, and a moving reset stroke. Bricks and ball lift emerge from contact and mechanism parameters. |

Mechanical mode is the most physical model, but its generic defaults are deliberately marked **provisional**. A profile should only be marked **Measured** after it has been fitted to real-machine footage and validated against shots that were not used for fitting.

## Collider meshes

The collider component exposes three mesh slots:

- **Front Collider** remains the legacy solid face. In Roth mode it becomes the non-solid hit sensor.
- **Back Collider** represents the passive rear/body surface.
- **Collision Collider** is the dedicated offset wall in Roth mode and the moving physical face in Mechanical mode.

For Roth parity, author a separate front sensor and offset collision mesh. If Collision Collider is empty, VPE retains a solid-front fallback, but it cannot exactly reproduce the sensor-plus-offset-wall arrangement. Mechanical mode can fall back to Front Collider, though a simplified dedicated collision mesh is preferable for predictable contact and lower broad-phase cost.

## Mechanical profiles

Create a reusable profile with **Assets > Create > Pinball > Drop Target Physics Profile**. Assign it to each target built from the same mechanism. Enable the local override only for a measured per-target difference.

VPE includes **Generic Sliding Blade (Provisional)** as an explicit evaluation starting point. It is not physical calibration data and must remain labeled provisional.

The most influential parameters are:

- **Effective Face Mass**, material elasticity, and friction control the ball/target impulse and rebound.
- **Deflection Kind** selects a sliding blade or a hinged blade. Hinged axes, pivots, and reference contact points are authored in target-local VPX coordinates; hinge travel thresholds are radians, and effective face mass is defined at the reference point.
- **Latch Release Travel**, **Latch Relatch Travel**, and **Latch Escape Drop** define release versus brick timing.
- **Rear Spring Frequency**, damping, rear clearance, and stop restitution control blade recoil.
- **Drop Mass**, spring force, guide damping, and guide friction control downward escape.
- **Reset Duration**, **Reset Effective Mass**, overshoot, and settle time control contact-derived ball lifting during reset.

Scene gizmos show the latch release, rear stop, down stop, and reset overshoot for a selected Mechanical target. Inspector errors identify impossible masses, travel ordering, and switch thresholds.

## Events and game logic

The public drop-target API is unchanged:

- `Hit` fires for the first qualified face contact, including a brick.
- the dropped switch and `TargetEventsDropped` close once at the downward switch crossing;
- the raised switch and `TargetEventsRaised` open once during reset;
- setting `IsDropped = true` starts a physical forced drop;
- setting `IsDropped = false` starts the moving reset stroke.

Mechanical targets remain collidable while dropping and while re-entering the playfield. A ball resting above a resetting blade is lifted by the moving finite-mass contact solver; advanced modes do not assign a fixed vertical ball velocity.

The reset bar is modeled as a powered, prescribed trajectory. Its configured effective mass controls the ball impulse during contact, while the actuator resumes the authored trajectory on the next physics step. This intentionally represents energy supplied by the reset coil rather than an unpowered momentum-conserving collision.

## Calibration

Record front and side views with a scale marker at 240 fps or faster. Track ball center, rear blade deflection, vertical target travel, switch timing, and reset motion across controlled speeds, angles, and contact positions. Fit parameters on one set of shots and record validation error on held-out shots in the profile's **Calibration Source** field.

At minimum, document the mechanism/parts family, camera frame rate and scale, ball mass, sample count, fitted dataset, held-out dataset, and errors in post-impact velocity, peak deflection, drop timing, brick classification, and reset lift.

## Compatibility and export

The mode, third collider mesh, and profiles round-trip in VPE packages. Old packages without these fields load as Legacy, and mesh indices 0 and 1 retain their previous meaning.

VPX BIFF has no fields for VPE's mechanical target masses, latch geometry, springs, or reset actuator. VPX export therefore retains the ordinary target data but cannot preserve advanced physics settings. Keep the VPE package or Unity source as the authoritative editable copy, and use table scripts when a VPX-only distribution needs Roth-style behavior.

## Performance

Tables without Mechanical targets bypass the advanced update and contact-reduction paths. Idle latched and fully down Mechanical targets take a rest-state fast path. Moving targets update their collider transforms and the kinematic broad phase only while their pose changes. Prefer simple dedicated collision meshes, and profile a full active bank on the target platform before shipping.
6 changes: 4 additions & 2 deletions VisualPinball.Unity/Documentation~/creators-guide/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,10 @@
href: manual/mechanisms/light-groups.md
- name: Teleporters
href: manual/mechanisms/teleporters.md
- name: Drop Target Banks
href: manual/mechanisms/drop-target-banks.md
- name: Drop Target Banks
href: manual/mechanisms/drop-target-banks.md
- name: Drop Target Physics
href: manual/mechanisms/drop-target-physics.md
- name: Rotators
href: manual/mechanisms/rotators.md
- name: Score Reels
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Drop target physics validation

The advanced drop-target implementation is developed against three distinct evidence sets. They must not be conflated.

## Compatibility fixtures

`RothDropTargetGoldenData` contains reviewable inputs extracted from these local Roth/nFozzy references:

- `Dark Chaos (apophis 2025) 2.0.vbs`, SHA-256 `D5DC776B80D919E4418732F03CE55BF4586C93C24AFEBABE9E4D28C98E74DD39`;
- `Catacomb (Stern 1981) v2.0.1.vbs`, SHA-256 `5A814437D836211DA377BE4EBFD91BE242043B8F97D4897D86E32C5942DE5E6B`.

Phase 0 deliberately does not assert fixture literals against themselves. Phase 2 must run production `RothCompatible` code against every golden case. The fixture records that:

- target mass is `0.2` in VPE mass units and the actual ball mass participates in the correction;
- normal velocity uses the elastic two-mass ratio while tangent velocity is retained;
- both inspected tables ship with scripted bricking disabled;
- the synthetic brick fixture may enable the existing `30` velocity and `8` center-distance thresholds, but must remain labeled synthetic;
- Dark Chaos backside release uses a velocity threshold of `15`;
- Catacomb's vertical `TargetBouncer` is a table-level post-effect, not part of the Roth drop-target class.

## Moving-collider feasibility gate

Mechanical mode depends on moving mesh contact. Before enabling it for authored content, tests must cover triangle faces, generated edges and points, relative-velocity time of impact, transformed bounds, sustained reset contact, and the supported maximum reset speed. A failure blocks Mechanical mode; it must never fall back to assigning a fixed ball Z velocity.

## Physical calibration

No bundled profile may be called realistic until it has been fitted and validated against a measured target mechanism. Until those measurements are checked in, all Mechanical profiles are provisional. The minimum dataset records ball and target trajectories, contact location, drop/brick outcome, target parts and spring configuration, and reset motion. Fit and validation shots must be separate.

## Performance gate

Profile a deterministic scene with the same ball trajectories in Legacy and Mechanical modes. Capture at least 10,000 physics ticks after warm-up on the reference machine and report median, p95, and maximum tick time. The profiler markers `DropTarget.MechanicalUpdate`, `DropTarget.ContactReduction`, and `DropTarget.ImpactGroup` isolate mechanism integration, stable contact collection/reduction, and the fixed-iteration contact solve.

Record separate runs for 20 idle latched targets, 20 simultaneously moving targets, and the five-target/two-ball contact fixture. Mechanical mode passes the provisional rollout gate only when the complete physics tick adds less than 5% to the Legacy reference. Do not infer that result from the isolated markers or from editor-frame timing. If the gate fails, retain full collision coverage and optimize collider complexity or localized broad-phase updates rather than reducing contact correctness.

## Collision-dispatch integration check

Before promoting a Mechanical profile beyond provisional, run the deterministic five-target scene in Unity with the physics trajectory logger enabled. Use two balls arranged to reach the same target at the same global collision time, then repeat with their creation order reversed. Record the complete 1 ms ball/target state stream and event stream for both runs and require byte-identical results.

The fixture must exercise all of these dispatch handshakes:

- two physical-face candidates are collected, sorted, and solved as one target/time group;
- each grouped ball state is written back exactly once and its collision event is cleared;
- a side or back collider at the same tick follows the generic collision path exactly once;
- a sustained reset contact is marked handled and is not processed again by the generic contact loop;
- triangle-face, generated-edge, and generated-point contacts remain distinct and deterministic;
- reversing ball creation order does not change state transitions or `Hit`, dropped, or raised events.

The analytical tests cover the finite-mass group solve and total candidate ordering. They do not replace this scene-level dispatch check; attach the two trajectory logs and profiler capture to calibration evidence.
Loading
Loading