Skip to content

Developer Guide

noteMASTER11 edited this page Nov 12, 2026 · 11 revisions

Developer Guide

Source checkout

git clone https://github.com/noteMASTER11/TaxiDriverReloaded.git
cd TaxiDriverReloaded

The repository contains source only. dist/taxidriver.zip is intentionally distributed through GitHub Releases rather than committed.

Development installation

BeamNG supports unpacked mods, but never enable the unpacked source and packaged taxidriver.zip simultaneously.

A development tree must preserve these roots:

lua/
ui/
mod_info/
CREDITS.txt

The release ZIP must contain these paths directly at archive root. Do not wrap them inside a taxidriver/ folder, and use / path separators inside the ZIP.

Version locations

Update all four values for a release:

  1. modVersion in lua/ge/extensions/taxiDriver/taxiDriver.lua;
  2. version in ui/modules/apps/TaxiDriverHUD/app.json;
  3. version in mod_info/TaxiDriver/info.json;
  4. version in package.json.

Also update externalUiRevision and the matching ?v= values in the external bootstrap and UI imports whenever browser-cached assets change.

The archive filename remains exactly taxidriver.zip.

Configuration changes

Balance and timing constants belong in config.lua. Keep pure logic in focused modules when possible. Avoid adding more top-level locals to taxiDriver.lua because the main chunk is close to LuaJIT's 200-local limit.

Changing a difficulty preset mutates the active balanceConfig fields. Every preset must therefore define every field that can differ between presets; otherwise a value from the previously selected preset can remain active.

Adding an order property

  1. Create it in createOffer().
  2. Preserve it when the offer becomes trip.
  3. Expose it from buildHudOffer() or buildHudState().
  4. Add a default in the shared model state if the UI reads it before the first backend snapshot.
  5. Add localized UI labels to all ten locales.
  6. Test dispatcher, floating next offer, and queued-offer transition.

Adding a phase

  1. Add the ID to config.lua phases and diagnostic labels.
  2. Add localized phase_* keys to all locales.
  3. Decide whether it logically contains a passenger.
  4. Decide whether penalties, mood, rush timer, and forced stop may advance.
  5. Decide whether the native minimap can render.
  6. Add a dedicated Vue v-if screen in hud-template.html or include it in an existing screen.
  7. Cover transition, reset, stop-mode, mission-end, and serialization cleanup.

Adding a localization

  1. Add the language to supportedLanguages in config.lua.
  2. Add it to the UI languages array.
  3. Add a complete dictionary to locales.json with the exact English key set.
  4. Verify placeholders and plural-neutral phrasing.

Adding a sound

  1. Put the renamed asset in ui/modules/apps/TaxiDriverHUD/sounds/.
  2. Register a pool in appAudio with an appropriate base volume and size.
  3. Call playAppSound(poolId) rather than invoking Audio directly.
  4. Confirm Silent Mode, AudioUiVol, and the TaxiDriver appVolume multiplier all affect it.
  5. Include the pool in the random sound-test list when appropriate.

Static validation

Recommended pre-release checks:

  • Parse every GE Lua module as Lua 5.1/LuaJIT syntax.
  • Keep the main extension below 200 top-level locals.
  • Rebuild Vue render and external bundle assets with pnpm build:ui; inspect app.css and shared hud-template.html.
  • Parse locales.json and compare every locale's keys with English.
  • Run git diff --check.
  • Inspect archive entries for missing files, extra root folders, or backslashes.
  • Verify the installed archive hash matches the release artifact.
  • Run the Realistic Mode × Random Events combinatorics across regular, rush, multi-stop, and delivery work.
  • Exercise all order-sorting buttons because native CEF selectors are intentionally not used in the scaled UI.

Runtime smoke test

