Skip to content

Native outputs for player plugins - #49

Merged
freezy merged 2 commits into
masterfrom
feat/player-plugins
Oct 14, 2026
Merged

freezy merged 2 commits into
masterfrom
feat/player-plugins

Conversation

@freezy

@freezy freezy commented Oct 14, 2026

Copy link
Copy Markdown
Member

Lets player plugins, such as the B2S backglass, see every light and coil MPF drives, including lights the playfield doesn't map. Requires the plugin contracts from VisualPinball.Engine feat/player-plugins (freezy/VisualPinball.Engine#588).

Numbering: MPF's visual_pinball_engine platform passes config numbers through as opaque strings.

  • Coils: the config number, when it is a plain integer.
  • Lights: subtype light is reported as a lamp and gi as a GI string, each with its config number.
  • Everything else gets -1 rather than a guessed number: FAST, P-ROC or OPP-style addresses, and other light subtypes.

Values:

  • Lights: physical brightness 0..1, following MPF's fades.
  • Coils: on/off, from enable or pulse until disable or the end of the pulse.
  • Hardware rules: flippers, slings and pops fire from switch changes, so they're reported from there. Removing a rule, as on a tilt, releases the coil it held.

Threading: commands from the gRPC threads are timestamped and applied in order once per frame on the main thread, with no allocation per frame in steady state. Detaching drops anything still queued.

Not covered: MPF's VPE platform has no mechs or segment metadata.

Separate existing bug, not fixed here: MpfExtensions.GetLampNumbersByNameDict keys lamps by HardwareChannelColor instead of HardwareChannelNumber. Incoming fades therefore fail their lookup, and mapped MPF lamps don't light on master.

Testing: verified with a standalone harness of 105 checks (not part of this repo, which has no test project). Not yet run in Unity or against live MPF.

Implements IGamelogicNativeOutputs, so player plugins such as the B2S backglass receive every light and coil MPF drives, mapped or not.

- Numbering: coils use their MPF config number when it is a plain integer. Lights of subtype `light` are lamps and `gi` lights are GI strings, both with their config number. Hardware addresses that aren't plain integers (FAST, P-ROC, OPP styles) and other light subtypes are reported with number -1 rather than a guessed number.
- Values: lights are physical brightness 0..1, following MPF's fades. Coils are on/off, from enable or pulse until disable or the pulse's end.
- Hardware rules (flippers, slings, pops) are reported from the switch changes that fire them. Removing a rule, as on a tilt, releases what it held.
- Commands from the gRPC threads are timestamped and applied in order once per frame on the main thread, with no allocation in steady state. Detaching drops anything still queued.
@greptile-apps

greptile-apps Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 5/5

[Medium impact] The changes since the previous review appear safe to merge.

Summary

Gives player plugins MPF light and coil changes, including outputs not mapped to the playfield.

  • Player plugins receive MPF’s lamp, GI, and coil changes.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  A[MPF commands] --> C[MpfOutputModel]
  B[Switch changes] --> C
  C --> D[Main-thread Poll]
  D --> E[NativeOutputSink]
  E --> F[Player plugin]
  G[Detach listener] --> H[Clear listener references and queued outputs]
Loading

Reviews (2) · Last reviewed commit: "plugins: release the native output liste..." · Reviewed by Greptile

Comment thread Runtime/MpfGamelogicEngine.cs Resolved
The dispatch sink kept a reference to the last listener after SetNativeOutputListener(null), keeping an unloaded plugin alive until the engine was destroyed.
@freezy
freezy merged commit faa3ec1 into master Oct 14, 2026
5 checks passed
@freezy
freezy deleted the feat/player-plugins branch October 14, 2026 16:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant