技术文档

LevelUp 737NG → MSFS 2024: conversion assessment and architecture

此页为项目的英文技术文档原文。 docs/CONVERSION_ASSESSMENT.md

Superseded in part (2026-10-31). The logic and the instruments are being rewritten as an MSFS WASM module and HTML display units; LU737 Host and its WebSocket link are removed from the product (kept as a test oracle). §2.2–2.4 and §3–6 below describe the previous architecture; see REWRITE_PLAN.md. §1 (sources), §2.1 (models) and §4 (flight model) still apply.

Status date: 2026-10-29. Variant in scope: 737-800 (CFM56-7B26, blended winglets). Goal set by the owner: a complete restoration of the original models, flight deck and instruments — the original instruments compiled for MSFS 2024, not redrawn.

1. What is used from the LevelUp download (branch main)#

Item Use
737_80NG.acf Object list with offsets and inside/outside flags (_obja), geometry, masses, CG, gear, engines, tanks, surfaces → MSFS configs; PANEL_3D (the 3-D panel: 6,887 generic instruments in 2,696 groups) → the panel program.
objects/**/*.obj, textures (DDS/PNG, normal/metal, _LIT) All 65 objects the 737-800 loads → LU738_EXTERIOR.gltf (exterior) and LU738_INTERIOR.gltf (flight deck, cabin), original textures, every animation, visibility rule, click spot and lit texture.
b738_cockpit.obj Click-spot layer and the display surfaces (ATTR_cockpit triangles mapped onto the panel texture).
cockpit_3d/-PANELS-/Panel.png, cockpit_3d/generic/** Panel background and the 1,257 instrument bitmaps the panel uses — copied unchanged.
plugins/xlua/{win,lin}_x64/xlua.xpl, init.lua, scripts/** XLua and the 15 Zibo/LevelUp Lua modules (~230k lines) — run unmodified in xphost.
plugins/zibomod/{win,lin}_x64/zibomod.xpl The compiled Zibo plugin (custom FMS/ND/TCAS logic, AFDS, flight controls, engine model) — run unmodified in xphost.
B738_Commands.txt, B738_Datarefs.txt Reference for the command/dataref interface.
fmod/*.bank, fmod/737_80NG.snd, GUIDS.txt Original sounds and their X-Plane sound logic, played by xphost.
airfoils/ Checked for the FDE.

2. Architecture#

MSFS 2024                                          LU737Host.exe (xphost)
┌──────────────────────────────────────────┐      ┌──────────────────────────────────┐
│ LU738_EXTERIOR / LU738_INTERIOR (glTF)   │      │ X-Plane plugin API (XPLM_64.dll) │
│  behaviour XML: L:LU737_<STATE> (SCI),   │      │  datarefs, commands, flight loops│
│  clicks → H:LU737_<CONTROL>_<ACTION>     │      │  draw callbacks, nav database    │
│                                          │      │ OPENGL32.dll: records drawing    │
│ XPanel gauge (LU_PANEL, 2048×2048)       │ ws:// │                                  │
│  • panel interpreter (original PANEL_3D, │◄────►│  xlua.xpl  → Zibo/LevelUp Lua    │
│    original bitmaps, replayed GL lines)  │ 52737│  zibomod.xpl                     │
│  • SimBridge: SimVars → sim/ datarefs,   │      │                                  │
│    plugin writes/commands → MSFS events  │      │ reads X-Plane 12 nav data files  │
└──────────────────────────────────────────┘      └──────────────────────────────────┘

2.1 Models (tools/convert)#

convert_aircraft.py loads the objects exactly as X-Plane does from the _obja list (offsets, flags: inside → interior model, outside/glass/alpha → exterior; the crew figures are replaced by MSFS avatars). obj8_to_gltf.py converts OBJ8 geometry, ANIM_* (one glTF animation per dataref, shared across objects), ANIM_hide/show, manipulators, ATTR_light_level/LIT textures (emissive) and ATTR_cockpit triangles (one LU_PANEL material with the original panel UVs). textures.py resolves textures like X-Plane (case-insensitive, PNG/DDS) and converts X-Plane normal/metalness maps to MSFS normal + ORM. generate_behaviors.py writes the model behaviours: physical animations (surfaces, gear, wheels, fans, exterior lights) read MSFS A: variables (data/xp_to_msfs_map.json); everything else reads L:LU737_<STATE> of the stable cockpit interface, and clicks send H:LU737_<CONTROL>_<ACTION>; the host maps both onto the plugins (data/sci, docs/SCI_IMPLEMENTATION.md).

2.2 Instruments (tools/msfs/build_xpanel.py, avionics/src/xpanel)#

The panel program is the original PANEL_3D, compiled to JSON with the bitmaps it references. The interpreter implements X-Plane's generic instruments: rotary (frames), needle (pivot offset, OFFSET, NAV/pitch deflection), pointer, pie (colour table, inner radius), text (53-glyph font strips), LED (16×6 font grids, leading-zero glyph, period width), rolling drums, translate/rotate/clip groups, SHOW_LESS/GREATER/EQUAL (inclusive), key frames with per-segment exponents and linear extrapolation, KF wrap, SIZE, CLIP boxes and rheostat brightness. Conventions were recovered from the panel itself and X-Plane's render of it (Panel_Preview.png): panel coordinates are y-up with the origin 256 px below the 2048² texture, POS is the instrument centre, name-1/-2/-3/-4.png are the runtime bitmap slots. The plugins' own OpenGL drawing on the panel (route lines etc.) is recorded in the host and replayed on the canvas.

2.3 Logic (xphost)#

xphost implements the X-Plane plugin SDK functions the two plugins import (52 for zibomod, 43 for XLua: datarefs with accessors and type conversion, commands with before/after handlers and held phases, legacy and modern flight loops, draw callbacks, plugin messaging, directory/system paths, nav-database search over earth_nav.dat/earth_fix.dat/apt.dat, probes, instances, and X-Plane's sim datarefs with their types and precision). It loads the plugins from the aircraft folder in X-Plane's order, sends the aircraft-loaded messages and runs one X-Plane frame per MSFS frame. It needs no change to the plugin binaries or scripts; the host only implements the documented plugin interface. Where the plugins rely on X-Plane's own behaviour, the host provides it: the radio stack (built-in tuning/flip/transponder commands and the hz/hz_833/Mhz/khz variants of each frequency), legacy and alias datarefs (e.g. sim/cockpit/radios/*, engine indications under several names), brightness rheostats, and dataref precision (float/int storage). Measured: 5,088 plugin datarefs, 1,183 commands, ~2.5 ms per frame for all plugins.

2.4 Coupling MSFS and the plugins (avionics/src/xpanel/simbridge.ts)#

The plugins override X-Plane's flight controls, engines, fuel flow, brakes, steering, IAS and pressurization and run their own models. MSFS keeps the physics (aerodynamics, thrust from its turbine model, fuel, gear). The bridge:

  • feeds ~300 sim datarefs from SimVars every frame (position, attitude and rates in X-Plane senses, air data, weather, time, engines, radios, gear, electrics);
  • treats a sim dataref the plugins write as theirs from then on (no longer fed), except where X-Plane itself keeps updating it (fuel, weights, gear, engine running state);
  • applies plugin writes to MSFS: trim, flap and gear handles, spoilers, baro settings, radio frequencies, transponder, lights, cut-off levers, igniters; yoke and thrust outputs only while the Zibo AP (CMD/CWS) or A/T has authority; MSFS engines are started when the plugins' engine model starts;
  • maps X-Plane built-in commands the plugins fire to MSFS events and the pilot's MSFS key bindings to the original commands;
  • learns the sign between MSFS control positions and X-Plane yoke ratios from the pilot's inputs and the aircraft's response (persisted), because the MSFS SDK documentation was not reachable to confirm it.

3. What is verified, and how#

Check Result
glTF of all objects, textures resolved 0 missing textures; exterior 2,257 nodes / 75 animations, interior 7,078 nodes / 562 animations, 1,033 click spots
Panel interpreter vs X-Plane's render positions/sizes match Panel_Preview.png (PFD, ND, EICAS, standby, clocks, radios); images placed with the 256 px rule match pixel-exactly
Original plugins in the host (Linux build, lin_x64 plugins) all 15 Lua modules run, 1,807 of 1,818 non-sim panel datarefs provided by the plugins; the remaining 11 are not defined by any plugin (treated as X-Plane does)
Windows build with the win_x64 plugins (under wine) same results, also over the WebSocket link
Panel from the live plugins PFD, ND, EICAS, lower DU, standby, radios, LevelUp EFB menu rendered with the plugins' values
Gauge bridge against the host (fake MSFS) inputs, ownership, AP/AT gating, commands, sign learning, protocol: unit tests + end-to-end run
In MSFS 2024 not yet — see TEST_PLAN.md

4. Flight model#

Positions and masses come exactly from the .acf (feet; x→lat, y→vert, −z→lon). The X-Plane origin is at the nose, so the models are moved to put the empty CG at the MSFS model origin, and every cfg position is written relative to that origin with reference_datum_position = 0, 0, 0 (the acf origin is 60.22 ft forward and 2.05 ft above it for the -800). MSFS 2024 measures aero_center_lift from the model origin and the other positions from the datum; a datum at the origin makes them agree (FDE_TUNING.md, "Reference frame and CG"). MSFS tables were derived from geometry and published performance and are initial values to tune in the sim — see FDE_TUNING.md. The plugins' AFDS flies the MSFS aircraft through the control positions, so the FDE quality also decides how well the original autopilot tracks.

5. Known gaps#

  • Sound comes from the host (original FMOD banks and .snd logic through X-Plane 12's FMOD runtime), not from MSFS's audio engine: it needs the X-Plane 12 install and is not mixed with MSFS's sounds or volume settings. Listener: pilot's eye in cockpit views, a fixed chase position outside.
  • X-Plane's EFIS base map (EFIS_basemap_s_HM, two instruments: X-Plane's own map layer under the ND) is not drawn; the Zibo ND symbols, route and labels are.
  • IRS display: overlapping LED fields are laid out by the generic LED rule and do not yet match X-Plane digit-for-digit.
  • Objects the plugin places in the world (XPLMLoadObject/instances, e.g. ground equipment) are not drawn.
  • Fuel/payload: set in MSFS; the LevelUp EFB loading pages do not change MSFS fuel or payload.
  • Thrust comes from MSFS's turbine model at the same lever position; the engine indications come from the plugins' engine model, so they can differ slightly from the thrust MSFS produces.
  • Other variants (-600/-700/-900/-900ER) use the same tools with another .acf but are not generated.

6. Plan#

  1. ✅ Readers, converters, MSFS configs; all original objects and textures.
  2. ✅ Original panel interpreter; plugin host; gauge and MSFS bridge; package.
  3. ⏳ First in-sim build and flight (owner) — fix load errors, check display placement, control signs, AP/AT tracking, engine start (TEST_PLAN).
  4. FDE tuning; IRS LED layout; EFIS base map; listener position from the MSFS camera.

7. Licensing#

The LevelUp README EULA: free for personal use "in its intended format"; modification/redistribution needs LevelUp's written consent; Zibo and Laminar Research hold their own copyrights. This conversion is kept private for the owner's personal use and must not be distributed. Until 2026-10-30 the original plugin binaries ran unmodified and were not reverse engineered. For the rewrite (REWRITE_PLAN.md) the owner authorised reading the zibomod binary with a decompiler, for personal use only; no decompiled code is committed, the rewrite is new code written from the behaviour it shows. Getting LevelUp's and Zibo's consent is recommended for anything beyond private use.