At minimum test:

  1. normal mode start and 10–12 offer fill;
  2. regular, rush, multi-stop, and cargo-delivery acceptance;
  3. pickup/door/boarding transition;
  4. speeding, collision, and harsh-manoeuvre event logging;
  5. mood increase and decrease animation;
  6. floating-offer expiry and queue acceptance;
  7. reset with queued offer;
  8. pause during every visible countdown;
  9. Realistic Mode with combustion and electric vehicles;
  10. station detour with and without a passenger;
  11. paid refueling, interruption, completion, and route restoration;
  12. cargo mass application, collision damage, completion, cancellation, and reset cleanup;
  13. full-phone and minimized-dashboard map geometry;
  14. vehicle switch, level reload, odometer continuity, and native selector opening;
  15. Magic Fuel, quick presets, projections, and active-order sufficiency;
  16. settings/profile/progress/vehicle-history reload after restarting the session.

Release publication

  1. Commit and push source changes.
  2. Build dist/taxidriver.zip from the committed source.
  3. Create a version tag such as v2.25.0 on the release commit.
  4. Upload the asset as taxidriver.zip without version text in the filename.
  5. Verify metadata version, asset digest, and download URL.
  6. Mark Beta builds as GitHub prereleases and use a SemVer prerelease tag such as v3.0.0-beta.

Native Vue build and verification

Use Node.js 24 and pnpm with the pinned pnpm-lock.yaml:

pnpm install --frozen-lockfile
pnpm test
pnpm test:game
.\scripts\package-mod.ps1

pnpm test rebuilds generated UI assets and runs behavior, template, DOM-scenario, lifecycle and asset checks. pnpm test:game connects to the running game's MCP at http://127.0.0.1:29292/mcp (BEAMNG_MCP_URL overrides it), compiles runtime Lua and runs isolated mock regressions. It does not drive the car or edit player settings.

pnpm test:visual needs a Playwright browser; TAXIDRIVER_BROWSER_CHANNEL=msedge selects installed Edge. pnpm test:lan needs .NET. Keep unrun checks distinct from passing results.

The native entry is app.vue; game imports vue and @/bridge resolve inside BeamNG. Build shared hud-template.html into hud-render.js; external entry.js bundles the shared component with Vue 3.5.43. Keep bridge receiver bindings and callback-expression semantics intact. When assets change, synchronize the revision in app.vue, external/index.html and external/external.js; 5.0.2 uses 513.

Home preset choices are immediate settings commits. Preserve Custom sliders and unrelated preferences. For route ingress, seed only the first two nodes through wpTargetList, then append the resolved suffix with ai.setPath after native initialization, retaining the shared terminal node needed by pathExtend. Changed Vehicle Lua requires a player-vehicle reload as well as GE/UI reloads. Keep experimental native-map API changes inside nativeMinimap.lua.

Font checks read BeamNG UI assets from the configured game installation. Set BEAMNG_UI_ROOT to the game's ui directory when it differs from the default D:/SteamLibrary/steamapps/common/BeamNG.drive/ui. The external Vue bundle includes its MIT attribution in external/THIRD-PARTY-NOTICES.txt; retain that file and the credits pointer when packaging.

Earth integration and readable builds (5.0.2)

Earth-dependent code belongs in the Earth adapters. Keep ordinary-map behavior independent of whether Earth is installed, and do not copy geographic endpoints into the finite local destination cache. Personal GPS sessions and their service context must not set the paid taxi shift active or replace its lifecycle.

The Connected Phone build uses Vue's production runtime with minification disabled. Preserve function names, source-module labels, original HUD sources/template, README.md and Vue license notices in the ZIP. The long values in sounds-data.js are embedded MP3 data. See Third Party Libraries and Source Review and the repository's DEVELOPMENT.md.

5.0.2 publication preflight passed 80 JavaScript/UI tests, compiled 52 runtime Lua files and passed 43 Lua regressions in the local compatibility runner. The game was closed for that preflight. Earlier development checks passed 43 isolated regressions and compiled 52 files in the running game's LuaJIT; the release notes distinguish those checks. Do not describe the local runner as a fresh native game run.

Clone this wiki locally