What ships as a native plugin
Every binding in the catalog is a thin layer over the same C wire core, exposed through the FFI header (clutchcall_moqt_ffi.h) that ships with the
package. The engine package gives you the Unity-facing transport surface; the
native plugin is the QUIC + MoQT implementation underneath it. The KPI strip
shows the core version currently published alongside the packages
(Wire core · FFI), and the Native targets KPI is just the row count of the
Native plugins table.
The Native plugins table has these columns:
The Native plugins button in the page header downloads the set. If you
install via UPM, the package already carries the binaries for the platforms its
matrix row marks as supported — you only place artifacts by hand when you pull
them separately, or when you vendor a single target into an existing plugin
folder.
Where each artifact goes in a Unity project
Unity decides how to import a native binary from its location and from the import settings on its.meta file. Place the file from the Artifact column
under Assets/Plugins/ in the directory for its target, then open the Plugin
Inspector and confirm the platform and CPU selection matches the ABI column:
Two rules that cause most of the support traffic:
- Set the platform on the
.meta, not just the folder. A binary left with “Any Platform” selected can be included twice, or included on a target it was not built for, and the failure surfaces only in the player build. - Keep the header next to the binary from the same release. The
clutchcall_moqt_ffi.hin the package and the binary in the Native plugins table are versioned together. See Pinning the FFI core version.
Picking the right ABI
TheABI column is the authoritative list of architectures inside each
artifact. Match it against the architecture your player is built for, not
against your development machine:
- Editor vs player. The editor loads the desktop artifact for the machine you are running on. An Apple-silicon editor needs an arm64 slice even when you only ship x86_64 players; a single-slice binary will work in one and fail in the other.
- Android. The ABIs you ship must cover the “Target Architectures” set in
Player Settings. If Player Settings includes an ABI with no matching
.sounderAssets/Plugins/Android/libs/, the store build still succeeds and the app fails on that device class only. - iOS. Device and simulator are different slices. If the artifact you were given does not list a simulator slice, build to a device.
- WebGL. There is no ABI choice; the native side is linked in by the Emscripten toolchain. The toolchain version has to match the one your Unity version ships with.
What an ABI mismatch looks like at runtime
A mismatch never shows up as a compile error. The symptoms, in order of how often they are reported:
When you hit the second row, treat it as a version problem rather than a
placement problem: re-pull both the header and the binary from the same catalog
row.
Signing and notarisation per platform
TheSigning cell on each Native plugins row records the requirement for that
target. Read the cell as the source of truth for the artifact you downloaded;
what follows is how the requirement is usually satisfied in a Unity pipeline.
- macOS. A native plugin inside an app bundle is signed as part of signing the app. If you enable the hardened runtime and notarise the build, the plugin has to carry your signature too — re-sign the bundle after Unity copies it in, then notarise the app as a whole. An unsigned or stale-signed plugin is the usual reason a notarised build launches and then fails on first connect.
- iOS. Signing is handled by Xcode as part of signing the app. Static artifacts inherit the app signature; if you were given a framework instead, it must be embedded and signed, not merely linked.
- Android. The
.sofiles are not signed individually; the APK or AAB signature covers them. Do not strip or re-compress them after the Gradle step. - Windows. Authenticode signing of the plugin is separate from signing your installer. Sign the plugin if your distribution channel checks per-file signatures.
- Linux. No platform signing step.
- WebGL. Nothing to sign; the code is linked into the wasm module and is covered by however you serve and integrity-check your build output.
Release channels and status chips
The two chips in the Package catalog table describe different things and are counted separately in the KPI strip.
What they do not tell you:
- A channel is not a compatibility contract across versions. The chip describes the release track of the row, not a promise that the next version on the same track keeps the same API surface. The number to reason about for compatibility is the version pair in the next section.
- A channel says nothing about the platform cells beside it. Channel and
the per-platform matrix are independent columns; a
stablerow can still show reduced support for an individual platform. liveis a catalog state, not a maturity level. A row can beliveon a non-stable channel. Read both chips before you pin a version into a shipping build.
live rows get an install card below the table, with the exact install
command and the row’s note. Copy the command from the card rather than typing a
package name from the table — the pkg line in the table is the package
identifier, not the full command.
The platform support matrix
The six columns afterChannel in the Package catalog table are the build
targets: Win, macOS, Linux, Android, iOS, WebGL. Each cell shows
that binding’s support for that target. The matrix is per binding; the
Native plugins table below it is per artifact. Use them together:
- Find your binding’s row and check the cell for your target platform.
- Find the matching Platform row in the Native plugins table for the artifact name, ABI, signing requirement, and size.
Pinning the FFI core version alongside the package version
There are two versions in play, and the console shows both:- the package version, in the
Versioncolumn of the Package catalog row; - the FFI core version, in the
Wire coreKPI at the top of the screen.
Wire core KPI in the same commit — in a
lockfile comment, a build note, or your own manifest — so that a later
EntryPointNotFoundException can be traced to a core bump rather than to a
placement mistake. If you vendor binaries by hand instead of installing through
UPM, take the header and every platform artifact from a single download so that
all of them carry the same core.
Related
- Telemetry — the transport-level metrics and traces the core emits
- Authentication — relay tokens and the namespace scope the transport presents on connect