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: the import-script path and data-expected-product-name attributes must again match your aircraft.


Since 2.0.7 the DRM library ships once per MSFS SDK:

  • DRMCore2_FS20.a / DRMCore2_FS20_debug.a for modules built with the MSFS 2020 SDK
  • DRMCore2_FS24.a / DRMCore2_FS24_debug.a for 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.

  1. Remove the WasmSigner step from your post-build script and delete WasmSigner.exe from your scripts folder. Keep wasm-opt.
  2. Remove any .requireLocalWasmSigning(...) call from your builder. It is deprecated and ignored (and produces a deprecation warning). Remove VerifySignature() calls too; it does nothing.
  3. Keep .wasmPath(...): the server checks the hash of your .wasm at activation, like the files added with addFileHash().

wasmPath is required in key mode: with keyless(false), when the Client API key has "require hash" on (the default), activation now fails with AUTHZ_006 if no .wasm hash is sent. Hashes of other files added with addFileHash() no longer count on their own. Check that wasmPath() points at the .wasm you 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:

  1. 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.
  2. Click Download C++ header and add L3DRM_Formulas.h to your project.
  3. Replace the C++ calculation with the generated wrapper and a degraded fallback.
  4. Where you used GetAuthMultiplier() or GetAuthValue() inside a calculation, move that calculation into a formula. Keep GetAuthValue() 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 fallback

Fallback: use a degraded fallback, never the correct value. The fallback is visible in your .wasm and 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() in PANEL_SERVICE_PRE_KILL (MSFS 2024 gauge API: _gauge_kill), once the last gauge of your module unloads.
  • Call an AssureAuthenticated variant 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. onSuccess receives the expiry, the username and the Client API key status vStatus, an enum (DRMvStatus_Active, DRMvStatus_Deprecated, DRMvStatus_Inactive).
  • SResponse::expires is 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.h now only contains the callback types (SResponse, FResponse) and the version. Internal structures and the unused DRM_OBFUSCATE macro were removed. Code that only uses DRMPublish::Builder is 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

Area2.0.X (Old)3.0.0 (New)
ActivationOnline, with temporary offline use after a previous activationOnline-only; 3 retries (10/30/60 s) on network failure
Protecting calculationsGetAuthValue(), GetAuthMultiplier()Formulas: L3DRM_Formulas.h wrappers or DRM_EVAL("VM_KEY", inputs..., fallback)
Configuration values / stringsGetAuthValue()Unchanged
LibrarySingle library (before 2.0.7)DRMCore2_FS20.a / DRMCore2_FS24.a (+ _debug)
WASM signingWasmSigner.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 exportsSDK default (--export-dynamic, ~1,800 functions)--no-export-dynamic + --export= per gauge callback
SResponse::expiresOff by the local timezone offsetCorrect 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.