L3S DRM Developer Guide
Upgrade Guide: Version 2.0.X → 3.0.0
This guide walks you through upgrading an existing L3DRM 2.0.X integration to 3.0.0. The headline changes are formulas (server-delivered calculations, now the recommended protection) and online-only activation. Your existing builder setup, GetAuthValue() calls and file hashes keep working unchanged.
Step 1: Update Include Files, Tools & Gauge Files
Replace your existing include folder with the one from the 3.0.0 release.
Replace the ModuleDrmGauge.html, .js and .css files in your aircraft's instrument folder with the versions from the html folder of the release.
Important: After replacing
ModuleDrmGauge.html, re-edit the<script>tag at the end of the file: theimport-scriptpath anddata-expected-product-nameattributes must again match your aircraft.
Step 2: Link the Library Matching Your MSFS SDK & Limit Exports
Since 2.0.7 the DRM library ships once per MSFS SDK:
DRMCore2_FS20.a/DRMCore2_FS20_debug.afor modules built with the MSFS 2020 SDKDRMCore2_FS24.a/DRMCore2_FS24_debug.afor modules built with the MSFS 2024 SDK
If you still link the single library from an older release, change Linker → Input → Additional Dependencies to the library matching the SDK (platform toolset) of your module. See Setting Up Visual Studio.
Then limit the exports of your module. The MSFS SDK links with --export-dynamic, which exports about 1,800 internal functions. Add --no-export-dynamic plus one --export= per gauge callback to Linker → Command Line → Additional Options, in every configuration:
--no-export-dynamic --export=MyGauge_gauge_callback --export=MyGauge_mouse_callback %(AdditionalOptions)List every callback the sim calls (for example _gauge_init, _gauge_draw, _gauge_kill for the MSFS 2024 gauge API); a missing one makes that gauge fail to load. See Linker Export Flags.
Step 3: Remove Local WASM Signing
3.0.0 no longer verifies an embedded signature in your .wasm, and WasmSigner.exe is no longer shipped.
- Remove the
WasmSignerstep from your post-build script and deleteWasmSigner.exefrom yourscriptsfolder. Keepwasm-opt. - Remove any
.requireLocalWasmSigning(...)call from your builder. It is deprecated and ignored (and produces a deprecation warning). RemoveVerifySignature()calls too; it does nothing. - Keep
.wasmPath(...): the server checks the hash of your.wasmat activation, like the files added withaddFileHash().
wasmPath is required in key mode: with
keyless(false), when the Client API key has "require hash" on (the default), activation now fails withAUTHZ_006if no.wasmhash is sent. Hashes of other files added withaddFileHash()no longer count on their own. Check thatwasmPath()points at the.wasmyou actually ship; a Release log line warns when it is missing.
Error codes TMPR_001 and TMPR_002 are no longer used.
Step 4: Activation Is Online-Only
In 3.0.0 the aircraft activates against the DRM server every time it is loaded. There is no offline or cached activation any more. If the network request fails, the module retries 3 times (after 10, 30 and 60 seconds) and then reports the error through onError.
- Tell your customers that the aircraft needs an internet connection when it is loaded.
- Keep unlocking your aircraft only in
DrmSuccessEvent(); no code change is needed.
Step 5: Protect Calculations with Formulas (New, Recommended)
A formula is a calculation you define in the Formulas tab of the DRM Portal (keys start with VM_). It is delivered encrypted after activation and evaluated by your aircraft, so the calculation itself is not in your .wasm. Formulas are stronger than GetAuthValue(), which returns a whole value, and than GetAuthMultiplier().
Migration steps:
- Pick calculations that your aircraft cannot work without (thrust, fuel flow, gauge scaling, lookup tables) and create a formula for each in the Formulas tab. Put a whole calculation into one formula.
- Click Download C++ header and add
L3DRM_Formulas.hto your project. - Replace the C++ calculation with the generated wrapper and a degraded fallback.
- Where you used
GetAuthMultiplier()orGetAuthValue()inside a calculation, move that calculation into a formula. KeepGetAuthValue()for configuration values and strings.
Before (2.0.X): calculation in C++
double ff = (throttle * 0.82 + rpm * 0.0031) * DRMPublish::GetAuthMultiplier();After (3.0.0): formula VM_FUEL_FLOW_R1 on the DRM Portal
#include "L3DRM_Formulas.h"
double ff = Formula_FUEL_FLOW_R1(throttle, rpm, 0.0); // 0.0 = degraded fallbackFallback: use a degraded fallback, never the correct value. The fallback is visible in your
.wasmand is what runs without activation.
See Formulas on the C++ Integration page (readiness checks, DRM_EVAL, diagnostics) and the Formula Reference for what a formula can use.
Step 6: Check Your Integration
- Call
DRMPublish::Shutdown()inPANEL_SERVICE_PRE_KILL(MSFS 2024 gauge API:_gauge_kill), once the last gauge of your module unloads. - Call an
AssureAuthenticatedvariant in code that only runs after activation, for example after drawing a gauge that is blocked until activation. Use a different variant (1-5) in each place. See AssureAuthenticated Checks. - The builder callback for failures is
onError.onSuccessreceives the expiry, the username and the Client API key statusvStatus, an enum (DRMvStatus_Active,DRMvStatus_Deprecated,DRMvStatus_Inactive). SResponse::expiresis now correct UTC. Before 3.0.0 it was off by the local timezone offset. If your code corrected for that offset, remove the correction.DRMCommon.hnow only contains the callback types (SResponse,FResponse) and the version. Internal structures and the unusedDRM_OBFUSCATEmacro were removed. Code that only usesDRMPublish::Builderis not affected; if something no longer compiles, replace it with the documented API.- Use only the API documented on the C++ Integration page. Anything else in the headers is internal, is not available in the shipped libraries, and may change.
Quick Reference
| Area | 2.0.X (Old) | 3.0.0 (New) |
|---|---|---|
| Activation | Online, with temporary offline use after a previous activation | Online-only; 3 retries (10/30/60 s) on network failure |
| Protecting calculations | GetAuthValue(), GetAuthMultiplier() | Formulas: L3DRM_Formulas.h wrappers or DRM_EVAL("VM_KEY", inputs..., fallback) |
| Configuration values / strings | GetAuthValue() | Unchanged |
| Library | Single library (before 2.0.7) | DRMCore2_FS20.a / DRMCore2_FS24.a (+ _debug) |
| WASM signing | WasmSigner.exe post-build step, requireLocalWasmSigning() | Removed; the server checks the .wasm hash via wasmPath() |
wasmPath() (key mode) | Optional; any file hash satisfied "require hash" | Required when "require hash" is on (default), else AUTHZ_006 |
| Module exports | SDK default (--export-dynamic, ~1,800 functions) | --no-export-dynamic + --export= per gauge callback |
SResponse::expires | Off by the local timezone offset | Correct UTC |
Need help? The Demo Aircraft shows formulas, auth values and the builder setup in a working aircraft. Earlier migrations are covered by the guides selectable at the top of this page.