Browse docs

Changelog

Full change history for Sky Mechanic Job.
Current

Version 1.38.0

Highlights

  • Fixed an issue where ready parts deliveries did not appear after joining or restarting the resource while its server setup was still loading.
  • Improved the Parts Shop and delivery overview with clearer order states, job colours and readable item images across tablet themes.

Notable Changes

  • Improved order and basket handling so late replies from a previous job or closed shop cannot replace the current view, and interrupted checkouts retain their existing request for a safe retry.
  • Improved delivery collection and carried-part handling through the shared supply system while retaining Mechanic parts, procurement, pallets and workshop collection points.

Other Changes

  • Improved delivery-note layout and standalone form controls.

Changed Files

  • sky_mechanicjob/config/locales/*
  • sky_mechanicjob/fxmanifest.lua
  • sky_mechanicjob/source/* — delete and reinsert
Update InstructionsWhat to copy, what to keep and what to check1.37.01.38.0

Simplified update

Update sky_mechanicjob safely

Read the complete update instructions in one continuous guide.

1. Back up and prepare

These steps update sky_mechanicjob from 1.37.0 to 1.38.0. Complete earlier guides first if your installed version is older.

  1. Download and extract the 1.38.0 package.
  2. Back up your game database, server configuration and installed sky_mechanicjob folder.
  3. Stop the server. Complete the Base 1.49.0 update and Jobs Base 1.52.0 update during the same maintenance window. Mechanic 1.38.0 loads its delivery modules from Jobs Base 1.52.0, so install them together.

2. Copy the package files

Inside your installed sky_mechanicjob folder:

  1. Delete the old source/ folder and copy the complete new source/ folder from the 1.38.0 package.
  2. Replace fxmanifest.lua with the matching downloaded file.
  3. Replace config/locales/ with the complete downloaded folder. For custom translations, compare the backup with the new language file and copy only your edited wording into matching keys; retain the new keys.

Keep your existing config/config.lua, config/adv_config.lua, provider functions, item definitions, images and models.

3. Keep or configure settings

Keep your existing jobs, prices, procurement rules, parts catalogue, collection points and carry-item settings. No Mechanic configuration change or settings import is required.

If /jobconfig is enabled, its saved settings remain in use; do not import the shipped defaults over them. If Config.UseJobConfigurator = false, keep your existing Lua values unchanged. The updated shop does not require recreating your catalogue or delivery locations.

4. Database, items and assets

The Jobs Base 1.52.0 update adds the delivery-reservation field to the existing sky_mechanic_part_deliveries table. With Config.AutoExecuteQuery = true in Jobs Base, let its migration finish during startup. With that switch disabled, complete the manual database branch in the Jobs Base guide before startup: on MariaDB, run the new sky_jobs_base/import.sql; on an existing MySQL 1.51.0 database, open sky_mechanic_part_deliveries in your database editor, check for claim_reservations, and add it only when absent as a nullable LONGTEXT column with default NULL. Keep existing columns and rows. Do not run the MariaDB full import on MySQL.

There is no additional Mechanic SQL migration. Keep existing orders, deliveries and storage data. No new items, inventory images or models are required.

5. Start and check

  1. Start the database connector, framework and selected inventory, banking, targeting and other providers in their normal dependency order. Then start sky_base 1.49.0, sky_jobs_base 1.52.0 and sky_mechanicjob 1.38.0.
  2. Resolve the first startup or migration error before allowing players back. Reconnect to load the new interface.
  3. With an on-duty mechanic, open the Parts Shop, review an existing order and place one small test order. Collect it at the configured workshop point and check the payment, received parts and order history.
  4. Test your configured physical carry/pallet or direct inventory delivery mode, including depositing a part into authorised workshop storage. Check ready deliveries again after reconnecting.

Version 1.37.0

Highlights

  • Improved the Parts Shop by using the shared supply-order system while retaining Mechanic catalogues, pallets, procurement and history.
  • Added per-job control over vehicle diagnostics and its repair actions.

Notable Changes

  • Added solo vehicle inspections so mechanics can select themselves as keeper and complete consent without closing their tablet.
  • Fixed an issue where parts-delivery setup started before pricing initialization completed.
  • Fixed an issue where disabled job shops still forced procurement through an inaccessible shop.
  • Fixed an issue where document galleries registered duplicate requests and reached rate limits.
  • Improved targets for the selected work vehicle, lift, hoist, dyno and fan controls.
  • Added selected-vehicle targets for prepared wheel and catalytic-converter theft steps.
  • Improved personal radio push-to-talk while using the tablet.

Other Changes

  • Improved participant names, document layouts, billing controls and shared asset selection.
  • Updated shop navigation text and bundled translations.

Changed Files

  • sky_mechanicjob/config/config.lua
  • sky_mechanicjob/config/locales/*
  • sky_mechanicjob/fxmanifest.lua
  • sky_mechanicjob/import.sql
  • sky_mechanicjob/source/* — delete and reinsert
Update InstructionsWhat to copy, what to keep and what to check1.36.01.37.0

Simplified update

Update sky_mechanicjob safely

Read the complete update instructions in one continuous guide.

1. Back up and stop the server

These steps update sky_mechanicjob from 1.36.0 to 1.37.0. If you are on an older version, complete its earlier update steps first.

  1. Download 1.37.0 and extract the ZIP on your computer.
  2. Make a full backup of your server files and game database. Also keep a separate copy of the installed sky_mechanicjob folder.
  3. Stop the server before replacing files. Put away equipped custom weapons first. Keep the backup until the update has been checked.

Also complete the Base update and Jobs Base update for your installed jobs. They contain the library, database and inventory steps shared by these jobs.

2. Copy the new files

Use the files from the 1.37.0 download throughout these steps. All paths below are inside your installed sky_mechanicjob folder.

  1. Delete the old source/ folder. Copy the complete new source/ folder into its place, including its interface files.
  2. Replace fxmanifest.lua with the file from the same download.
  3. Replace the complete config/locales/ folder with the new one. If you changed any wording, open the backed-up language file beside the new file and copy your edited text into the matching entries. Keep the new translation keys and folders.
  4. Keep your existing config/config.lua; make only the settings changes described in step 3 below. Do not overwrite your configured jobs or locations with the download's defaults.

Copy the new import.sql to the same path. The required order-table update is installed through Jobs Base in step 4.

3. Check your settings

Your existing diagnostics stay enabled unless you choose to disable them. Keep your current jobs, parts, prices, delivery locations and permissions.

Using /jobconfig (the default): after starting the updated server, open /jobconfig → Mechanic → your job → Vehicle Diagnostics. Use Enable vehicle diagnostics only if you want to change that job's access, then save. No settings import is needed.

Only if Config.UseJobConfigurator = false and you want to disable diagnostics for a job: open sky_mechanicjob/config/config.lua, find that job inside Config.Jobs, and add this inside its existing job table:

diagnosticsSettings = {
    enabled = false
},

If the block already exists, change its existing value instead of adding another block. Use true to keep diagnostics enabled. This setting does not disable inspections, tuning or general vehicle wear.

The Parts Shop now uses Jobs Base's order system. Keep the existing parts catalogue and collection points. Review that job's online-shop switch and the global Parts Delivery switch if the shop should be available. Existing delivery time and payment settings continue to apply; company payment still needs permission 9 and the job's society account. You do not need to enter the same settings again.

4. Update database, items and models

Complete the database step in the Jobs Base 1.51.0 guide before testing Mechanic. It updates the existing order table without deleting orders. If Jobs Base has Config.AutoExecuteQuery = true, wait for its automatic update at startup. If false, execute the new sky_jobs_base/import.sql in your game database before startup.

Keep sky_mechanic_part_deliveries, existing orders, your inventory items and models. Do not run clear.sql. There are no further new Mechanic items or models to install.

5. Start the server and check

  1. Finish the file copies, required Lua edits and database steps, then start the server. Start the framework, database connector and your selected inventory/weather/phone/banking/voice/key providers first. Start sky_base 1.48.0, then sky_jobs_base 1.51.0, then the installed jobs. Wait for database updates to complete. If used together, start DOJ 0.6.0 before Police 1.40.0, and Ambulance 2.47.0 before Crime 0.11.0.
  2. Check the server console for startup or database errors. If an error appears, resolve the first error before testing further. Check that this resource reports version 1.37.0.
  3. Reconnect so the new interface and models load. If step 3 listed in-game settings, open the named configurator, make those changes and save. Then check your saved jobs and the features you use before reopening the server to everyone.

What to check for this resource: Open an existing order, place one test order and collect it. Check its payment and parts. Test diagnostics for an enabled job and, if configured, a job where you disabled them. Open a saved inspection and the document gallery.

Version 1.36.0

Highlights

  • Added configurable repair and wash services to the instant-tuning basket with separate fixed prices.
  • Added separate torque settings for each ECU engine-software stage.
  • Added the option to present an existing unpaid or partially paid workshop invoice to its customer again.

Notable Changes

  • Added engine and body damage readings alongside maintenance wear in vehicle diagnostics.
  • Fixed an issue where Dyno tests displayed inflated power and torque figures for stock vehicles.
  • Fixed an issue where Dyno placement could reject level interior floors or the location of a station being moved.
  • Fixed an issue where vehicle-owner billing could select another character or query a different framework's database tables.
  • Fixed an issue where tuning refunds could be credited to a different character after reconnecting.
  • Fixed an issue where unsuccessful repairs could consume a repair kit or reset wear before the vehicle had been repaired.
  • Fixed an issue where delivered parts pallets could remain static or react incorrectly when being picked up.
  • Fixed an issue where document actions could send duplicate requests and display an error before completing.
  • Improved invoice history so workshop invoices remain available regardless of the connected vehicle.
  • Improved vehicle diagnostic images with the shared vehicle image catalogue.
  • Improved invoice recipient selection with nearby player names and distances while preserving the invoice draft when the list updates.
  • Fixed an issue where external billing providers displayed payment controls intended for Sky Billing.
  • Improved tablet navigation and forms with consistent headers, clearer labels and better keyboard focus.

Other Changes

  • Added Anodized Monochrome to the chameleon paint palette.
  • Updated the bundled translations for workshop, invoice and tuning workflows.
  • Improved the appearance of calendar popups inside tablet dialogs.

Changed Files

  • sky_mechanicjob/config/adv_config.lua
  • sky_mechanicjob/config/locales/*
  • sky_mechanicjob/fxmanifest.lua
  • sky_mechanicjob/source/* — delete and reinsert
Update InstructionsWhat to copy, what to keep and what to check1.35.01.36.0

Simplified update

Update sky_mechanicjob safely

Read the complete update instructions in one continuous guide.

  1. Prepare

These instructions cover sky_mechanicjob 1.35.0 → 1.36.0. Complete applicable earlier migrations first if you are upgrading from an older version. Back up the database, resources, custom configuration/translations and saved jobs, roles, locations and /jobconfig data. Test on staging and stop the server before replacing files. Start the framework, database connector and selected inventory, phone, banking and UI providers first, then sky_base 1.47.0 and sky_jobs_base 1.50.0, followed by the installed job resources. If you use DOJ with Police, start DOJ 0.5.0 before Police 1.39.0. If you use the Crime medical integration, start Ambulance 2.46.0 before Crime 0.10.0. Mechanic 1.36.0 and Fire 1.18.0 follow both libraries. Include only resources you have installed.

  1. Replace files

Use the complete 1.36.0 customer package. Delete the entire sky_mechanicjob/source/ folder and insert the new one. Replace sky_mechanicjob/fxmanifest.lua from the same download; do not merge old generated interface or bootstrap files. Refresh the complete sky_mechanicjob/config/locales/ tree and merge custom translations without restoring an older dictionary. Preserve the selected locale value in sky_base/config/config.lua.

Merge sky_mechanicjob/config/adv_config.lua using the new blocks below, preserving your existing locations, access rules and custom functions. sky_mechanicjob/config/config.lua has no new option to merge in this release. Install the matching Jobs Base 1.50.0 locale packs as part of the Jobs Base update. The repair/wash illustrations are bundled inside the new interface in source/; no separate inventory image install is needed.

  1. Merge settings

Instant repair and wash. In sky_mechanicjob/config/adv_config.lua, add these complete new child tables inside your existing Config.InstantTuning = { ... } block:

    repair = { enabled = true, price = 500 },
    wash = { enabled = true, price = 50 },

Previously all four values were absent. The new defaults are Config.InstantTuning.repair.enabled = true, Config.InstantTuning.repair.price = 500, Config.InstantTuning.wash.enabled = true and Config.InstantTuning.wash.price = 50. Preserve the other fields and configured locations. The unchanged shipped priceMultiplier = 1.25, mechanicOnly = false and allowedJobs = nil continue to control tuning/access; keep your intentional restrictions. No new location is created. Repair and wash are independent; repair-only preserves dirt. Their prices are fixed whole currency amounts and are excluded from the tuning multiplier and subscription discount.

With Config.UseJobConfigurator = true, make any desired changes after the updated server has started and before the gameplay checks. Edit Mechanic Jobs → Instant Tuning with instantTuningRepairEnabled, instantTuningRepairPrice, instantTuningWashEnabled and instantTuningWashPrice. The four new keys initialize from the shipped defaults until you save a different value. Preserve existing feature, location and access overrides, including instantTuningMechanicOnly and instantTuningAllowedJobs; copying this plaintext file does not replace them. With the configurator disabled, the entries above are the active values.

ECU engine software. Add this complete new block to sky_mechanicjob/config/adv_config.lua:

Config.ElectronicTuning = {
    engineTorqueMultipliers = {
        [1] = 1.10,
        [2] = 1.25,
        [3] = 1.35,
        [4] = 1.70
    }
}

The table was previously absent; these four defaults match the previous fixed boosts. Stock remains 1.00, and installed ECU stages 0–4 are retained. 1.00 adds no boost and 1.10 adds 10% torque. Do not rewrite saved vehicle stages as percentages.

With /jobconfig enabled, use Mechanic Jobs → ECU Engine Software: ecuEngineTorqueStage1 = 1.10, ecuEngineTorqueStage2 = 1.25, ecuEngineTorqueStage3 = 1.35 and ecuEngineTorqueStage4 = 1.70. New keys use shipped defaults until an override is saved. Change those four effective values to tune the boosts. With the configurator disabled, edit Config.ElectronicTuning.engineTorqueMultipliers[1] through [4] in the new block.

Keep all saved jobs, grades, permissions, locations and other overrides. No reset or routine import is needed. Use /jobconfigimport sky_mechanicjob only when you intentionally want to import your reviewed plaintext configuration after backing up its replacement scope. It does not install runtime files, SQL or images.

Optional profiling is disabled by default. If support requests a recording, put setr sky_profiler 1 in server.cfg before the Sky ensure lines and perform a full server restart. In the server console, run profiler record 1000, wait for profiler status to show completion, then run profiler saveJSON sky-release-20261014.json; choose a new filename for each recording. Disable it with setr sky_profiler 0 and another full server restart. This is not a /jobconfig setting. No recording or upload starts automatically.

  1. Database, items and assets

Database: No new Mechanic table, column or manual SQL migration is introduced from 1.35.0. Preserve invoices, payments, orders, refunds, ownership and saved vehicle stages. The ownership fixes use the selected framework's existing vehicle/character tables; do not create ESX tables on a QB/Qbox server or rewrite historical recipients.

Items and permissions: No new inventory item or permission ID is required. Existing repair-kit, ECU, invoice/duty and nearby-customer access rules remain. Present invoice again reuses the original outstanding invoice and its payment history; it does not create a replacement invoice or cancel it when the receipt closes.

Images and assets: Repair/wash pictures ship in the rebuilt interface under source/; no separate consumable registration is needed. There is no new streamed model or map. No non-source removals or renames are needed.

  1. Restart and check

Perform a full server restart after all replacements and migrations so manifests and file lists reload, then reconnect clients. Start the framework, database connector and selected inventory, phone, banking and UI providers first, then sky_base 1.47.0 and sky_jobs_base 1.50.0, followed by the installed job resources. If you use DOJ with Police, start DOJ 0.5.0 before Police 1.39.0. If you use the Crime medical integration, start Ambulance 2.46.0 before Crime 0.10.0. Mechanic 1.36.0 and Fire 1.18.0 follow both libraries. Include only resources you have installed. Check the actual installed versions and the first startup/database error before testing.

At an existing instant-tuning location, select repair-only, wash-only and both; verify the fixed service prices in the basket and the result after cash/card payment. Confirm a subscription or tuning multiplier does not discount those service prices. Check the original customer can receive an outstanding invoice again and previous payments remain. Verify vehicle-owner billing and refunds on your actual framework and a character switch, without changing historical invoice recipients.

Inspect engine/body collision damage separately from maintenance wear. Test a Dyno placement on a level workshop floor and move an existing station, then run a stock vehicle test. Confirm the four effective ECU multipliers and check an installed stage while driving on staging. Confirm a failed vehicle-owner repair does not report a completed repair or consume the reserved kit. Open document actions, workshop invoice history, the paint palette and nearby-player invoice selection.

Version 1.35.0

Highlights

  • Added configurable vehicle purchase-price catalogues, including custom database mappings.
  • Added optional JG HUD mileage display independently of the mileage source.
  • Added free camera movement during tuning with the Space key.

Notable Changes

  • Improved JG Mileage selection to retain Sky mileage while the optional provider is unavailable.
  • Fixed initial tuning saves for owned Qbox vehicles with empty properties.
  • Improved workshop vehicle history with temporary-registration online time and recorded plate-style changes.
  • Added optional server integration for attributing successful plate-style changes to their workshop actor.
  • Improved remote vehicle, lift and Dyno handling when a streamed vehicle is not yet available.
  • Added HP below the existing PS output in Dyno results.
  • Improved File Explorer loading so ordinary folders remain available while shared document data loads.
  • Improved shared document and video previews, with clearer feedback when a document cannot be loaded.
  • Improved court execution forms with automatic deadline updates that preserve entered details.
  • Improved targeted invoices so the selected recipient stays attached to the invoice throughout creation.

Other Changes

  • Improved customer names in workshop invoices.
  • Removed a repeated stance diagnostic from normal console output.

Changed Files

  • sky_mechanicjob/README.md
  • sky_mechanicjob/compat/jg_hud_mileage.lua
  • sky_mechanicjob/config/config.lua
  • sky_mechanicjob/config/locales/*
  • sky_mechanicjob/config/sv_functions.lua
  • sky_mechanicjob/fxmanifest.lua
  • sky_mechanicjob/source/* — delete and reinsert
Update InstructionsWhat to copy, what to keep and what to check1.34.11.35.0

Simplified update

Update sky_mechanicjob safely

Read the complete update instructions in one continuous guide.

  1. Prepare

These instructions cover sky_mechanicjob 1.34.1 → 1.35.0. Complete applicable earlier migrations when upgrading from an older version. Back up the database, resources, framework files, custom configuration/translations and saved /jobconfig/Creator data. Test on staging and stop the server for replacement. Install the coordinated versions for your installed resources. Start the framework, database connector and selected inventory, phone, banking and UI providers first, then Base 1.46.0 and Jobs Base 1.49.0. Start DOJ 0.4.0 before Police 1.38.0 for their shared catalogue and court workflows. Start Ambulance 2.45.0 before Crime 0.9.0 when using their medical integration. Mechanic 1.35.0 and Fire 1.17.0 follow both libraries. Include only installed resources.

  1. Replace files

Use the complete 1.35.0 customer package. Delete the entire sky_mechanicjob/source/ folder and insert the new one, then replace sky_mechanicjob/fxmanifest.lua from the same package. Refresh the complete sky_mechanicjob/config/locales/ tree and merge custom translations. Preserve your selected language. Do not restore an older bootstrap or merge generated interface files.

Merge config/config.lua and the updated Config.Functions.GetVehiclePurchasePrice implementation in config/sv_functions.lua, retaining deliberate custom API hooks. Add compat/jg_hud_mileage.lua and update the supplied README.md. Keep the matching manifest and complete generated source together.

  1. Merge settings

When Config.UseJobConfigurator = true, saved /jobconfig settings take precedence over the plaintext defaults. Change the effective values in /jobconfig; copying config files does not replace saved jobs, grades, locations or overrides. Keep the saved data and do not reset the configurator. Use /jobconfigimport sky_mechanicjob only if you intentionally want to import your edited plaintext configuration, after backing up and reviewing its replacement scope. With Config.UseJobConfigurator = false, merge the settings into the supplied config files instead.

New Config.VehiclePrices controls the global price source used by vehicle-value-based tuning. Defaults retain the existing mapping:

Config.VehiclePrices = {
    source = "auto",
    tableName = "vehicles",
    modelColumn = "model",
    priceColumn = "price",
    hashColumn = ""
}

In /jobconfig → Mechanic Jobs → General → Database, use vehiclePriceSource, vehiclePriceTable, vehiclePriceModelColumn, vehiclePricePriceColumn and vehiclePriceHashColumn. auto uses ESX's SQL mapping or QBCore/Qbox's vehicle catalogue. database uses the configured SQL mapping on any framework. For JG Dealerships choose database, dealership_vehicles, spawn_code, price, hashkey. The model column must contain spawn names, not display names; price values must be positive numbers. The optional hash column accepts numeric signed/unsigned hashes; leave it empty to resolve from spawn names. SQL identifiers allow up to 64 letters, digits or underscores. Missing prices retain the configured fallback vehicle value. The catalogue is read-only; the existing custom purchase-price hook remains available.

New Config.ToggleFeatures.tuningFreeCamera = true allows Space to hide the tuning cursor for camera movement; it is independent of existing automatic tuningCamera. New Config.ToggleFeatures.jgHud = false enables optional JG HUD display. Existing jgMileage = false and mileageHud = true remain. Select these feature switches in /jobconfig when enabled. For Sky mileage shown only in JG HUD, enable JG HUD and disable JG Mileage and Mileage HUD. JG Mileage uses jg-vehiclemileage v2.1.1+ while started, otherwise Sky mileage continues; switching does not migrate old odometer data.

For JG HUD integration, add this after the existing client_scripts block in jg-hud/fxmanifest.lua, so it loads after framework/cl-functions.lua:

client_script "@sky_mechanicjob/compat/jg_hud_mileage.lua"

Reload manifests with refresh, then restart Mechanic and jg-hud, or use the full server restart in the verification step. This retains JG HUD's original getter when Sky has no active display value. No additional JG resource is required if the new switch stays off. Plate-style audit integration is opt-in through the supplied server exports; installing this release alone does not enable attribution for an external script. Keep existing actor/permission policies. Install Base 1.46.0 with Mechanic 1.35.0 for the Qbox initial-save correction.

Optional profiling remains off by default. If support requests it, put setr sky_profiler 1 before the Sky ensure lines in server.cfg, perform a full server restart, run profiler record 1000, wait for profiler status to show completion, then run profiler saveJSON sky-release-20261008.json with a new filename for each capture. Disable it with setr sky_profiler 0 and another full server restart. This is not a /jobconfig setting; no recording or upload starts automatically.

  1. Database, items and assets

SQL: No new Mechanic table, column or manual migration. Vehicle-price configuration reads your existing catalogue; do not alter dealership tables merely to apply the update. Existing registration history and vehicle properties remain. Items: No new definitions. Assets: Add the supplied JG compatibility Lua file if integrating the HUD; no new map, stream model or item image. No Sky-to-JG mileage data migration is performed.

  1. Restart and check

Perform a full server restart to reload changed manifests and file lists, then reconnect clients. Start the framework, database connector and selected inventory, phone, banking and UI providers first, then Base 1.46.0 and Jobs Base 1.49.0. Start DOJ 0.4.0 before Police 1.38.0 for their shared catalogue and court workflows. Start Ambulance 2.45.0 before Crime 0.9.0 when using their medical integration. Mechanic 1.35.0 and Fire 1.17.0 follow both libraries. Include only installed resources. Check actual installed versions and the first startup/database error before testing.

Confirm saved tuning settings and calculate a price for a known model, including your fallback for a missing price. Test automatic tuning camera and Space free camera independently. If JG HUD is enabled, check its mileage with your selected source, provider stop/restart and vehicle exit. On Qbox, save tuning and retrieve an already-owned vehicle with naturally empty saved properties, preserving plate, fuel and damage. Check temporary-registration remaining online time and history, Dyno PS/HP output, File Explorer and targeted invoices. If integrating plate-style audit exports, confirm only successful attributed changes are recorded.

Version 1.34.1

Highlights

  • Added a configurable global vehicle purchase-price catalogue so vehicle-value-based tuning prices can use your dealership's existing table and spawn-name fields.
  • Fixed an issue where Space could not restore the tuning cursor after entering free camera.
  • Fixed an issue where the first tuning save failed for owned Qbox vehicles with missing or empty saved properties.
  • Fixed an issue where Mechanic failed to initialize when shared dependencies took more than 60 seconds to load.

Notable Changes

  • Added a Free camera in tuning menu feature switch in /jobconfig, allowing you to disable free-camera entry separately from automatic part focusing.
  • Fixed an issue where vehicle and Dyno updates produced network-object warnings outside a player's streaming range.
  • Fixed an issue where lift attachment updates tried to use a vehicle after it left streaming range during loading.
  • Improved Mechanic startup so a failed migration is reported without aborting the entire initializer.

Other Changes

  • Updated the release package to keep its own dependency bootstrap editable for support.

Changed Files

  • sky_mechanicjob/README.md
  • sky_mechanicjob/config/config.lua
  • sky_mechanicjob/config/locales/*
  • sky_mechanicjob/config/sv_functions.lua
  • sky_mechanicjob/fxmanifest.lua
  • sky_mechanicjob/source/* — delete and reinsert
Update InstructionsWhat to copy, what to keep and what to check1.34.01.34.1

Simplified update

Update sky_mechanicjob safely

Read the complete update instructions in one continuous guide.

  1. Prepare

These instructions cover sky_mechanicjob 1.34.0 → the refreshed 1.34.1 package. If you already installed the earlier 1.34.1 startup hotfix, download the latest 1.34.1 package again for these additions. The manifest version stays 1.34.1, so the version alone cannot distinguish the earlier package. Check that the new download includes Config.VehiclePrices and Config.ToggleFeatures.tuningFreeCamera in sky_mechanicjob/config/config.lua, then check the settings after installation.

Back up resources, the database, custom configuration, translations and saved configurator data. Validate the update on staging and stop the server for replacement. Install the latest refreshed Base 1.45.1, then Jobs Base 1.48.1, then Mechanic 1.34.1 and the matching updates for your installed consumers. Base supplies the Qbox first-save storage contract and Jobs Base supplies startup readiness plus the matching configurator fields and labels. An older package with the same .1 version may lack the new additions. Complete earlier release migrations first if upgrading from before 1.34.0.

  1. Replace files

Use the complete refreshed 1.34.1 customer package. Delete the entire sky_mechanicjob/source/ folder and insert the new folder, then replace sky_mechanicjob/fxmanifest.lua from that same package. This replaces the runtime code and generated interface together; do not merge old generated interface files.

Merge the new sky_mechanicjob/config/config.lua entries and the updated purchase-price hook in sky_mechanicjob/config/sv_functions.lua as described below, preserving intentional custom values and hooks. Replace sky_mechanicjob/README.md and refresh the complete sky_mechanicjob/config/locales/ tree, merging custom translations. Keep your selected Base language.

The supplied dependency bootstrap remains editable for support and must match the new source and manifest. Keep the new source/dependencies.lua; do not restore an older custom bootstrap. There are no outside-source removals or renames in this Mechanic update.

  1. Merge settings

Keep your existing jobs, grades, workshop locations and saved overrides. Merge the changed values into sky_mechanicjob/config/config.lua; do not replace your custom configuration with all shipped defaults. Config.UseJobConfigurator remains true by default. When it is true, managed features and settings use the packaged defaults plus saved database overrides, so edit them in /jobconfig. Plaintext edits to those managed values do not change the effective saved configuration. When it is false, the Lua values below are authoritative. Startup settings such as Config.UseJobConfigurator and Config.AutoExecuteQuery remain plaintext settings. No configuration reset or re-import is required.

Vehicle purchase prices — old: no Config.VehiclePrices block; the supplied hook used ESX vehicles.model / vehicles.price or the QBCore/Qbox catalogue. New: add this complete block, with the default auto preserving those sources:

Config.VehiclePrices = {
    source = "auto",
    tableName = "vehicles",
    modelColumn = "model",
    priceColumn = "price",
    hashColumn = "" -- Optional numeric model-hash column; leave empty to hash the spawn names.
}

In /jobconfig, open Mechanic Jobs → General → Database and set Vehicle price source, Vehicle price table, Spawn name column, Price column, and Model hash column (optional). This is one global catalogue for the resource's vehicle-value-based tuning calculations, not a separate mapping for each workshop. The saved setting keys and new defaults are vehiclePriceSource = "auto", vehiclePriceTable = "vehicles", vehiclePriceModelColumn = "model", vehiclePricePriceColumn = "price", and vehiclePriceHashColumn = "". Missing new keys inherit those defaults; saved non-default mappings remain authoritative. Save the intended values there and reopen the section after a restart to check them.

Choose auto / Automatic (framework) for the existing behaviour: ESX reads the configured SQL mapping, while QBCore and Qbox use their framework vehicle catalogue. Choose database / Database to read a custom SQL catalogue on any of those frameworks. Use the exact names of an existing table and columns. The model column must contain spawn names, the price column numeric purchase prices, and SQL table/column names must contain 1–64 letters, digits or underscores. Do not enter schema prefixes, spaces or SQL expressions. Leave the optional hash column empty to match model hashes from spawn names; an existing numeric hash column may contain signed or unsigned values, including numeric strings.

For an existing JG Dealerships catalogue that uses these exact column names, the complete example is:

Config.VehiclePrices = {
    source = "database",
    tableName = "dealership_vehicles",
    modelColumn = "spawn_code",
    priceColumn = "price",
    hashColumn = "hashkey"
}

With /jobconfig enabled, enter the same five values in General → Database instead of relying on the Lua example. JG's model column is a display name; use spawn_code for the spawn name. The mapping only reads prices and does not create or change dealership tables. Missing or nonpositive prices use your existing Config.TuningCostProfile.fallbackVehicleValue or the applicable workshop/instant-tuning price profile's fallback. The shipped global fallback remains 50000; preserve intentional pricing overrides.

Merge sky_mechanicjob/config/sv_functions.lua from the same package. The supplied Config.Functions.GetVehiclePurchasePrice(model, modelHash, source) now reads Config.VehiclePrices; restoring an older supplied hook would bypass the mapping. If you deliberately use a custom resource API or complex query, preserve that custom hook and check its returned prices; the new SQL settings do not override custom hook code. Keep the supplied startup readiness line at the top of this file. For the standard mapping, this is the complete new hook:

Config.Functions.GetVehiclePurchasePrice = function(model, modelHash, source)
    local modelName = tostring(model or "")
    modelName = modelName:match("^%s*(.-)%s*$")
    local normalizedHash = tonumber(modelHash)
    if normalizedHash then
        normalizedHash = normalizedHash % 4294967296
    end

    local function getSharedVehiclePrice(vehicles)
        if modelName ~= "" then
            local directVehicle = vehicles[modelName] or vehicles[modelName:lower()] or vehicles[modelName:upper()]
            local directPrice = tonumber(directVehicle and directVehicle.price) or 0
            if directPrice > 0 then
                return math.floor(directPrice)
            end
        end

        if not normalizedHash then
            return nil
        end

        for catalogModel, vehicle in pairs(vehicles) do
            local price = tonumber(vehicle.price) or 0
            if price > 0 then
                local vehicleModel = tostring(vehicle.model or vehicle.hash or catalogModel or "")
                if vehicleModel ~= "" and (joaat(vehicleModel) % 4294967296 == normalizedHash
                    or (tonumber(vehicleModel) and tonumber(vehicleModel) % 4294967296 == normalizedHash)) then
                    return math.floor(price)
                end
            end
        end

        return nil
    end

    local price_source = Config.VehiclePrices or ConfigDefaults.VehiclePrices
    if price_source.source ~= "auto" and price_source.source ~= "database" then
        error("[sky_mechanicjob] Config.VehiclePrices.source must be auto or database")
    end

    if price_source.source == "database" or Sky.Config.framework == "esx" then
        local identifiers = {}
        for _, key in ipairs({ "tableName", "modelColumn", "priceColumn", "hashColumn" }) do
            local identifier = tostring(price_source[key] or ""):match("^%s*(.-)%s*$")
            if key ~= "hashColumn" or identifier ~= "" then
                if #identifier == 0 or #identifier > 64 or not identifier:match("^[%w_]+$") then
                    error(("[sky_mechanicjob] Invalid Config.VehiclePrices.%s: use a SQL identifier of 1-64 letters, digits or underscores"):format(key))
                end
                identifiers[key] = "`" .. identifier .. "`"
            end
        end

        if modelName ~= "" then
            local rows = Sky.Query(("SELECT %s AS price FROM %s WHERE %s = ? LIMIT 1")
                :format(identifiers.priceColumn, identifiers.tableName, identifiers.modelColumn), { modelName })
            local price = tonumber(rows[1] and rows[1].price) or 0
            if price > 0 then
                return math.floor(price)
            end
        end

        if not normalizedHash then
            return nil
        end

        if identifiers.hashColumn then
            local signed_hash = normalizedHash >= 2147483648 and normalizedHash - 4294967296 or normalizedHash
            local rows = Sky.Query(("SELECT %s AS price FROM %s WHERE %s IN (?, ?) LIMIT 1")
                :format(identifiers.priceColumn, identifiers.tableName, identifiers.hashColumn),
                { ("%.0f"):format(signed_hash), ("%.0f"):format(normalizedHash) })
            local price = tonumber(rows[1] and rows[1].price) or 0
            return price > 0 and math.floor(price) or nil
        end

        local rows = Sky.Query(("SELECT %s AS model, %s AS price FROM %s")
            :format(identifiers.modelColumn, identifiers.priceColumn, identifiers.tableName), {})
        for _, row in ipairs(rows) do
            local rowModel = tostring(row.model or "")
            local price = tonumber(row.price) or 0
            if rowModel ~= "" and price > 0 and joaat(rowModel) % 4294967296 == normalizedHash then
                return math.floor(price)
            end
        end

        return nil
    end

    if Sky.Config.framework == "qbox" then
        return getSharedVehiclePrice(exports.qbx_core:GetVehiclesByName())
    end

    local qb = exports["qb-core"]:GetCoreObject()
    return getSharedVehiclePrice(qb.Shared.Vehicles)
end

Free camera — old: Config.ToggleFeatures.tuningFreeCamera was absent and free-camera entry was not separately configurable. New: add tuningFreeCamera = true alongside the existing tuningCamera = true. tuningCamera still controls automatic focusing of the selected tuning part; its shipped default is unchanged. tuningFreeCamera controls hiding the cursor for manual camera movement, independently of the automatic camera. This complete shipped block is a reference: add the new entry and preserve your existing choices for all other entries:

Config.ToggleFeatures = {
    kuv = false,
    vehicleRegistration = false,
    stance = true,
    tuningCamera = true, -- Automatically focus the selected tuning part. Also managed in /jobconfig.
    tuningFreeCamera = true, -- Allow Space to hide the tuning cursor for free camera movement. Also managed in /jobconfig.
    instantTuning = false,
    partsDelivery = true,
    carryItems = false,
    nitro = true,
    antiLag = true,
    twoStep = true,
    electronicTuning = true,
    wheelDamage = true,
    customHandling = true,
    handlingEditor = true, -- Admin editor and its automatic plate/model overrides.
    mileageHud = true,
    -- Requires jg-vehiclemileage v2.1.1+ to be started first. Existing Sky mileage is not migrated to JG.
    jgMileage = false,
    workshopLift = true,
    mobileDyno = true,
    brakeOverheating = true,
    selfServiceOrderNotifications = true,
    vehicleMaintenanceNotifications = true,
    subscriptions = true
}

In /jobconfig, open Mechanic Jobs → Features → Free camera in tuning menu. Its saved feature key is tuningFreeCamera, with default true; a saved false remains disabled after restart. Keep or adjust Automatic tuning camera separately (tuningCamera, unchanged default true). With free camera enabled, Space releases the tuning cursor and pressing it again restores the cursor; Escape still closes the menu. With it disabled, Space does not enter free camera. Disabling it through /jobconfig during an unfocused tuning session restores the cursor. The existing focus-key default remains Config.Keybinds.tuningFocusKey = "SPACE"; retain player key bindings and existing hotkey overrides.

Update the matching Jobs Base 1.48.1 package and its complete sky_jobs_base/config/locales/jobconfigurator/sky_mechanicjob/ tree for the new price fields, General → Hotkeys/Database labels and free-camera feature label. Refresh Mechanic's own complete locale tree and merge custom translations. Keep the selected language in sky_base/config/config.lua. The configurator labels are owned by Jobs Base.

The existing Parts Delivery Shop → Delivery handling selector is restored by Jobs Base 1.48.1. Its setting remains partsDeliveryMode; without /jobconfig, retain Config.PartsDelivery.deliveryMode in sky_mechanicjob/config/config.lua ("standard" or "player_inventory"). The shipped default remains "standard". Keep saved overrides.

Optional diagnostics remain disabled by default. If support requests a recording, put setr sky_profiler 1 before the Sky ensure lines in server.cfg, restart the server, run profiler record 1000, wait for profiler status to show completion, then run profiler saveJSON sky-startup-hotfix.json. Disable with setr sky_profiler 0 and another full server restart. This is a plaintext server convar, not a /jobconfig setting; no recording or upload starts automatically.

  1. Database, items and assets

SQL: No new table, column or SQL import is introduced by this Mechanic update. Keep your existing Config.AutoExecuteQuery policy. Repair the original database error if an earlier migration failed; continuing startup does not create missing schema. Do not replay a full import, clear tuning tables, force success markers or reset saved jobs/configurator data.

The vehicle-price mapping reads an existing catalogue; it does not create a dealership table, alter its schema or change prices. Check the table and columns before choosing Database. JG Dealerships is optional and is only needed if you choose its existing catalogue or custom hook.

Qbox: Update the refreshed Base 1.45.1 together with Mechanic 1.34.1, keeping your existing Qbox qbx_core and qbx_vehicles setup. An already-owned vehicle with missing or empty properties can receive its first complete tuning snapshot through qbx_vehicles; later saves continue preserving stored fuel, damage and other fields. This does not create an ownership record, repair malformed nonempty property data, or require a framework patch or manual SQL repair. Do not empty an existing vehicle's saved properties to trigger initialization. If you customized sky_base/config/vehicle_storage.lua, merge its Qbox initialization-marker update while preserving your garage schema mapping.

Items: No new item definitions, inventory registrations or item migration are introduced. Assets: No new item images, models, audio or stream assets are introduced. Keep the existing inventory and asset setup. The new frontend files are supplied inside the replaced source/ folder.

Progress providers: Keep your selected provider configuration. If you use ZSX_UIV2, install the matching Base 1.45.1 provider files and follow Base's provider setup; ensure the provider starts before Base. ZSX supports player cancellation; no programmatic stop export is assumed.

  1. Restart and check

Perform a full server restart after replacement so changed manifests and file lists reload. Start the framework, database connector and selected providers first, then Base 1.45.1, Jobs Base 1.48.1, Mechanic 1.34.1 and other installed consumers. Reconnect clients. The new changes keep the existing startup hotfix: Mechanic waits for Jobs Base initialization instead of aborting after 60 seconds. SQL migration warnings remain actionable and failure to read saved settings remains a visible initialization error.

Open the Mechanic tablet at your existing workshop. With /jobconfig, confirm the General → Database values, the Free camera in tuning menu feature, and Parts Delivery Shop → Delivery handling. Save a deliberate non-default price mapping or free-camera choice, reopen the section and restart once to verify that choice persists; do not reset unrelated overrides.

For vehicle-value-based pricing, use a vehicle with a known positive purchase price in your selected catalogue and check its tuning quote. With an optional hash column, test a vehicle whose catalogue stores its hash in the format you use. Also check a missing-price vehicle against the intended fallback. Fixed-price or otherwise overridden tuning options may not change when the purchase catalogue changes.

In the tuning menu, test Space to hide and restore the cursor and Escape to close, with Automatic tuning camera both enabled and disabled. Then disable Free camera in tuning menu and confirm that entry is blocked; if you disable it during an unfocused session, confirm that the cursor returns. Test your existing rebound focus key too.

On Qbox, use an already-owned staging vehicle with naturally missing or empty saved properties. Complete one permitted tuning install, store and retrieve it through your configured garage, and check the installed tuning, plate/model, fuel and damage. Repeat a save with an existing complete record and check that stored fuel, damage and other vehicle data remain intact. Source/contract tests do not establish the customer's paid install or garage round trip.

With two clients or a staging streaming-range test, check a spawned tuned vehicle, Dyno updates, remote AntiLag/TwoStep effects, catalytic smoke, wheel repair and engine-sound previews both nearby and outside streaming range. Check that no new network-object warnings occur and that nearby effects and restoration still work. Test lift attachment while in range, moving out of range during loading, and detachment; this change does not create a missing garage/lift vehicle association.

Complete and cancel one non-minigame install/repair using your selected progress provider; include ZSX_UIV2 if configured. Do not assume a provider has a programmatic stop export when it does not document one. If a feature remains unavailable, collect the first initialization/SQL error, preceding lines and actual package versions. Customer/client/provider acceptance remains a check to perform on your server.

Version 1.34.0

Highlights

  • Added an automatic tuning camera that focuses the selected vehicle part, with a player toggle and manual camera control.
  • Added optional authoritative mileage integration with jg-vehiclemileage.
  • Added invoice creation for unpaid public tuning orders while retaining the original customer and quoted order amount.

Notable Changes

  • Added separate interaction profiles for mobile dyno stations and result monitors, including placement controls and live blip updates.
  • Added gang and independent organization access selectors for supported mechanic activities and instant tuning.
  • Added the shared Sky Billing view alongside the existing mechanic service invoice workflows.
  • Improved mechanic invoice receipts and shared payment views with eligible installment choices and clearer payment status.
  • Fixed an issue where record printing callbacks were missing or the wrong file view reopened.
  • Fixed an issue where reopening the tablet lost its current route and navigation context.
  • Fixed an issue where an expired advanced pricing quote could fail while rebuilding the tuning catalogue.
  • Fixed an issue where untracked vehicles kept the wrong engine sound after repair.
  • Fixed an issue where persistence checks reported a normal unowned vehicle as a save error.
  • Improved tuning, wheel replacement and billing to use the active workshop's configuration.
  • Improved custom handling updates to reuse unchanged vehicle settings and discard stale updates.
  • Added an ESX vehicle properties compatibility diagnostic for unsupported upstream property layouts.
  • Improved first-time invoice, printer and tablet initialization.
  • Improved document navigation with grouped types and profile tabs.

Other Changes

  • Changed the default mechanic invoice amount limits to 999999999 while retaining custom configured limits and other grade rules.
  • Changed the default engine sound camera focus from the rear to the engine.
  • Improved configuration updates so other resources' edits do not invoke mechanic handlers.
  • Improved tablet descriptions so longer text remains readable.
  • Updated mechanic and billing translations.

Changed Files

  • sky_mechanicjob/config/adv_config.lua
  • sky_mechanicjob/config/config.lua
  • sky_mechanicjob/config/engine_sounds_config.lua
  • sky_mechanicjob/config/init.lua
  • sky_mechanicjob/config/locales/*
  • sky_mechanicjob/config/sv_functions.lua
  • sky_mechanicjob/fxmanifest.lua
  • sky_mechanicjob/source/* — delete and reinsert
Update InstructionsWhat to copy, what to keep and what to check1.33.11.34.0

Simplified update

Update sky_mechanicjob safely

Read the complete update instructions in one continuous guide.

  1. Prepare

These instructions cover sky_mechanicjob 1.33.1 → 1.34.0. Before replacing files, confirm that your customer download platform provides the versions below and check each downloaded resource's fxmanifest.lua; published documentation or a source tag alone does not establish that its customer download has been uploaded. Complete earlier migrations first if upgrading from an older version. Back up the database, resources, custom config, translations and saved Job Configurator/Creator data. Validate the update on staging before applying it to your production server. Stop the server during replacement. Install Sky Base 1.45.0, then Sky Jobs Base 1.48.0, then the matching releases for your installed jobs and Crime. Keep provider dependencies and optional integrations compatible; preserve saved overrides and existing records.

  1. Replace files

Use the complete 1.34.0 release package. Delete the entire sky_mechanicjob/source/ folder and insert its new version; do not merge old generated interface files. Replace sky_mechanicjob/fxmanifest.lua from the same package. Refresh the complete sky_mechanicjob/config/locales/ tree and merge your custom translations into the new files. Keep your selected shared language in sky_base/config/config.lua. Install the following shipped paths from that package, merging custom configuration into the updated public files rather than restoring old complete files:

  • sky_mechanicjob/config/adv_config.lua
  • sky_mechanicjob/config/config.lua
  • sky_mechanicjob/config/engine_sounds_config.lua
  • sky_mechanicjob/config/init.lua
  • sky_mechanicjob/config/locales/*
  • sky_mechanicjob/config/sv_functions.lua
  • sky_mechanicjob/fxmanifest.lua
  • sky_mechanicjob/source/* — delete and reinsert
  1. Merge configuration

Merge the two new feature defaults into sky_mechanicjob/config/config.lua:

Config.ToggleFeatures.tuningCamera = true
Config.ToggleFeatures.jgMileage = false

Set /jobconfig → Mechanicjob → Features keys tuningCamera and jgMileage when the configurator is enabled. Saved overrides remain effective. The camera feature permits automatic focus; each player can disable the automatic camera in the tuning menu and use the existing manual/free camera control with Space. Disabling the feature releases its own camera immediately.

Leave jgMileage = false unless using jg-vehiclemileage v2.1.1 or newer, started before Mechanicjob. With the feature enabled, JG's valid odometer value is authoritative, including zero and corrected lower values. Existing Sky mileage is not migrated into JG. Back up and review both systems' odometer data before switching; do not enable this to copy Sky mileage.

Add both new profiles inside your existing Config.Interactions table, keeping all existing workshop profiles:

mobile_dyno_station = {
    public = false,
    interaction = true,
    duty = true,
    interactionDistance = 3.5,
    unique = true,
    requiresHeading = true,
    placementGizmo = true,
    marker = { enabled = false, type = 1, offset = vector3(0.0, 0.0, 0.0) },
    npc = { enabled = false },
    blip = { enabled = false, sprite = 446, color = 5 }
},
mobile_dyno_monitor = {
    public = false,
    interaction = false,
    duty = true,
    unique = true,
    requiresHeading = true,
    placementGizmo = true,
    marker = { enabled = false, type = 1, offset = vector3(0.0, 0.0, 0.0) },
    npc = { enabled = false },
    blip = { enabled = false, sprite = 446, color = 5 }
},

With /jobconfig, edit the station and monitor interaction/placement profiles for Mechanicjob and keep saved custom rules. They are interaction profiles, not new global boolean settings. Menu and inventory placement use the configured placement gizmo and limits. Review existing installations and their blips after a live update.

The default global Config.Billing.maximumInvoiceAmount changes 250000 → 999999999. The shipped per-job Config.Jobs[*].billing.maximumInvoiceAmount also changes 250000 → 999999999; the shipped grade rows 0/1/2/3 change 15000/50000/125000/250000 → 999999999. Keep deliberate server-specific limits, discounts, taxes, permissions and other grade flags. Review the selected job's Billing settings in /jobconfig; do not reset saved custom limits to receive the new default.

In config/engine_sounds_config.lua, the default Config.EngineSounds.cameraPart changes "rear" → "engine". Preserve custom sound entries and their chosen focus. This sound option catalogue stays in the plaintext file; tuningCamera controls whether automatic focus is available.

Activity allow-lists in config/adv_config.lua now accept exact job/group names and "gang:<internal_name>". Gang membership is checked independently; a job duty requirement applies to job grants. Preserve existing jobs and enter only the intended gang selector in a supported activity list.

Mechanic's native service invoice and advanced billing configuration remain separate from central Sky Billing. Configure Base Config.billing = "sky" and Jobs Base billing to use the shared central panel; do not assume this migrates existing mechanic or external invoices. Unpaid public tuning orders can be invoiced from the Tuning Orders view by an authorized mechanic, using the original order/customer rather than a nearby replacement.

Merge readiness lines in config/init.lua and config/sv_functions.lua while retaining your custom function bodies. These bootstrap extension files are not /jobconfig settings.

The new readiness line in the supplied public bootstrap/hooks is:

if not Citizen.Await(SkyJobsReady) then return end

Retain it in the same position as the supplied file, before code using the job dependency. Merge your custom function bodies into the updated files; do not add this line inside every custom function. This is a bootstrap change, not a new editable setting.

Optional diagnostics are disabled by default. If support requests a recording, put setr sky_profiler 1 before the Sky ensure lines in server.cfg, then restart the server. Run profiler record 1000, wait for profiler status to show that recording has completed, then run profiler saveJSON sky-release-profile.json. Disable diagnostics with setr sky_profiler 0 and another server restart. This is not a /jobconfig setting; no recording or upload starts automatically.

For an older explicit profiler package, replace any previously modified public config/provider/compatibility files with the supplied versions and merge your intentional customizations. In this release package, profiler preparation preserves all files outside source/ byte for byte except fxmanifest.lua; the functional config changes listed in this guide still require their own merge.

  1. Data, items and dependencies

SQL: No new Mechanic table or column is introduced by this release. Keep existing orders, invoice links and vehicle mileage. Do not replay the full Mechanic import on an established database. Complete matching Base and Jobs Base migrations for the central Billing panel; existing mechanic invoices keep their own workflow.

Items/assets: No new item definition or streamed model is required by these changes. Existing mobile dyno, monitor, engine sound and carry-item names must still match your configured inventory. Replace the shipped UI, style and image files named in Changed Files. Keep your selected external vehicle properties and mileage provider configuration.

Providers: JG mileage is optional and requires jg-vehiclemileage v2.1.1+ started first. The ESX compatibility diagnostic reports unsupported upstream vehicle property support; it does not patch ESX or guarantee successful persistence. Follow the reported upstream compatibility requirement when this warning appears.

Dependencies: Install matching Sky Base 1.45.0 and Jobs Base 1.48.0 releases before Mechanicjob 1.34.0. Start framework/database/providers, Base, Jobs Base and then Mechanicjob; include the compatible JG resource before Mechanicjob only when that integration is enabled. Restart and reconnect clients.

  1. Restart and check

Start your framework, database connector and configured providers first, then Base, Jobs Base and the updated job resources in dependency order. Reconnect clients. Open a workshop and test automatic focus on the selected part, the player camera toggle, Space/manual control and live disabling. If JG is enabled, verify a loaded, zero and corrected odometer value and preserve the unconverted Sky history. Place a dyno/monitor through the configured routes and check saved interaction, slope/placement and blip settings. Invoice an unpaid public order and confirm the original customer, quote and permission checks; retry without creating a duplicate. Test the native mechanic invoice flow separately from the shared Sky Billing panel, print a record, reopen the tablet at its current view and check tuning prices/materials for two workshop jobs.

If a check fails, keep the update on staging and collect the installed resource versions, selected provider, effective saved setting and the first relevant startup or action error. A successful source test, build or copy does not establish live FiveM, provider or customer acceptance.

Version 1.33.1

Highlights

  • Changed Mechanic startup back to the previous shared-dependency loading behavior.

Notable Changes

  • Added missing English tuning labels and consolidated older handling-editor and Dyno translation files.

Other Changes

  • Updated the bundled Hungarian translations.

Changed Files

  • sky_mechanicjob/config/locales/*
  • sky_mechanicjob/fxmanifest.lua
  • sky_mechanicjob/source/* — delete and reinsert

Removed Files

  • sky_mechanicjob/config/locales/partials/handling_editor.lua
  • sky_mechanicjob/config/locales/partials/mobile_dyno.lua
Update InstructionsWhat to copy, what to keep and what to check1.33.01.33.1

Simplified update

Update sky_mechanicjob safely

Read the complete update instructions in one continuous guide.

  1. Prepare

These instructions cover sky_mechanicjob 1.33.0 → 1.33.1. Complete earlier migrations first if upgrading from an older version. Back up the database, resources, custom configuration and saved job/Creator data. Stop the server for the coordinated update. Install Base 1.44.1, then Jobs Base 1.47.1, then the matching hotfixes for your installed Sky jobs and Crime.

  1. Replace files

Use the 1.33.1 download. Delete the entire sky_mechanicjob/source/ folder and insert the new folder. Replace sky_mechanicjob/fxmanifest.lua from that same package. Refresh the complete sky_mechanicjob/config/locales/ tree and reapply custom translations. Keep the new source and manifest together; do not merge old generated interface files into them.

Remove these obsolete locale fragments after merging any custom translations into the matching language file: sky_mechanicjob/config/locales/partials/handling_editor.lua, sky_mechanicjob/config/locales/partials/mobile_dyno.lua.

  1. Keep settings

No configuration values or Job Configurator setting keys are added, removed or reset by this hotfix. Keep your current settings and saved overrides. Hungarian uses the existing Config.locale = "hu" setting in sky_base/config/config.lua; leave your selected language unchanged if you do not want to switch. Update the matching Base, Jobs Base and installed resource locale folders together.

Optional diagnostics stay disabled by default. If support requests a recording, put setr sky_profiler 1 before the Sky ensure lines in server.cfg, restart, run profiler record 1000, wait for profiler status to show completion, then run profiler saveJSON sky-hotfix-profile.json. Disable with setr sky_profiler 0 and another restart. This is not a /jobconfig option; nothing is recorded or uploaded automatically.

  1. Data and assets

No new SQL import, item definition, inventory image or stream asset is required for this hotfix. Keep saved job/Creator data; do not reset or reimport it. Required earlier migrations still apply when upgrading from an older release.

  1. Restart and check

Start your framework, database connector and configured providers first, then Base 1.44.1, Jobs Base 1.47.1 and the updated jobs/Crime. Reconnect clients. Open /jobconfig and check that the tuning menu loads and saves vehicle properties. If startup still fails, collect the first error and its preceding log lines together with the installed versions.

Version 1.33.0

Highlights

  • Fixed an issue where a visited workshop could offer tuning options from the visitor's job or the global defaults instead of its own restrictions.
  • Fixed an issue where repaired vehicles could still crawl without normal throttle response after engine damage.
  • Fixed an issue where Dyno results ignored installed performance upgrades or reused the calibration from an earlier run.

Notable Changes

  • Improved open tuning menus so configuration changes remove newly forbidden pending choices while retaining installed tuning and other permitted selections.
  • Fixed an issue where a basket containing disabled tuning options could proceed with only part of the requested work.
  • Fixed an issue where subscription-terminal NPC settings were overwritten by separate legacy settings after saving.
  • Fixed an issue where different Instant Tuning locations inherited the first NPC's heading.
  • Fixed an issue where saved Dyno installations moved when reloaded before world collision was available.

Other Changes

  • Improved Hungarian translations, including the handling editor and mobile Dyno, so older translation fragments no longer replace the selected language.
  • Added missing English labels for tuning options, including wheels, window tints, lights and performance upgrades.
  • Optimized workshop lift discovery to avoid repeatedly scanning the same world objects during one refresh.
  • Fixed an issue where custom workshop interaction consumers kept old settings after a configuration update.
  • Improved keyboard selection and accessibility in shared tablet dropdowns.
  • Updated vehicle documents to display times in 24-hour format.
  • Improved startup dependency loading and database-wait diagnostics for protected resource packages.

Changed Files

  • sky_mechanicjob/compat/sky_mechanicjob_repair_hotfix.lua
  • sky_mechanicjob/config/config.lua
  • sky_mechanicjob/config/locales/*
  • sky_mechanicjob/fxmanifest.lua
  • sky_mechanicjob/source/* — delete and reinsert

Removed Files

  • sky_mechanicjob/config/locales/partials/handling_editor.lua
  • sky_mechanicjob/config/locales/partials/mobile_dyno.lua
Update InstructionsWhat to copy, what to keep and what to check1.32.01.33.0

Simplified update

Update sky_mechanicjob safely

Read the complete update instructions in one continuous guide.

  1. Prepare the update

These instructions cover sky_mechanicjob 1.32.0 → 1.33.0. Complete earlier required migrations first if upgrading from an older version. Stop the server for the coordinated update and back up the database, resource files, customized configuration and saved job/Creator data. Install Base 1.44.0 first, then Jobs Base 1.47.0, then sky_mechanicjob 1.33.0 and the matching updates for your other installed Sky jobs. The updated manifest requires the matching Base and Jobs Base imports; do not combine it with older dependency folders.

  1. Replace the package files

Use the matching 1.33.0 package. Delete the complete old sky_mechanicjob/source/ folder and insert the new folder. Replace sky_mechanicjob/fxmanifest.lua from the same download. Refresh the entire sky_mechanicjob/config/locales/ tree and merge your custom translations back. Do not merge old generated interface files into the new source/ folder.

Merge the comment update in sky_mechanicjob/config/config.lua while preserving your workshop settings. Copy sky_mechanicjob/compat/sky_mechanicjob_repair_hotfix.lua to its packaged compat/ location. It is an optional compatibility file for older 1.32.0 installations; do not additionally install it into config/locales/partials/ for this full update, which already includes the repair fix. If you already used that drop-in on 1.32.0, it automatically skips its repair callback when the integrated fix is present. Delete the old sky_mechanicjob/config/locales/partials/handling_editor.lua and sky_mechanicjob/config/locales/partials/mobile_dyno.lua files. Their supplied translations are now included in the normal language files. Use the matching fxmanifest.lua, which no longer loads the old partials directory. Merge any custom text from those fragments into the corresponding normal locale table instead of restoring the old files or their manifest globs. If you maintain other custom files in that directory, move their translations into the corresponding normal locale files too. No file rename is required.

  1. Merge configuration and saved overrides

Hungarian language

Refresh the complete resource locale folder from this download, including hu.lua, and carry over your custom translations. To use Hungarian, set the existing Config.locale value to "hu" in sky_base/config/config.lua; its supplied default remains "en". Keep your current value if you are not changing language. This is the shared Sky language setting, so update the matching Base, Jobs Base and installed job locale folders together. Jobs Base supplies the Hungarian /jobconfig translations too. No new /jobconfig language setting, saved-job reset or database migration is required for this language addition. Apply the normal restart and reconnect steps at the end of this update.

In sky_mechanicjob/config/config.lua, the only file change is the guidance comment inside Config.Subscriptions.npc. No shipped value changes, new config tables, adv_config.lua edits or interaction capability flags are required. The existing defaults remain:

Config.Subscriptions.npc = {
    pedModel = "s_m_m_autoshop_01",
    scenario = "WORLD_HUMAN_CLIPBOARD",
    emote = { dict = "", clip = "" }
}

Keep your customized values rather than replacing them with this example. Previously these subscription-specific values could overwrite the terminal's edited NPC. They are now legacy plaintext/import defaults; customized interaction values in Config.Interactions.subscription_terminal.npc take priority. Set model through pedHash, scenario through scenario, and animation through animation.dict / animation.name. Leave the scenario empty to use an animation. For a server without /jobconfig, retain legacy values or move intentional customizations to those interaction fields; no bulk reset is needed.

With /jobconfig: After starting the updated resources, open Mechanic → Interactions → Subscription Terminal → NPC. The four old standalone settings are retired and automatically move to the interaction only where no explicit interaction override exists:

Old saved settingNew NPC field under __interactions.subscription_terminal.npc
subscriptionsNpcPedModelpedHash
subscriptionsNpcScenarioscenario
subscriptionsNpcEmoteDictanimation.dict
subscriptionsNpcEmoteClipanimation.name

Explicit interaction values, including empty scenario/animation strings, are preserved. The load migration is repeatable; the next normal save persists the new interaction overrides and removes the retired standalone keys. Review and save the effective NPC once. Do not edit the database, reset the job or reimport the whole configuration.

Workshop tuning restrictions: Existing per-job Config.Jobs[*].tuningCostProfile, managed as the job-owned tuningCostProfile extension, now determines the visited workshop's choices for staff and public customers. Its optionCostByOptionId settings remain unchanged. Existing disabled objects (enabled = false) and legacy literal false entries remain disabled. Existing global Config.ToggleFeatures.electronicTuning, .antiLag and .twoStep also apply when open menus refresh. Saved overrides remain authoritative. Recheck a normal and a restricted workshop separately; enabling an option in one workshop must not enable it in another. Instant Tuning keeps its separate profile. Already installed tuning is preserved when a newly forbidden pending selection is removed.

Dyno installation coordinates, headings and all Dyno/lift settings retain their current values. Saved Dyno positions are restored directly; correct an intentionally misplaced installation using its existing editor instead of deleting the stored installations.

Optional performance diagnostics

Extra profiler information remains disabled by default. If support requests a recording, add setr sky_profiler 1 to server.cfg before the Sky ensure lines and restart the server. In the server console, run profiler record 1000, wait until profiler status reports completion, then run profiler saveJSON sky-release-profile.json. Share the file only when requested. To disable the extra information, change the line to setr sky_profiler 0 and restart again. This is not a /jobconfig setting; enabling it does not record or upload anything automatically.

Keep source/ and fxmanifest.lua from the same download even when diagnostics are disabled. Profiler processing changes only source Lua and the manifest. If an older profiler package changed public files outside source/, restore those files once from the clean current download and reapply your own customizations.

  1. Apply SQL, inventory and asset updates

No Mechanic SQL migration, table/column type/default change, new inventory item, image or streamed asset is required. Existing subscriptions, invoices, orders, vehicle tuning and role grants are retained. The subscription NPC change migrates existing configurator values through the normal load/save path; it is not an SQL schema migration.

  1. Restart and verify

Start providers/framework, Base 1.44.0, Jobs Base 1.47.0 and Mechanic 1.33.0, then reconnect. Check subscription terminal model/scenario/animation after saving, reopening and restarting; test two Instant Tuning NPC locations with different headings. Check that an interaction save updates active workshop points.

At two workshops with different ECU permissions, test both staff and public customers. Change an option while the tuning menu is open: only a now-forbidden pending choice should be removed, installed tuning and other permitted selections should remain, and a rejected basket should not charge money. Compare Dyno runs on the same vehicle before/after engine or turbo upgrades and after removing them, including a second run without reconnecting. The Dyno remains a simulated estimate; this update does not calibrate it to real-world power figures. Restart/reopen a saved Dyno installation and check its exact position and heading. Damage and repair a vehicle using your actual repair provider, then verify normal throttle response and its selected engine sound. Check workshop lifts after streaming away/back and 24-hour vehicle-document times.

Version 1.32.0

Highlights

  • Added an “Invoice myself” option to the tuning basket for authorized mechanics at their own workshop.
  • Added deletion of unpaid tuning orders together with cancellation of their unpaid invoice, subject to the existing cancellation permissions.

Notable Changes

  • Fixed an issue where inspection and registration points did not open the vehicle records app or authorize an explicitly shared workshop correctly.
  • Fixed an issue where disabled tuning stages could still appear as available choices.
  • Fixed an issue where repairs and non-minigame installation work ignored the configured progress-bar provider or its cancellation result.
  • Fixed an issue where tuning invoice actions were offered without the required role permission or rejected correctly configured workshop names beginning with “society_”.
  • Improved invoice rejection messages so staff can identify missing permissions, duty requirements or the wrong workshop without losing their tuning basket.
  • Fixed an issue where invoice receipts with an empty item list could fail to display.

Other Changes

  • Added playback for video records opened in the shared document viewer.
  • Fixed an issue where select menus inside dialogs could appear behind the dialog or lose its focus scope.
  • Improved scaling of shared tablet controls, signatures and document views across screen resolutions.

Changed Files

  • sky_mechanicjob/fxmanifest.lua
  • sky_mechanicjob/config/config.lua
  • sky_mechanicjob/config/locales/*
  • sky_mechanicjob/source/* — delete and reinsert
Update InstructionsWhat to copy, what to keep and what to check1.31.01.32.0

Simplified update

Update sky_mechanicjob safely

Read the complete update instructions in one continuous guide.

  1. Prepare the update

If Fire Job is installed, take all breathing bottles out of vehicle bottle storage before stopping the old server. The Fire update cannot migrate its old live vehicle-state contents. Complete this pre-shutdown step before updating Base or Jobs Base.

These instructions cover sky_mechanicjob 1.31.0 → 1.32.0. Complete earlier required migrations first if upgrading from an older release. Stop the server for the coordinated update and back up the resource, database, customized configuration and saved job/creator settings. Install Base 1.43.0 first, then Jobs Base 1.46.0, then the matching installed job releases.

  1. Replace the package files

Use the matching 1.32.0 package. Delete the old sky_mechanicjob/source/ directory completely and insert the new directory. Replace sky_mechanicjob/fxmanifest.lua from the same package. Refresh the entire sky_mechanicjob/config/locales/ tree and merge your custom translations back. Merge sky_mechanicjob/config/config.lua as described in this view, preserving unrelated workshops, prices and custom values.

Do not merge old generated interface files into the new source/ directory.

  1. Merge configuration and saved overrides

Prepare file changes while the server is stopped. Perform the /jobconfig, Creator and other in-game actions described in this section after starting the updated resources in step 5, during maintenance and before admitting players.

Changed file: sky_mechanicjob/config/config.lua, Config.Interactions.vehicle_registry. The generated defaults mirror it. No adv_config.lua, SQL, item, stream asset or permission-ID migration exists.

Old block:

vehicle_registry = {
    public = false,
    interaction = false,
    unique = false,
    marker = { enabled = false },
    npc = { enabled = false },
    blip = { enabled = false }
},

New block:

vehicle_registry = {
    public = false,
    interaction = true,
    duty = true,
    interactionDistance = 2.5,
    unique = false,
    marker = { enabled = true, type = 1, offset = vector3(0.0, 0.0, 0.0) },
    npc = { enabled = false },
    blip = { enabled = true, sprite = 446, color = 5 }
},
  • Exact changed fields: interaction false -> true; duty absent -> true; interactionDistance absent -> 2.5; marker.enabled false -> true with new type = 1, offset = vector3(0.0, 0.0, 0.0); blip.enabled false -> true with new sprite = 446, color = 5. public = false, unique = false, npc.enabled = false remain unchanged.
  • /jobconfig resource: sky_mechanicjob. This is an interaction definition at interactions.vehicle_registry, not a new individual feature switch. There is no vehicleRegistryInteraction setting. Definitions/capability flags and actual saved Workshop locations are different objects.
  • Existing feature keys are kuv and vehicleRegistration (Config.ToggleFeatures.kuv / .vehicleRegistration), both default false and unchanged. At least one must be enabled for the service point. The service-point interaction follows those feature switches; disabling both removes it.
  • Review saved interaction/location display overrides in the Mechanic Interaction System and Workshops area. Existing saved disabled marker/blip choices remain intentional overrides; defaults alone do not force them visible. Place/retain the actual vehicle_registry point in the desired workshop, review marker/blip visibility and workshop sharing for the intended job. No reset or destructive reimport is required.
  • New self-invoices use existing job billingSettings / fallback Config.Billing settings: enabled, allowTuningInvoices and allowImmediatePayment, plus duty, own workshop and the role's existing Create invoices permission. No new config setting is added. Exact configured job names beginning with society_ must be retained; do not rename jobs/accounts for this fix.
  • Unpaid-order deletion requires existing Cancel invoices permission and effective rank allowCancellation. It is not unrestricted deletion and does not refund paid/open orders through this path. Closing a receipt still leaves the order pending.
  • Progress provider selection remains in sky_base/config/config.lua (Config.progressbar), not a new Mechanic option or /jobconfig key. Update Base with the job; verify the configured provider during the installation check.
  • Dependencies: Base 1.43.0, Jobs Base 1.46.0, then Mechanic 1.32.0.

Optional performance diagnostics

Extra profiler information is disabled by default. If support requests a recording, add setr sky_profiler 1 to server.cfg before the Sky ensure lines and restart. In the server console, run profiler record 1000, wait until profiler status reports completion, then run profiler saveJSON sky-release-profile.json. To disable the extra information, use setr sky_profiler 0 and restart. This is not a /jobconfig setting. Enabling it does not start recording or upload anything automatically.

Keep source/ and fxmanifest.lua from the same download even when diagnostics are disabled. Profiler processing changes only source Lua and the manifest; public configuration and provider files remain unchanged by that processing. If an older profiler package altered files outside source/, restore those once from the current download and reapply your own customizations.

  1. Apply SQL, inventory and asset updates

No Mechanic SQL, inventory item, image or stream migration is required. Keep existing data and role grants. The new source provides the runtime changes; /jobconfig does not install source files or manifests.

  1. Restart and verify

Start framework/providers, Base 1.43.0, Jobs Base 1.46.0 and Mechanic 1.32.0, then reconnect. Test the placed inspection/registration point and a deliberately shared workshop. Check an authorized customer invoice, self-invoice and unpaid-order deletion, plus a role without invoice permission. Closing a receipt must leave its order pending. Test cancellation with the configured progress provider and confirm cancelled work does not install parts or complete a repair.

If a separate invoice-creation window remains invisible, provide the first F8 NUI error and the installed versions. The empty-item receipt correction does not establish the cause of every window-opening problem.

Version 1.31.0

Update Base to 1.42.0 and Jobs Base to 1.45.0 before installing sky_mechanicjob1.31.0.

Highlights

  • Added File Explorer directories for workshop vehicles, orders, invoices and subscriptions, with shared documents grouped by the issuing job.
  • Added Print and Share actions for saved workshop vehicles, orders and invoices, with explicit recipients and read-only access for receiving jobs.
  • Added payment of mechanic invoices from an authorized customer company account, including refunds to the original paying company.
  • Improved radial invoicing with a dedicated invoice printer, multiple catalogue reasons, multiline notes and matching customer receipts.

Notable Changes

  • Fixed an issue where on-duty staff could not invoice a customer from their own configured workshop tuning point.
  • Added temporary preservation of unsubmitted staff tuning baskets when closing and reopening the same vehicle at the same workshop.
  • Fixed an issue where closing the Stance Kit discarded authorized stance adjustments.
  • Fixed an issue where accepted vehicle tuning and electronic settings were lost or not reapplied after restarting the Mechanic resource.
  • Fixed an issue where anti-lag flames appeared at hidden stock exhausts instead of the installed exhaust outlets.
  • Fixed an issue where real plates containing spaces stopped matching vehicle keys after fake-plate compatibility handling.
  • Fixed an issue where saving a vehicle profile could restore recipients that another worker had revoked.
  • Fixed an issue where carried parts or parts-delivery boxes could be deposited without warehouse access; denied deposits now preserve the carried stock and delivery state.

Other Changes

  • Fixed an issue where custom performance-stage item quantities, including one item, were replaced when saving or reopening the configurator.
  • Improved workshop record updates while preserving unsaved input, and added clearer vehicle color values with RGB copying.
  • Optimized dyno updates to avoid repeatedly sending unchanged session data and completed results.
  • Optimized workshop configuration saves so unchanged creator settings and billing templates are left in place.
  • Improved workshop directories, subscriptions, tags, filters and form readability across screen sizes.
  • Fixed an issue where an older invoice response could change the currently displayed receipt, and kept paid receipts open until closed.

Changed Files

  • sky_mechanicjob/source/* — delete and reinsert
  • sky_mechanicjob/config/locales/*
  • sky_mechanicjob/compat/fakeplates.lua
  • sky_mechanicjob/compat/fakeplates_realplate_native.lua
  • sky_mechanicjob/fxmanifest.lua
  • sky_mechanicjob/import.sql
Update InstructionsWhat to copy, what to keep and what to check1.30.01.31.0

Simplified update

Update sky_mechanicjob safely

Read the complete update instructions in one continuous guide.

  1. Prepare

These instructions cover 1.30.0 → 1.31.0. Complete older required migrations first if upgrading from an earlier version. Stop the server and back up the database, resource, customized files and saved job/creator data. Install Base 1.42.0 first, then Jobs Base 1.45.0 with its own SQL, inventory and printer requirements, then sky_mechanicjob 1.31.0.

  1. Replace files

Install the matching 1.31.0 package and replace these delivered paths:

  • sky_mechanicjob/source/* — delete and reinsert
  • sky_mechanicjob/config/locales/*
  • sky_mechanicjob/compat/fakeplates.lua
  • sky_mechanicjob/compat/fakeplates_realplate_native.lua
  • sky_mechanicjob/fxmanifest.lua
  • sky_mechanicjob/import.sql

Delete the old sky_mechanicjob/source/ directory and insert the complete new one, including its UI. Replace the complete locale directory. Preserve unrelated writable data and customized public configuration. There are no additional deleted or renamed package paths outside source/ in this release.

Always replace source/* and fxmanifest.lua from the same download, even with diagnostics off. The profiler may instrument only source Lua and the generated manifest; public configuration and compatibility files must match the uninstrumented release source. If an older profiler package modified public files, restore those once from the clean new package and reapply your custom edits.

  1. Configuration and access

No options are added, removed or given new defaults in sky_mechanicjob/config/config.lua or config/adv_config.lua for this update. Preserve your job and workshop configuration. File Explorer and the saved-record Print/Share actions become available with Jobs Base 1.45.0; no separate activation flag or record import is required. Vehicle records, orders, invoices and subscriptions retain their app restrictions and role permissions. Own-record actions require an on-duty authorized worker. A recipient sees an explicitly shared record read-only. Other jobs use Shared Documents under the issuing workshop; existing explicit vehicle recipients are retained, while the old Jobs Base Share-tab record/link rules no longer grant document access. DOJ is optional and is needed only for DOJ-origin documents.

Shared-storage permissions: Keep the existing warehouse and full-access role settings. This correction requires no new configuration key, SQL step, permission ID or role reassignment. Update Jobs Base 1.45.0 and any installed Mechanic Job 1.31.0 together so shared storage and workshop deposits use the matching checks. Personal lockers, trunks and custom storage are outside this shared-storage refresh change.

Billing: The existing per-job Config.Jobs[*].billingSettings / /jobconfig Billing extension remains authoritative. Keep enabled, radialEnabled, allowTuningInvoices and allowImmediatePayment enabled for the corresponding workflows; retain your existing customer range and amount limits. Config.Billing remains the plaintext fallback for jobs without those values. There is no new company-payment switch or permission ID. Pay with Company is shown only to the actual invoice recipient whose current registered, active job grants Manage money and differs from the issuing workshop. It uses that company's balance and does not fall back to personal cash or bank funds. Ordinary invoices retain their configured instalment policy; tuning invoices require full payment before installation. Refunds of company-funded tuning go back to the original paying company, even if the customer changes jobs or is offline.

Tuning materials: Explicit quantities in the existing /jobconfig per-job tuningCostProfile extension, including quantity one, are now preserved. If an earlier version overwrote a custom quantity, enter the intended values again and save after this update; the old intended amounts cannot be recovered automatically. Old bare item-name defaults still migrate. No new setting or SQL migration is needed for this correction.

Workshop and vehicle state: An unsubmitted staff basket survives closing and reopening the same live vehicle at the same workshop during the current client session. It does not survive character logout, reconnect, resource restart or vehicle removal, and it does not save unpaid changes to the vehicle. Separately, already accepted runtime tuning can survive a Mechanic resource stop/start while the same vehicle exists; that is not persistence across a full server restart. The Stance Kit saves authorized changes when closed. Existing self-service interaction capability flags and saved per-location vehicle class restrictions are unchanged; do not add new capability flags as ordinary saved settings.

Document printing: Complete the Jobs Base 1.45.0 SQL and printer setup before using Print. The active inventory must support item metadata. Merge the supplied job_document entry from sky_jobs_base/config/inventory/items_ox.lua into your active inventory; for Ox Inventory, put it inside the existing ox_inventory/data/items.lua table and copy sky_jobs_base/config/inventory/job_document.png to ox_inventory/web/images/job_document.png:

["job_document"] = {
    label = "Document",
    weight = 10,
    stack = false,
    close = true,
    consume = 0,
    description = "Printed copy of a job record.",
    client = { image = "job_document.png" },
},

In sky_jobs_base/config/printers.lua, keep Config.Printers.enabled = true and enable this resource in Config.Printers.resources. Configure a printer in /jobconfig → the job → Locations, then review the existing job printerSettings. paperEnabled and inkEnabled remain off by default; register and supply printer_paper or printer_ink only when the corresponding consumption setting is enabled. Saved records can be printed only when access and printer checks pass. The requester collects the finished item at the printer. A collected paper copy remains readable after the corresponding digital share is revoked. Printing is optional; it is not needed to browse or share records. Editing Ambulance or Mechanic configuration does not install these shared items or tables. For Mechanic, Config.Printers.resources.sky_mechanicjob = true is newly supplied by Jobs Base 1.45.0; add that entry to a customized existing resources table.

Optional performance diagnostics: Extra profiler information remains off by default. To make a support recording, put setr sky_profiler 1 in server.cfg before the Sky ensure lines and restart the server. Run profiler record 1000 in the server console, wait for profiler status to report completion, then run profiler saveJSON sky-release-profile.json. Share the file only when requested. To disable the extra information, use setr sky_profiler 0 and restart again. This is not a /jobconfig setting; enabling it does not record or upload anything automatically.

  1. SQL, assets and inventory

SQL: Back up the database. With the existing plaintext Config.AutoExecuteQuery = true, startup adds the two columns. If it is false, apply these matching statements from sky_mechanicjob/import.sql before using the new release:

ALTER TABLE `sky_mechanic_invoice_payments`
    ADD COLUMN IF NOT EXISTS `payer_job` VARCHAR(64) NULL;
ALTER TABLE `sky_mechanic_vehicle_profiles`
    ADD COLUMN IF NOT EXISTS `sharing_revision` BIGINT UNSIGNED NOT NULL DEFAULT 0;

payer_job records the company for each invoice payment; existing rows remain valid with NULL. sharing_revision protects vehicle recipient changes from stale edits, starting at zero for existing profiles. Existing profiles, recipients, invoices and tuning orders are retained. Jobs Base 1.45.0 also needs its own shared-record and printed-document tables; apply that dependency's migration first. Do not reset or delete business records. /jobconfig does not install SQL.

Inventory and assets: No Mechanic item, image outside the UI bundle, stream model or tuning-material definition is added or renamed. Replace the full UI through source/* and all locales. Optional record printing uses the Jobs Base job_document item/image and the job's configured printer supplies.

Fake-plate compatibility: Replace sky_mechanicjob/compat/fakeplates.lua and sky_mechanicjob/compat/fakeplates_realplate_native.lua. Restart the garage/key resources that load these compatibility files after Mechanic starts. Real plates such as ABC 123 must retain their internal space through keys, fake-plate application/removal and garage storage. Fake-plate input validation is unchanged. Previously compacted stored real plates cannot be reconstructed reliably by inserting guessed spaces; compare an affected entry with its original owned-vehicle record.

  1. Restart and verify

Restart the database/framework and any changed inventory first, then Base 1.42.0, Jobs Base 1.45.0 and Mechanic 1.31.0, followed by garage/key resources loading the updated fake-plate compatibility files. Confirm versions and resolve migration errors before admitting players. With two workers, test vehicle-share grant/revoke conflicts and verify an ordinary profile save cannot restore revoked recipients. Open File Explorer and verify vehicle, order, invoice and subscription access plus a receiving job's read-only view. If printing is configured, print, collect and open a document. Issue a radial invoice with multiple reasons; test cash, card, authorized company payment, insufficient company funds and a tuning refund back to the original company. Verify the workshop receives the payment through the configured banking adapter. At a real workshop point, select tuning, close/reopen, invoice the nearby customer, pay in full and install. Reopen the Stance Kit after closing and restart only Mechanic with the same tuned vehicle present. Check a mixed-space real plate through keys, fake-plate removal and garage storage, plus anti-lag on stock and modified exhausts. Run a dyno session with an observer. Save/reopen custom quantity-one stages in /jobconfig.

Shared-storage role check: Use a regular employee role with warehouse access, not the highest rank or a full-access role, since those retain their existing bypass. Confirm that permitted stock can be transferred. Remove warehouse access through role management while storage is open: it must close, and reopening or transferring stock must be denied. Restore access and reopen without reconnecting. Restrict an item and a weapon for that role, then verify that withdrawals are blocked, including a weapon whose stored name uses different capitalization and any supported carried-item withdrawal. The restriction list blocks withdrawal; it does not reserve stock for that role. Deposits still require warehouse access. With access retained, change a restriction and confirm that the open view updates without losing the current selection or entered quantities.

Carried-parts deposit check: With an on-duty employee carrying a part, revoke warehouse access and attempt to deposit it into shared storage. Repeat with a parts-delivery box. Each denied deposit must leave the carried stock and delivery state unchanged. Restore warehouse access and confirm that both deposits succeed without reconnecting.

Version 1.30.0

Update Base to 1.41.0 and Jobs Base to 1.44.0 before installing sky_mechanicjob1.30.0.

Highlights

  • Added tuning invoices for nearby customers, with installation becoming available only after the invoice is paid in full.
  • Added an invoice action to the mechanic radial menu and per-workshop controls for invoicing and customer distance.
  • Added nearby vehicle capture and nearby owner selection when creating workshop vehicle records.

Notable Changes

  • Fixed an issue where repair-kit animations could start for a vehicle outside the configured repair range or continue after a rejected repair.
  • Improved vehicle pushing with gentler wheel steering while keeping forward and backward movement separate.
  • Improved workshop vehicle records by separating the actual model from its displayed name and filling in the vehicle plate during capture.
  • Optimized workshop order loading to reduce unnecessary server work when viewing orders.
  • Improved engine-hoist placement updates after workshop settings are changed.

Other Changes

  • Added missing inventory images for drift tyres, blank plates, fake-plate kits, plate printers and plate scanners.
  • Optimized nearby-vehicle capture for areas containing many vehicles.
  • Updated translations and tuning checkout feedback for customer invoices and nearby vehicle records.

Changed Files

  • sky_mechanicjob/config/adv_config.lua
  • sky_mechanicjob/config/config.lua
  • sky_mechanicjob/config/inventory/blank_plate.png
  • sky_mechanicjob/config/inventory/drift_tyres.png
  • sky_mechanicjob/config/inventory/fake_plate_kit.png
  • sky_mechanicjob/config/inventory/plate_printer.png
  • sky_mechanicjob/config/inventory/plate_scanner.png
  • sky_mechanicjob/config/locales/*
  • sky_mechanicjob/fxmanifest.lua
  • sky_mechanicjob/source/* — delete and reinsert
Update InstructionsWhat to copy, what to keep and what to check1.29.11.30.0

Simplified update

Update sky_mechanicjob safely

Read the complete update instructions in one continuous guide.

  1. Prepare the update

Update Base to 1.41.0 and Jobs Base to 1.44.0 before installing sky_mechanicjob 1.30.0. These instructions cover 1.29.1 → 1.30.0; complete earlier migrations first when upgrading from an older version. Stop the server and back up the resource, database, customized files and saved configurator/creator data.

  1. Replace the package files

Install the matching 1.30.0 download. Update every path in Changed Files, delete and reinsert sky_mechanicjob/source/*, and replace sky_mechanicjob/config/locales/* completely. Remove the exact paths under Removed Files and apply any listed renames. Preserve unrelated files, writable data and custom assets; merge the configuration changes in this tab into your customized public files.

Replace source/* and fxmanifest.lua from the same download even when optional diagnostics remain off. Profiler instrumentation is confined to Lua in source/ and the generated manifest. Public configuration, integration and compatibility files match the uninstrumented source; their functional changes are listed separately for this release. If an older profiler package modified public files, restore those once from the clean new package and reapply your own edits.

  1. Merge configuration

In sky_mechanicjob/config/config.lua, add the following three fields to each relevant Config.Jobs[*].billingSettings table and to the existing Config.Billing fallback table. All three fields were absent in 1.29.1:

radialEnabled = true,
allowTuningInvoices = true,
customerRange = 8.0,

With /jobconfig, edit Mechanic → job → Billing: Invoice radial action (billingSettings.radialEnabled), Invoice tuning customers (billingSettings.allowTuningInvoices) and Customer distance (billingSettings.customerRange, 1–20 m). Keep existing explicit job settings. Config.Billing is the file-based compatibility fallback for missing per-job billing fields; it is not a second global configurator section.

Billing and immediate payments must be enabled. The mechanic must be on duty and have the existing CREATE_BILLING permission. A normal tuning invoice is sent to the nearest other eligible player within range; check the recipient before issuing it. The linked order remains unavailable until full payment, even if ordinary invoices allow partial payment. Cancelling the unpaid invoice closes its blocked order. Public self-service, instant tuning and administrator tuning retain their own checkout flows.

In sky_mechanicjob/config/adv_config.lua, remove Config.VehiclePush.steeringDegreesPerSecond (previous default 34.0). Steering now uses limited wheel movement; there is no replacement setting and no saved configurator key to migrate. Keep the other VehiclePush values.

Nearby owner selection associates a workshop record with a character. It does not transfer legal framework vehicle ownership. No other configuration values change.

Optional performance diagnostics

Extra profiler information remains disabled by default. For a support recording, add setr sky_profiler 1 to server.cfg before the Sky ensure lines and restart the server. In the server console, run profiler record 1000, wait for profiler status to report completion, then run profiler saveJSON sky-release-profile.json. Share that file when requested by support. Set setr sky_profiler 0 and restart again to disable the extra information. This is not a /jobconfig setting; enabling it does not start a recording or upload data automatically.

  1. Apply data and inventory updates

No database migration or new item type is required. Existing invoice and order storage supports the new payment state. Copy the new images from sky_mechanicjob/config/inventory/ to the matching image directory of your inventory if you use drift_tyres, blank_plate, fake_plate_kit, plate_printer or plate_scanner. Preserve existing item definitions, workshop orders, invoices and vehicle records.

  1. Restart and verify

Restart the database, framework and any edited inventory first, then Base, Jobs Base and the installed job resources. Confirm 1.30.0 and resolve startup errors before admitting players. With two players, send a tuning invoice, pay it in full and install the order. Verify that an unpaid or cancelled invoice cannot release installation. Check the selected recipient, range, cash/card payment and workshop income. Capture a nearby vehicle and owner without changing legal ownership, try a repair at the configured distance, push a vehicle gently in both directions and inspect stock quantities in an order.

Hotfix

Version 1.29.1

Update Base to 1.40.1 and Jobs Base to 1.43.1 before installing Mechanic 1.29.1.

Highlights

  • Fixed an issue where workshops without engine hoist locations repeatedly requested workshop data, creating unnecessary network traffic.

Notable Changes

  • Removed repeated workshop requests while waiting for the initial workshop setup to become available; later location changes still apply automatically.
  • Changed missing engine hoists to be restored when a player takes them or a workshop update arrives, removing the periodic background check.

Other Changes

No additional changes.

Changed Files

  • sky_mechanicjob/fxmanifest.lua
  • sky_mechanicjob/source/* — delete and reinsert
Update InstructionsWhat to copy, what to keep and what to check1.29.01.29.1

Simplified update

Update sky_mechanicjob safely

Read the complete update instructions in one continuous guide.

  1. Prepare the update

These instructions cover 1.29.0 to 1.29.1. Complete earlier updates first when upgrading from an older version. Stop the server and back up the resource, database, customized files and saved workshop settings. Install Base 1.40.1 and Jobs Base 1.43.1 before Mechanic 1.29.1.

  1. Replace the runtime files

Delete the old sky_mechanicjob/source folder and insert the complete replacement from the 1.29.1 package. Replace sky_mechanicjob/fxmanifest.lua from the same package. Preserve existing configuration, locales, compatibility files and persistent data outside source.

  1. Keep the existing workshops

No manual configuration values or saved /jobconfig settings change. Existing workshop shops and engine hoist locations do not need to be recreated. No SQL, item or locale migration is required, and the database must not be reset or reimported for this hotfix.

  1. Restart and verify

Start Base, Jobs Base and Mechanic in that order and confirm Mechanic 1.29.1. Test a workshop without an engine hoist, then place, move and remove a hoist through /jobconfig. Verify that the changes appear for connected players and that taking an existing hoist works. Check server and client logs for recurring timeout errors.

Version 1.29.0

Update Base to 1.40.0 and Jobs Base to 1.43.0 before installing sky_mechanicjob1.29.0. Vehicle documents also require Mechanic 1.29.0 and Police 1.32.0 together.

Highlights

  • Added optional vehicle inspections with car and motorcycle checklists, expiry dates, reinspection fees and signed reports.
  • Added optional vehicle registration, ownership transfers and deregistration with owner consent and permanent document history.
  • Improved vehicle records with nearby-customer selection, compact details, separate history and signed document previews.

Notable Changes

  • Fixed an issue where vehicle records could keep the plate field locked when creating a new entry after viewing another vehicle.
  • Fixed an issue where electronic tuning options could disappear from saved instant-tuning price profiles.
  • Fixed an issue where saved tuning could overwrite vehicle extras restored by a garage.
  • Fixed an issue where nearby observers or delayed garage restoration could overwrite live engine-sound changes and previews.
  • Improved dynamometer engine-speed synchronization for nearby observers.
  • Fixed an issue where Handling Editor diagnostics bypassed the central debug settings, including messages on player disconnect.
  • Fixed an issue where switching propulsion settings did not consistently apply the requested driven wheels.
  • Fixed an issue where resetting ECU effects on an aircraft could apply an unsuitable vehicle effect.
  • Added a confirmation for eight-gear handling settings that explains the live gear limit before applying them.
  • Added confirmed invoice income to the organization finance history.

Other Changes

  • Improved invoice and subscription layouts and kept vehicle-record panels readable across tablet themes.
  • Optimized repeated ECU, engine-sound, lighting and Two-Step checks while keeping installed tuning active.
  • Removed unnecessary synchronization diagnostics while retaining validation and persistence.
  • Updated bundled tuning and interface images with smaller files.

Changed Files

  • sky_mechanicjob/config/config.lua
  • sky_mechanicjob/config/inventory/air_filter.png
  • sky_mechanicjob/config/inventory/antilag_kit.png
  • sky_mechanicjob/config/inventory/armor_plating.png
  • sky_mechanicjob/config/inventory/body_kit.png
  • sky_mechanicjob/config/inventory/brake_fluid.png
  • sky_mechanicjob/config/inventory/brakes.png
  • sky_mechanicjob/config/inventory/catalytic_converter.png
  • sky_mechanicjob/config/inventory/ecu_tuning_kit.png
  • sky_mechanicjob/config/inventory/engine.png
  • sky_mechanicjob/config/inventory/engine_coolant.png
  • sky_mechanicjob/config/inventory/engine_oil.png
  • sky_mechanicjob/config/inventory/engine_sound_kit.png
  • sky_mechanicjob/config/inventory/fix_kit.png
  • sky_mechanicjob/config/inventory/inverter.png
  • sky_mechanicjob/config/inventory/lug_wrench.png
  • sky_mechanicjob/config/inventory/mobile_dyno.png
  • sky_mechanicjob/config/inventory/mobile_dyno_monitor.png
  • sky_mechanicjob/config/inventory/nitro_kit.png
  • sky_mechanicjob/config/inventory/rgb_controller.png
  • sky_mechanicjob/config/inventory/spark_plugs.png
  • sky_mechanicjob/config/inventory/spray_can.png
  • sky_mechanicjob/config/inventory/stance_kit.png
  • sky_mechanicjob/config/inventory/suspension.png
  • sky_mechanicjob/config/inventory/traction_battery.png
  • sky_mechanicjob/config/inventory/transmission.png
  • sky_mechanicjob/config/inventory/transmission_fluid.png
  • sky_mechanicjob/config/inventory/turbo.png
  • sky_mechanicjob/config/inventory/vehicle_lights.png
  • sky_mechanicjob/config/inventory/vehicle_wax.png
  • sky_mechanicjob/config/inventory/wash_sponge.png
  • sky_mechanicjob/config/inventory/wheels.png
  • sky_mechanicjob/config/locales/*
  • sky_mechanicjob/fxmanifest.lua
  • sky_mechanicjob/import.sql
  • sky_mechanicjob/source/* — delete and reinsert
  • sky_mechanicjob/vehicle_registry.sql
Update InstructionsWhat to copy, what to keep and what to check1.28.01.29.0

Simplified update

Update sky_mechanicjob safely

Read the complete update instructions in one continuous guide.

  1. Prepare the update

Update Base to 1.40.0 and Jobs Base to 1.43.0 before installing sky_mechanicjob 1.29.0. Vehicle documents also require Mechanic 1.29.0 and Police 1.32.0 together. These instructions cover 1.28.0 → 1.29.0; complete earlier migrations first when upgrading from an older version. Stop the server and back up the resource, database, customized files and saved configurator/creator data.

  1. Replace the package files

Install the matching 1.29.0 package. Update every path in Changed Files, delete and reinsert sky_mechanicjob/source/*, and replace sky_mechanicjob/config/locales/* completely. Remove every exact path listed under Removed Files and apply any listed renames. Preserve unrelated files, writable data and your own custom assets; merge the configuration changes in this tab into customized public files.

Replace source/* and fxmanifest.lua from the same download even when optional diagnostics remain off. The profiler only instruments Lua inside source/ and adds its manifest entries; public configuration, integration and compatibility files must match the uninstrumented package. Apply the separate functional public-file changes listed for this release. If an older profiler package modified public files, restore those once from the clean new package and reapply your edits.

  1. Merge configuration

Merge these additions into sky_mechanicjob/config/config.lua. Paste assignments after their corresponding existing parent table declarations. Both new features are disabled by default. Every path in this table was absent in 1.28.0:

Exact pathNew default/jobconfig key
Config.ToggleFeatures.kuvfalsekuv
Config.ToggleFeatures.vehicleRegistrationfalsevehicleRegistration
Config.KUV.validityDays30registryKuvValidityDays
Config.KUV.warningDays2registryKuvWarningDays
Config.KUV.fee500registryKuvFee
Config.KUV.reinspectionFee200registryReinspectionFee
Config.KUV.maxDistance6.0registryDistance
Config.KUV.sessionSeconds600registrySessionSeconds
Config.KUV.vehicleTypes{"automobile", "bike"}registryVehicleTypes
Config.KUV.carChecks{"identity", "engine", "body", "tyres", "lights", "brakes", "modifications"}registryCarChecks
Config.KUV.bikeChecks{"identity", "engine", "tyres", "lights", "brakes", "modifications"}registryBikeChecks
Config.VehicleRegistration.requireKuvtrueregistryRequireKuv
Config.VehicleRegistration.fee250registryRegistrationFee
Config.VehicleRegistration.transferFee150registryTransferFee
config/config.lua
Config.ToggleFeatures.kuv = false
Config.ToggleFeatures.vehicleRegistration = false
config/config.lua
Config.KUV = {
    validityDays = 30, -- Real-time days; configurable in /jobconfig.
    warningDays = 2,
    fee = 500,
    reinspectionFee = 200,
    maxDistance = 6.0,
    sessionSeconds = 600,
    vehicleTypes = { "automobile", "bike" },
    carChecks = { "identity", "engine", "body", "tyres", "lights", "brakes", "modifications" },
    bikeChecks = { "identity", "engine", "tyres", "lights", "brakes", "modifications" }
}
config/config.lua
Config.VehicleRegistration = {
    requireKuv = true,
    fee = 250,
    transferFee = 150
}

Also add the complete new interaction definition. All six leaf values are new and false: Config.Interactions.vehicle_registry.public, .interaction, .unique, .marker.enabled, .npc.enabled, and .blip.enabled. This is the service-point capability definition; changing it does not create a workshop location:

config/config.lua
Config.Interactions.vehicle_registry = {
        public = false,
        interaction = false,
        unique = false,
        marker = { enabled = false },
        npc = { enabled = false },
        blip = { enabled = false }
    }

For managed settings, open /jobconfig > sky_mechanicjob > Settings and search for the inspection/registration fields using the exact keys above. Saved overrides take precedence; missing values use the new defaults. With Config.UseJobConfigurator = false, maintain the Lua values directly. Enable only the services you want to offer.

Create a Vehicle inspection / registration point (vehicle_registry) in the workshop's Locations editor and assign it to the intended job. The vehicle must be at that point within the configured distance. Grant the relevant role permissions: 1401 reads records, 1402 performs inspections, 1403 handles registration/deregistration, and 1404 revokes documents issued by that job. Staff must be on duty. The actual owner must be nearby and confirm with a drawn signature; selecting a nearby customer does not replace owner consent.

The defaults give inspections 30 real days of validity, a two-day warning and a ten-minute session. Registration requires a valid inspection by default. Changing validity affects new documents; it does not renew an old certificate. Ownership transfers require the registration workflow. Fees use normal Mechanic invoices, including applicable billing settings; an issued document is not proof that its invoice was paid. No additional direct payment is required by this update.

Saved instantTuningProfile.optionCostByOptionId profiles now regain missing electronic-option entries from shipped defaults during loading/import. Existing prices remain unchanged. Review the completed price list in /jobconfig after updating; no manual profile reset is required. Dyno ground settings already shipped in 1.28.0 do not require another migration.

Removed diagnostic setting: Config.HandlingEditor.debugEnabled changes from false to removed. Delete that property from a customized sky_mechanicjob/config/config.lua. Its /jobconfig key handlingEditorDebugEnabled is also retired; existing saved overrides are ignored, so no SQL deletion or settings reset is required. Detailed Handling Editor traces now follow Sky Base's central debug level. For support diagnostics, enable Config.debugLevels.debug in sky_base/config/config.lua, then restart Base and dependent resources. Restore it to its unchanged default false afterward. Keep Config.debug and Config.debugLevels.all at their unchanged default false when selecting individual levels. These Base settings are maintained in files, outside /jobconfig.

The existing Handling Editor performance controls remain unchanged: Config.HandlingEditor.performanceChecksEnabled = true, Config.HandlingEditor.performanceWarningMs = 25, Config.HandlingEditor.payloadWarningBytes = 262144, and Config.HandlingEditor.performanceSummaryIntervalMs = 60000. Threshold warnings now respect Base's central warning level; enabling debug is not required for those warnings.

Optional performance diagnostics

Extra profiler information remains disabled by default. Normal use needs no diagnostic setting. For a support recording, add setr sky_profiler 1 to server.cfg before the Sky ensure lines and restart the server. In the server console, run profiler record 1000, wait for profiler status to report completion, then run profiler saveJSON sky-release-profile.json. Share that file only when requested by support. Set setr sky_profiler 0 and restart again to disable the extra information. This is not a /jobconfig option; enabling it does not start a recording or upload data automatically.

  1. Apply data and inventory updates

Back up the vehicle, registry and invoice tables. The normal Mechanic startup migration adds sky_mechanic_invoices.registry_operation_id CHAR(36) NULL and unique index uniq_mechanic_registry_operation when Config.AutoExecuteQuery = true.

With automatic SQL disabled, run the shipped sky_mechanicjob/vehicle_registry.sql against the existing game database. Merely rerunning the invoice CREATE TABLE IF NOT EXISTS in import.sql does not add this column to an existing table. For new installations, the updated import.sql includes it.

Complete the Base owned-vehicle identifier upgrade and import sky_jobs_base/vehicle_registry.sql when Jobs Base automatic SQL is disabled. The shared finance update also needs sky_jobs_logs.payment_reference and its unique index; follow Jobs Base 1.43.0 before starting Mechanic. Keep existing ownership, tuning, invoice and document data. No new items are required. Never clear the registry, regenerate vehicle IDs or issue old certificates automatically to resolve a migration error.

  1. Restart and verify

Confirm version 1.29.0 and all schema migrations. Leave both new switches off until a test workshop, permissions and service point are ready. With the owner nearby, issue an inspection, sign it, register the vehicle and inspect the history from Mechanic and Police. Check expiry, owner rejection, off-duty rejection and one invoice per operation. Verify the actual society credit separately from document issuance. Then test an existing instant-tuning profile, a garage vehicle with extras, propulsion changes and the eight-gear confirmation. With two clients, test engine-sound preview, cancellation and saved restoration after a garage spawn, streaming away/back and a change of vehicle controller. Check that a nearby dynamometer observer sees the current engine revs. With central debug disabled, verify that ordinary Handling Editor use and player disconnect do not force debug traces; enable the debug level for a support trace and restore it afterward.

Version 1.28.0

Update sky_base to 1.39.0 and sky_jobs_base to 1.42.0 before installing sky_mechanicjob1.28.0.

Highlights

  • Improved tuning saves so confirmed purchases and completed installations update the vehicle's garage record before it is parked.
  • Fixed an issue where cancelling a paint preview could change unrelated vehicle settings or fail to restore the original color.
  • Fixed an issue where changing a vehicle's drivetrain could leave it unable to move.

Notable Changes

  • Fixed an issue where saved handling changes could be lost when a vehicle was restored or entered again.
  • Added an option to disable the handling editor and its automatic vehicle rules while keeping the rest of the mechanic job available.
  • Improved gear-count editing by explaining unsupported changes before they can be saved and preserving unchanged factory gear counts.
  • Improved engine-sound previews and synchronization so cancelled changes restore the original sound and saved changes reach nearby vehicles.
  • Added separate Extras and Liveries sections under the tuning menu's More button.
  • Improved the tuning basket with clearer failure messages and disabled payment buttons while a purchase is being processed.
  • Changed mobile dyno placement to accept any ground material that meets the existing flatness and clearance requirements.

Other Changes

  • Fixed an issue where the dyno controls could show missing or untranslated text until another interface had been opened.
  • Fixed an issue where opening the mobile dyno could fail when loading its active sessions.
  • Improved the cleanup of tyre data for vehicles that no longer exist, including compatibility with different database collations.
  • Improved ownership checks used during cleanup by adding a missing vehicle-plate index when needed.
  • Removed misleading handling-performance warnings caused only by waiting for a network response.
  • Optimized engine-sound restoration checks for vehicles without saved Mechanic sound changes.
  • Added optional performance diagnostics to help support investigate lag and delays, with diagnostics disabled by default.

Changed Files

  • sky_mechanicjob/config/adv_config.lua
  • sky_mechanicjob/config/config.lua
  • sky_mechanicjob/config/locales/*
  • sky_mechanicjob/fxmanifest.lua
  • sky_mechanicjob/import.sql
  • sky_mechanicjob/source/* — delete and reinsert
Update InstructionsWhat to copy, what to keep and what to check1.27.11.28.0

Simplified update

Update sky_mechanicjob safely

Read the complete update instructions in one continuous guide.

  1. Prepare the update.

Update sky_base to 1.39.0 and sky_jobs_base to 1.42.0 before installing sky_mechanicjob 1.28.0. These steps cover 1.27.1 → 1.28.0. Follow earlier update instructions first when upgrading from an older version. Stop the server and back up the resource, database, custom settings, and saved configurator data.

  1. Replace the package files.

Install the matching 1.28.0 package. Update every path listed in Changed Files, delete and reinsert sky_mechanicjob/source/*, and replace sky_mechanicjob/config/locales/* completely. Merge the configuration changes in this tab into your customized files. Preserve writable data and generated user content.

Required profiler files

For the profiler update, replace the complete sky_mechanicjob/source/* tree and sky_mechanicjob/fxmanifest.lua from the same download, even if diagnostics stay disabled. Delete the old source/ folder before copying the new one.

The profiler builder leaves configuration, integration and compatibility files unchanged. Apply any separate configuration or integration changes listed for this release as usual.

If you previously installed an older profiler package that also modified files outside source/, restore those affected files once from the unmodified versions in the new download and reapply your custom edits. Later profiler-only updates do not require this step.

  1. Merge and review configuration.

In sky_mechanicjob/config/config.lua, add the previously absent feature switch:

config/config.lua
Config.ToggleFeatures.handlingEditor = true

The new default true keeps the handling editor and its automatic plate/model rules enabled. Set it to false to disable both. This is separate from the existing Config.ToggleFeatures.customHandling, which remains unchanged. With Config.UseJobConfigurator = true, use Mechanic → Features → Handling editor, feature key handlingEditor; saved feature overrides take precedence. With the configurator disabled, use the file value. Respawn vehicles after disabling previously applied handling changes; switching the feature off does not reset vehicles already in the world.

In sky_mechanicjob/config/adv_config.lua, delete Config.MobileDyno.placement.acceptedMaterials. The old list was { "tarmac", "concrete_pavement", "paving_slab", "road", "concrete", "concrete_solid" }; it is no longer read. There is no replacement material list. maxSlopeDegrees = 1.0, maxHeightSpread = 0.04, rayStartHeight = 2.0, rayDepth = 5.0, and the footprint probes stay unchanged. Placement still needs valid, sufficiently flat ground. The removed material list and the model-specific probes are file settings; existing /jobconfig slope and height settings continue to apply.

Before using the new tuning save path, follow Garage Integration and the matching ESX, QBCore, or Ox instructions. Some framework versions need the documented vehicle-property additions to preserve paint types and separate livery values. Check your actual installed files and keep custom changes. In particular, QBCore with MSK Garage 5.6 needs a review of the different vehicle-property formats; installing field additions alone does not establish compatibility.

Optional performance diagnostics

Sky's extra profiler information is disabled by default. This update does not start recordings or send data automatically. No configuration change is required for normal use. If support needs a performance recording, add the following line to server.cfg before the Sky ensure lines, then restart the server:

server.cfg
setr sky_profiler 1

This global setting is configured in server.cfg; it is not managed by /jobconfig. The previous state with no setting remains disabled. Set the value to 1 only when you want the additional diagnostics.

Run profiler record 1000 in the server console for a server delay, or in the player's F8 console for a client problem. Reproduce the issue during the recording. Wait until profiler status reports that recording has stopped, then run profiler saveJSON sky-profile.json in the same console to save the capture. These are the standard FiveM profiler commands.

After diagnostics, change the line to setr sky_profiler 0 and restart again. Keep the new package files installed; disabling diagnostics does not require editing Lua or removing manifest entries.

  1. Apply database and item changes.

Back up sky_mechanic_vehicle_tuning and your framework's owned-vehicle table before the first start. The automatic migration, controlled by Config.AutoExecuteQuery, adds nullable legacy_properties LONGTEXT DEFAULT NULL to sky_mechanic_vehicle_tuning and ensures a non-unique plate index on owned_vehicles (ESX) or player_vehicles (QBCore/Qbox) when needed. Existing suitable indexes and vehicle rows are retained.

If Config.AutoExecuteQuery = false, run the VEHICLE OWNERSHIP INDEX block from sky_mechanicjob/import.sql against your active database. It starts with SET @sky_mechanic_ownership_table = 'owned_vehicles';; change that value to 'player_vehicles' for QBCore/Qbox. Then run:

ALTER TABLE `sky_mechanic_vehicle_tuning`
    ADD COLUMN IF NOT EXISTS `legacy_properties` LONGTEXT NULL;

Confirmed tuning now updates owned_vehicles.vehicle on ESX, the existing QBCore/Qbox vehicle properties, or the Sky job-garage vehicle record. On conversion, the previous full Mechanic snapshot is saved once in legacy_properties; Mechanic-specific extras remain in its active record. Existing vehicles are not converted in bulk. Keep those backup values and verify an existing vehicle after a confirmed save. The older /migrate command is not a bulk conversion tool for this change.

Replace all Mechanic locales. No new inventory item, image, streamed model, or provider secret is introduced by this release.

  1. Start and verify the update.

Confirm a tuning purchase, check the existing garage record, and retrieve the vehicle twice. Verify paint, RGB-to-palette changes, liveries, extras, engine sound, and handling before entering the vehicle and from a second player's view. Cancel a paint preview and confirm unrelated tuning stays intact. Test drivetrain conversion, the handling-editor switch, and a mobile dyno on valid flat ground. Check persistence again after a server restart.

Version 1.27.1

Update sky_jobs_base to 1.41.1 and use sky_base1.38.0 before updating sky_mechanicjob.

Highlights

  • Fixed an issue where tuning purchases could succeed with insufficient funds when the payment provider allowed an overdraft.
  • Fixed an issue where Anti-Lag installed on a spawned, unsaved vehicle could be reported as missing.

Notable Changes

  • Fixed an issue where the mobile Dyno could sit above the ground after placement.
  • Added controls for sharing completed Dyno measurements with nearby players, including recipient selection and send feedback.

Other Changes

  • Fixed an issue where received Dyno results could disappear while the tablet opened or refreshed.
  • Improved the standalone tablet presentation of shared Dyno results and restored normal input when leaving the Dyno view.

Changed Files

  • sky_mechanicjob/config/locales/*
  • sky_mechanicjob/fxmanifest.lua
  • sky_mechanicjob/source/* — delete and reinsert
  • sky_mechanicjob/stream/sky_mechanic_props.ytyp
  • sky_mechanicjob/stream/sky_mobile_dyno.ydr
Update InstructionsWhat to copy, what to keep and what to check1.27.01.27.1

Simplified update

Update sky_mechanicjob safely

Read the complete update instructions in one continuous guide.

  1. Update sky_jobs_base to 1.41.1 and use sky_base 1.38.0 before updating sky_mechanicjob. These steps cover 1.27.0 → 1.27.1; complete earlier release instructions first if you are upgrading from an older version. Stop the server and back up the resource, database, saved Job Configurator settings and custom configuration. Preserve generated reports and other writable data.
  2. Install 1.27.1 as a matching package. Update every path in Changed Files, delete and reinsert sky_mechanicjob/source/*, and replace sky_mechanicjob/config/locales/* completely. Merge the configuration instructions in this tab into customized files; retain intentional settings and persistent data.
  3. Review the configuration steps.

No config/config.lua, config/adv_config.lua or /jobconfig value changes are required for this patch. Keep existing Anti-Lag, vehicle persistence, payment and Mobile Dyno settings. The Anti-Lag correction supports the existing temporary tuning path for spawned vehicles; it does not make those vehicles persistent across deletion or server restarts.

Sharing is available from a completed measurement owned by the operator. Open the sharing controls, select a nearby player and send the result. Existing duty, distance and session checks still apply. No additional monitor is required for direct player sharing.

  1. Apply the data, inventory and asset steps.

Replace sky_mechanicjob/stream/sky_mobile_dyno.ydr and sky_mechanicjob/stream/sky_mechanic_props.ytyp together with the matching source package. The corrected placement uses updated collision bounds; no manual station Z offset is required for the shipped model. Replace all sky_mechanicjob/config/locales/* for the sharing controls.

No new SQL migration, inventory item, image or provider secret is introduced. Preserve stored tuning, Dyno measurements, orders and balances. Follow any unfinished 1.27.0 installation steps when upgrading from an older version.

  1. Start providers, Base, Jobs Base and Mechanic in that order. Check a tuning purchase with insufficient and sufficient funds, Anti-Lag on a spawned vehicle, mobile Dyno placement, leaving its tablet view and sharing a completed measurement with a second nearby player.

Version 1.27.0

Update sky_base to 1.38.0 and sky_jobs_base to 1.41.0 before updating sky_mechanicjob.

Highlights

  • Added a standalone administrator handling editor with simple and advanced controls, field explanations, flags, validation, saved profiles, and vehicle-specific rules.
  • Improved the mobile Dyno with a physical control panel, a dedicated tablet workspace, and independently placeable result monitors.
  • Added inventory-based Dyno placement, cancellation, pickup, and controls through the mechanic radial menu.
  • Added staged power sweeps, sustained-load tests, steady holds, and coastdown runs with cooling-fan preparation and temperature warnings.

Notable Changes

  • Added road-test telemetry, acceleration and braking measurements, a driving overlay, and handling recommendations based on recorded runs.
  • Added handling profile revisions, personal workspaces, fleet-rule history, and clipboard-based XML import and export.
  • Improved handling edits so repeated applications preserve the original vehicle baseline, configured field limits remain stable, and unsuccessful live changes are reported.
  • Improved Dyno operation for seated drivers and external operators, including run cleanup, distance checks, and access validation.
  • Improved Dyno graphs with elapsed-time axes, separate power and torque scales, smoother stage transitions, saved results, and sharing to result monitors.
  • Improved Dyno fan controls, wheel and roller presentation, screen alignment, and tyre-squeal suppression.
  • Added player-configurable mechanic, nitro, tuning, and editor key bindings.
  • Removed the exhaust-smoke color tuning option and retired its saved configuration while preserving historical paid-order refund handling.
  • Fixed an issue where a driver could not toggle an installed Anti-Lag kit unless they were the registered vehicle owner.

Other Changes

  • Improved workshop lift, engine-hoist, parts-delivery, and self-service tuning updates so older responses cannot replace newer creator data.
  • Improved handling editor layout, theme consistency, dropdown behavior, and telemetry-mode selection when reopening or applying changes.
  • Updated all bundled mechanic gameplay translations and the shared Job Configurator labels required by the new settings.
  • Updated Dyno models, animations, audio, inventory icons, and handling field definitions required by the new tools.

Changed Files

  • sky_mechanicjob/audioconfig/sky_mobile_dyno_mix.dat15.rel
  • sky_mechanicjob/audioconfig/sky_mobile_dyno_mix.dat15.rel.xml
  • sky_mechanicjob/config/adv_config.lua
  • sky_mechanicjob/config/config.lua
  • sky_mechanicjob/config/inventory/mobile_dyno.png
  • sky_mechanicjob/config/inventory/mobile_dyno_monitor.png
  • sky_mechanicjob/config/locales/*
  • sky_mechanicjob/data/handling_editor_schema.json
  • sky_mechanicjob/fxmanifest.lua
  • sky_mechanicjob/import.sql
  • sky_mechanicjob/source/* — delete and reinsert
  • sky_mechanicjob/stream/sky_mechanic_props.ytyp
  • sky_mechanicjob/stream/sky_mobile_dyno.ycd
  • sky_mechanicjob/stream/sky_mobile_dyno.ydr
  • sky_mechanicjob/stream/sky_mobile_dyno.ytd
  • sky_mechanicjob/stream/sky_mobile_dyno_fans.ycd
  • sky_mechanicjob/stream/sky_mobile_dyno_rollers.ycd
Update InstructionsWhat to copy, what to keep and what to check1.26.01.27.0

Simplified update

Update sky_mechanicjob safely

Read the complete update instructions in one continuous guide.

  1. Update sky_base to 1.38.0 and sky_jobs_base to 1.41.0 before updating sky_mechanicjob. Stop the server and back up the complete sky_mechanicjob resource, its database and inventory data, saved Job Configurator settings where applicable, and intentional public configuration edits. Preserve writable reports and other generated data outside the replaceable source files.
  2. Install 1.27.0 as a consistent package. Replace every file listed in Changed Files, delete and reinsert sky_mechanicjob/source/*, and replace sky_mechanicjob/config/locales/* completely. Merge the public configuration changes listed in this tab into your customized files; do not copy old configuration files over the new package wholesale. Keep the manifest, built UI, runtime and dependencies from the matching release set.
  3. Apply the following configuration changes before starting the resource.

In sky_mechanicjob/config/config.lua, add the complete Config.Keybinds block. This table and its paths were absent in 1.26.0; 1.27.0 uses the following string defaults instead of scattered settings or fixed controls. Preserve your chosen keys when transferring old settings.

config/config.lua
Config.Keybinds = {
    mechanicDynoControl38 = "E",
    mechanicDynoControl47 = "G",
    mechanicDynoControl174 = "LEFT",
    mechanicDynoControl175 = "RIGHT",
    mechanicDynoControl172 = "UP",
    mechanicDynoControl173 = "DOWN",
    mechanicDynoControl45 = "R",
    mechanicDynoControl177 = "BACK",
    mechanicSprayPaintControl202 = "ESCAPE",
    mechanicSprayPaintControl200 = "ESCAPE",
    mechanicVehicleCareControl202 = "ESCAPE",
    mechanicVehicleCareControl200 = "ESCAPE",
    mechanicWheelChangeControl22 = "SPACE",
    mechanicWheelChangeControl200 = "ESCAPE",
    mechanicWheelChangeControl202 = "ESCAPE",
    mechanicCatalyticConverterCATALYTICACTIONCONTROL = "E",
    mechanicCatalyticConverterCATALYTICCANCELCONTROL = "X",
    mechanicWheelTheftWHEELTHEFTACTIONCONTROL = "E",
    mechanicWheelTheftWHEELTHEFTCANCELCONTROL = "X",
    mechanicVehiclePushINPUTMOVEUP = "W",
    mechanicVehiclePushINPUTMOVEDOWN = "S",
    mechanicVehiclePushINPUTMOVELEFT = "A",
    mechanicVehiclePushINPUTMOVERIGHT = "D",
    mechanicVehiclePushINPUTSPRINT = "LSHIFT",
    mechanicVehiclePushINPUTCONTEXT = "E",
    nitroActivationKey = "LSHIFT",
    tuningFocusKey = "SPACE",
    handlingEditorFocusKey = "F7",
}

With Config.UseJobConfigurator = true, open /jobconfig → this resource → General → Keybinds. Every key inside the block is also its exact saved setting ID; for example Config.Keybinds.mechanicDynoControl38 is saved under the same final name. Saved overrides take precedence over the generated defaults. Numeric overrides migrate to their corresponding QWERTY key, and -1 migrates to an empty string. An empty string means no initial binding. Players retain their own assignments in Settings → Key Bindings → FiveM; changing a server default does not overwrite those assignments.

With Config.UseJobConfigurator = false, edit these paths in the file and restart the resource. Keep mouse/controller prefixes exactly as shown. Command permissions and Config.AutoExecuteQuery remain file settings; their reordering does not change their values.

Remove the following old paths after transferring your overrides. The new paths all live in config/config.lua; the saved setting ID is the final segment of each new path.

Old path in 1.26.0Old defaultNew path in 1.27.0New default
Config.Nitro.activationKey in config/adv_config.lua"LSHIFT"Config.Keybinds.nitroActivationKey"LSHIFT"

Move Config.AutoExecuteQuery and the complete Config.CommandPermissions table from sky_mechanicjob/config/adv_config.lua to sky_mechanicjob/config/config.lua, preserving your existing values and groups. Remove the old definitions from adv_config.lua so they cannot overwrite the new table. Add the previously absent permission and feature flag:

config/config.lua
Config.CommandPermissions.handlingeditor = { "god", "superadmin", "admin" }
Config.ToggleFeatures.mobileDyno = true

The permission remains plaintext/global. mobileDyno is a saved /jobconfig feature toggle. Add the complete new handling editor block to config/config.lua; all these paths were absent in 1.26.0:

config/config.lua
Config.HandlingEditor = {
    defaultTab = "advanced", -- simple, advanced, flags, inspector, telemetry, profiles, fleet, export
    -- Suggested percentage window above/below the captured vehicle basis.
    -- A non-default field maximum below takes precedence over the upper endpoint.
    -- The vehicle basis remains stable after Apply, so reopening cannot compound this range.
    sliderMaximumDeviationPercent = 30,
    -- Optional hard maximums for every numeric handling field. Fields not listed here use the
    -- default maximum from data/handling_editor_schema.json (fallback: 1,000,000,000).
    -- Overrides may raise or lower that default, up to the editor's numeric ceiling of
    -- 1,000,000,000 (2,147,483,647 for integers). The same limits are editable in /jobconfig; they do not
    -- change a vehicle value by themselves. A non-default maximum is also the slider endpoint;
    -- fields using their default maximum retain the suggested vehicle-basis slider window.
    -- Example: ["CHandlingData.fInitialDriveMaxFlatVel"] = 250.0,
    fieldMaximums = {},
    layerInspectorEnabled = true,
    fieldDocumentationEnabled = true,
    validatorEnabled = true,
    blockCriticalValidation = true,
    telemetryCoachEnabled = true,
    profileVersioningEnabled = true,
    fleetManagerEnabled = true,
    flagSearchEnabled = true,
    workspacesEnabled = true,
    maxProfileRevisions = 30,
    maxFleetResults = 200,
    maxWorkspacesPerAdmin = 12,
    coachMinimumSamples = 20,
    coachWheelSlipWarningKmh = 12.0,
    coachMinimumBrakeDeceleration = 6.0,
    -- Detailed traces are opt-in; threshold warnings use the queued Sky.Debug logger.
    debugEnabled = false,
    performanceChecksEnabled = true,
    performanceWarningMs = 25,
    payloadWarningBytes = 262144,
    performanceSummaryIntervalMs = 60000
}

With /jobconfig, the saved keys are handlingEditorDefaultTab, handlingEditorSliderMaximumDeviationPercent, handlingEditorLayerInspectorEnabled, handlingEditorFieldDocumentationEnabled, handlingEditorValidatorEnabled, handlingEditorBlockCriticalValidation, handlingEditorTelemetryCoachEnabled, handlingEditorProfileVersioningEnabled, handlingEditorFleetManagerEnabled, handlingEditorFlagSearchEnabled, handlingEditorWorkspacesEnabled, handlingEditorMaxProfileRevisions, handlingEditorMaxFleetResults, handlingEditorMaxWorkspacesPerAdmin, handlingEditorCoachMinimumSamples, handlingEditorCoachWheelSlipWarningKmh, handlingEditorCoachMinimumBrakeDeceleration, handlingEditorDebugEnabled, handlingEditorPerformanceChecksEnabled, handlingEditorPerformanceWarningMs, handlingEditorPayloadWarningBytes, and handlingEditorPerformanceSummaryIntervalMs. They map to the same suffixes in Config.HandlingEditor. Each Config.HandlingEditor.fieldMaximums[field_id] override uses the exact saved key handlingEditorMaximum__<field_id> and must be checked under the matching handling field. Saved overrides win; changing a maximum does not itself change a vehicle. With the configurator disabled, the file is authoritative.

Add the complete new Config.MobileDyno block to sky_mechanicjob/config/adv_config.lua. Every path in this block was absent in 1.26.0; retain the model-specific coordinates for the supplied models only:

config/adv_config.lua
Config.MobileDyno = {
    itemPlacement = {
        enabled = true,
        stationItem = "mobile_dyno",
        monitorItem = "mobile_dyno_monitor",
        consumeItem = true,
        returnItemOnRemove = true,
        persistPlacedProps = false,
        removeDistance = 3.5,
    },
    model = "sky_mobile_dyno",
    requireOnDuty = true,
    interactionDistance = 3.5,
    serverInteractionDistance = 20.0,
    maxVehicleDistance = 7.0,
    maxActiveSessionsPerJob = 3,
    duiDistance = 65.0,
    historyLimit = 20,
    countdownMs = 3000,
    cooldownMs = 2400,
    fullLoadDurationMs = 15000,
    telemetryIntervalMs = 100,
    -- Converts normalized engine RPM into the visual wheel-rotation native's
    -- units. This is vehicle/native presentation tuning and remains Lua-only.
    wheelSpeedMultiplier = 72.0,
    -- The panel quad is calibrated against the actual front glass vertices of
    -- sky_mobile_dyno. Rendering the DUI directly avoids the model's rotated
    -- and cropped texture mapping. This geometry intentionally remains Lua-only.
    screen = {
        width = 1024,
        height = 610,
        topLeft = { x = 1.36335, y = -2.14804, z = 1.61428 },
        topRight = { x = 1.87627, y = -2.14808, z = 1.61442 },
        bottomLeft = { x = 1.36149, y = -2.17236, z = 1.30767 },
        bottomRight = { x = 1.87844, y = -2.17224, z = 1.30729 }
    },
    rollers = {
        centerX = -1.35,
        leftTrackY = 0.78,
        rightTrackY = -0.78,
        longitudinalTolerance = 0.75,
        lateralTolerance = 0.55,
        chassisLongitudinalTolerance = 1.90,
        chassisLateralTolerance = 1.10,
        headingTolerance = 12.0,
        maximumSpeed = 0.25
    },
    fanController = {
        offset = { x = 3.28, y = 0.0, z = 0.82 },
        interactionDistance = 1.35
    },
    -- Thermal rates and thresholds form one coherent simulation/safety contract.
    -- They intentionally remain Lua-only instead of exposing independently
    -- adjustable values that could invalidate the model through /jobconfig.
    thermal = {
        ambientC = 24.0,
        initial = { engine = 86.0, oil = 78.0, coolant = 84.0 },
        heatPerSecond = { engine = 1.10, oil = 1.24, coolant = 0.92 },
        passiveCoolingPerSecond = { engine = 0.045, oil = 0.035, coolant = 0.050 },
        fanCoolingPerSecond = { engine = 0.34, oil = 0.20, coolant = 0.46 },
        warning = { engine = 112.0, oil = 128.0, coolant = 106.0 },
        critical = { engine = 124.0, oil = 145.0, coolant = 118.0 },
        powerLossStart = { engine = 100.0, oil = 112.0, coolant = 98.0 },
        maximumPowerLoss = 0.10,
        minimumEngineHealth = 350.0,
        cacheLifetimeMs = 1800000
    },
    -- Surface material identifiers and footprint probes form a model-specific
    -- world-placement contract and intentionally remain Lua-only.
    placement = {
        maxSlopeDegrees = 1.0,
        maxHeightSpread = 0.04,
        rayStartHeight = 2.0,
        rayDepth = 5.0,
        acceptedMaterials = {
            "tarmac",
            "concrete_pavement",
            "paving_slab",
            "road",
            "concrete",
            "concrete_solid"
        },
        probes = {
            { x = -4.55, y = -1.65 },
            { x = -4.55, y = 0.0 },
            { x = -4.55, y = 1.65 },
            { x = -1.00, y = -1.65 },
            { x = -1.00, y = 0.0 },
            { x = -1.00, y = 1.65 },
            { x = 2.80, y = -1.65 },
            { x = 2.80, y = 0.0 },
            { x = 2.80, y = 1.65 }
        }
    },
    -- The calibrated result-monitor screen quad is coupled to
    -- prop_tv_stand_01 and intentionally remains Lua-only.
    resultMonitor = {
        model = "prop_tv_stand_01",
        renderDistance = 55.0,
        width = 1280,
        height = 720,
        screen = {
            topLeft = { x = -0.659, y = -0.148, z = 1.876 },
            topRight = { x = 0.655, y = -0.148, z = 1.876 },
            bottomLeft = { x = -0.659, y = -0.148, z = 1.138 },
            bottomRight = { x = 0.655, y = -0.148, z = 1.138 }
        }
    },
    animation = {
        full = { dictionary = "sky_mobile_dyno", clip = "dyno_spin" },
        rollers = { dictionary = "sky_mobile_dyno_rollers", clip = "rollers_spin" },
        fans = { dictionary = "sky_mobile_dyno_fans", clip = "fans_spin" }
    },
    -- Stage shapes are a trusted test-program contract. The operator-facing
    -- full-load duration is managed separately through /jobconfig.
    profileOrder = { "sweep", "full_load", "hold", "coastdown" },
    profiles = {
        sweep = {
            label = "Advanced Power Sweep",
            stages = {
                { key = "warmup", durationMs = 3000, startRpm = 0.20, endRpm = 0.32, throttle = 0.30, load = 0.20 },
                { key = "ramp", durationMs = 9000, startRpm = 0.32, endRpm = 0.96, throttle = 1.00, load = 0.92 },
                { key = "full_load", durationMs = 15000, fullLoad = true, startRpm = 0.96, endRpm = 0.96, throttle = 1.00, load = 1.00 },
                { key = "coastdown", durationMs = 6000, startRpm = 0.96, endRpm = 0.18, throttle = 0.00, load = 0.12 }
            }
        },
        full_load = {
            label = "15s Full Load",
            stages = {
                { key = "warmup", durationMs = 4000, startRpm = 0.20, endRpm = 0.36, throttle = 0.35, load = 0.25 },
                { key = "ramp", durationMs = 6000, startRpm = 0.36, endRpm = 0.94, throttle = 1.00, load = 0.90 },
                { key = "full_load", durationMs = 15000, fullLoad = true, startRpm = 0.94, endRpm = 0.98, throttle = 1.00, load = 1.00 },
                { key = "recovery", durationMs = 5000, startRpm = 0.98, endRpm = 0.24, throttle = 0.00, load = 0.10 }
            }
        },
        hold = {
            label = "Steady-State Hold",
            stages = {
                { key = "warmup", durationMs = 3500, startRpm = 0.20, endRpm = 0.34, throttle = 0.30, load = 0.20 },
                { key = "ramp", durationMs = 5000, startRpm = 0.34, endRpm = 0.72, throttle = 0.78, load = 0.68 },
                { key = "steady_hold", durationMs = 15000, startRpm = 0.72, endRpm = 0.72, throttle = 0.78, load = 0.75 },
                { key = "recovery", durationMs = 4500, startRpm = 0.72, endRpm = 0.22, throttle = 0.00, load = 0.10 }
            }
        },
        coastdown = {
            label = "Extended Coastdown",
            stages = {
                { key = "warmup", durationMs = 3000, startRpm = 0.20, endRpm = 0.34, throttle = 0.30, load = 0.20 },
                { key = "ramp", durationMs = 8000, startRpm = 0.34, endRpm = 0.96, throttle = 1.00, load = 0.88 },
                { key = "coastdown", durationMs = 12000, startRpm = 0.96, endRpm = 0.16, throttle = 0.00, load = 0.08 },
                { key = "recovery", durationMs = 3000, startRpm = 0.16, endRpm = 0.20, throttle = 0.00, load = 0.08 }
            }
        }
    }
}

The managed Dyno settings and exact file paths are:

Saved /jobconfig keyPath in config/adv_config.lua
mobileDynoItemUseEnabledConfig.MobileDyno.itemPlacement.enabled
mobileDynoStationItemConfig.MobileDyno.itemPlacement.stationItem
mobileDynoMonitorItemConfig.MobileDyno.itemPlacement.monitorItem
mobileDynoConsumeItemConfig.MobileDyno.itemPlacement.consumeItem
mobileDynoReturnItemConfig.MobileDyno.itemPlacement.returnItemOnRemove
mobileDynoPersistItemsConfig.MobileDyno.itemPlacement.persistPlacedProps
mobileDynoPickupDistanceConfig.MobileDyno.itemPlacement.removeDistance
mobileDynoRequireOnDutyConfig.MobileDyno.requireOnDuty
mobileDynoTabletDistanceConfig.MobileDyno.serverInteractionDistance
mobileDynoMaxActiveSessionsConfig.MobileDyno.maxActiveSessionsPerJob
mobileDynoDuiDistanceConfig.MobileDyno.duiDistance
mobileDynoResultDuiDistanceConfig.MobileDyno.resultMonitor.renderDistance
mobileDynoFullLoadDurationMsConfig.MobileDyno.fullLoadDurationMs
mobileDynoFanInteractionDistanceConfig.MobileDyno.fanController.interactionDistance
mobileDynoPlacementMaxSlopeDegreesConfig.MobileDyno.placement.maxSlopeDegrees
mobileDynoPlacementMaxHeightSpreadConfig.MobileDyno.placement.maxHeightSpread
mobileDynoHistoryLimitConfig.MobileDyno.historyLimit
mobileDynoCountdownMsConfig.MobileDyno.countdownMs
mobileDynoCooldownMsConfig.MobileDyno.cooldownMs
mobileDynoInteractionDistanceConfig.MobileDyno.interactionDistance
mobileDynoMaxVehicleDistanceConfig.MobileDyno.maxVehicleDistance

Review these values in Mobile Dyno and saved installations. The default tablet operating distance is 20.0 metres, pickup distance is 3.5, and requireOnDuty stays enabled in the new block. Item placements are not persistent by default. Model identifiers, screen geometry, roller geometry, animation definitions, thermal simulation and test-profile shapes remain plaintext Lua settings; they are not ordinary saved location fields. Place the supplied Dyno on a valid flat surface and use the editor for each installation rather than copying one model's coordinates to another model. Existing explicit overrides remain effective.

Remove Config.Jobs[*].tuningCostProfile.optionCostByOptionId.electronic_exhaust_smoke_color, including its enabled and complete cost table. This option was enabled in the old shipped workshop, with prices from 0.0 to 4.65 and ecu_tuning_kit requirements; it has no replacement. The updated runtime retires old job and instant-tuning overrides and ignores old vehicle smoke-color values. Keep paid historical orders and existing ECU kits for their remaining supported uses and refund handling. No Two-Step default value changes in this release; retain your current Two-Step settings.

  1. Complete the following database, inventory, and asset steps.

With Config.AutoExecuteQuery = true, let startup create the seven new handling tables. Otherwise apply the matching new sky_mechanicjob/import.sql statements before starting the resource. Existing vehicle tuning, Dyno result history, orders and balances must be retained. Exact new schema:

migration.sql
CREATE TABLE IF NOT EXISTS `sky_mechanic_handling_profiles` (
    `id` INT NOT NULL AUTO_INCREMENT,
    `name` VARCHAR(64) NOT NULL,
    `vehicle_label` VARCHAR(120) NULL,
    `vehicle_model` VARCHAR(64) NULL,
    `vehicle_model_hash` BIGINT UNSIGNED NULL,
    `handling_name` VARCHAR(64) NULL,
    `snapshot` LONGTEXT NOT NULL,
    `created_by_identifier` VARCHAR(120) NULL,
    `created_by_name` VARCHAR(120) NULL,
    `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (`id`),
    INDEX `idx_mechanic_handling_profiles_name` (`name`),
    INDEX `idx_mechanic_handling_profiles_model` (`vehicle_model_hash`)
);

CREATE TABLE IF NOT EXISTS `sky_mechanic_handling_overrides` (
    `id` INT NOT NULL AUTO_INCREMENT,
    `scope` VARCHAR(16) NOT NULL,
    `target_key` VARCHAR(80) NOT NULL,
    `target_label` VARCHAR(120) NOT NULL,
    `vehicle_model_hash` BIGINT UNSIGNED NULL,
    `profile_name` VARCHAR(64) NULL,
    `snapshot` LONGTEXT NOT NULL,
    `created_by_identifier` VARCHAR(120) NULL,
    `created_by_name` VARCHAR(120) NULL,
    `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (`id`),
    UNIQUE KEY `uniq_mechanic_handling_override` (`scope`, `target_key`),
    INDEX `idx_mechanic_handling_overrides_scope` (`scope`),
    INDEX `idx_mechanic_handling_overrides_model` (`vehicle_model_hash`)
);

CREATE TABLE IF NOT EXISTS `sky_mechanic_handling_runs` (
    `id` INT NOT NULL AUTO_INCREMENT,
    `vehicle_label` VARCHAR(120) NULL,
    `vehicle_model_hash` BIGINT UNSIGNED NOT NULL,
    `plate` VARCHAR(24) NULL,
    `mode` VARCHAR(16) NOT NULL,
    `top_speed` DECIMAL(8,2) NOT NULL DEFAULT 0,
    `distance` DECIMAL(10,2) NOT NULL DEFAULT 0,
    `elapsed` DECIMAL(10,3) NOT NULL DEFAULT 0,
    `max_acceleration` DECIMAL(8,3) NOT NULL DEFAULT 0,
    `max_deceleration` DECIMAL(8,3) NOT NULL DEFAULT 0,
    `max_wheel_slip` DECIMAL(8,3) NOT NULL DEFAULT 0,
    `zero_to_sixty` DECIMAL(10,3) NULL,
    `zero_to_hundred` DECIMAL(10,3) NULL,
    `zero_to_two_hundred` DECIMAL(10,3) NULL,
    `hundred_to_zero` DECIMAL(10,3) NULL,
    `quarter_mile` DECIMAL(10,3) NULL,
    `kilometer` DECIMAL(10,3) NULL,
    `samples` LONGTEXT NOT NULL,
    `created_by_identifier` VARCHAR(120) NULL,
    `created_by_name` VARCHAR(120) NULL,
    `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (`id`),
    INDEX `idx_mechanic_handling_runs_model` (`vehicle_model_hash`, `created_at`),
    INDEX `idx_mechanic_handling_runs_plate` (`plate`, `created_at`)
);

CREATE TABLE IF NOT EXISTS `sky_mechanic_handling_profile_revisions` (
    `id` INT NOT NULL AUTO_INCREMENT,
    `profile_id` INT NOT NULL,
    `revision` INT NOT NULL,
    `note` VARCHAR(500) NULL,
    `release_status` VARCHAR(16) NOT NULL DEFAULT 'draft',
    `telemetry_run_id` INT NULL,
    `snapshot` LONGTEXT NOT NULL,
    `created_by_identifier` VARCHAR(120) NULL,
    `created_by_name` VARCHAR(120) NULL,
    `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (`id`),
    UNIQUE KEY `uniq_mechanic_handling_profile_revision` (`profile_id`, `revision`),
    INDEX `idx_mechanic_handling_revisions_profile` (`profile_id`, `created_at`)
);

CREATE TABLE IF NOT EXISTS `sky_mechanic_handling_preferences` (
    `identifier` VARCHAR(120) NOT NULL,
    `preferences` LONGTEXT NOT NULL,
    `favorites` LONGTEXT NOT NULL,
    `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (`identifier`)
);

CREATE TABLE IF NOT EXISTS `sky_mechanic_handling_workspaces` (
    `id` INT NOT NULL AUTO_INCREMENT,
    `owner_identifier` VARCHAR(120) NOT NULL,
    `owner_name` VARCHAR(120) NULL,
    `name` VARCHAR(64) NOT NULL,
    `vehicle_label` VARCHAR(120) NULL,
    `vehicle_model_hash` BIGINT UNSIGNED NULL,
    `snapshot` LONGTEXT NOT NULL,
    `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (`id`),
    UNIQUE KEY `uniq_mechanic_handling_workspace_owner_name` (`owner_identifier`, `name`),
    INDEX `idx_mechanic_handling_workspaces_owner` (`owner_identifier`, `updated_at`)
);

CREATE TABLE IF NOT EXISTS `sky_mechanic_handling_fleet_history` (
    `id` INT NOT NULL AUTO_INCREMENT,
    `scope` VARCHAR(16) NOT NULL,
    `target_key` VARCHAR(80) NOT NULL,
    `target_label` VARCHAR(120) NOT NULL,
    `vehicle_model_hash` BIGINT UNSIGNED NULL,
    `action` VARCHAR(24) NOT NULL,
    `snapshot` LONGTEXT NULL,
    `created_by_identifier` VARCHAR(120) NULL,
    `created_by_name` VARCHAR(120) NULL,
    `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (`id`),
    INDEX `idx_mechanic_handling_fleet_target` (`scope`, `target_key`, `created_at`),
    INDEX `idx_mechanic_handling_fleet_created` (`created_at`)
);

Register mobile_dyno (weight 25000) and mobile_dyno_monitor (weight 5000) in the active inventory. The ESX-style items inserts in import.sql are idempotent; QBCore, Qbox and ox_inventory normally need their own shared item definitions. The runtime registers usable actions through the shared prop service. Copy the new config/inventory/mobile_dyno.png and config/inventory/mobile_dyno_monitor.png into the inventory's image directory.

Install every listed Dyno stream file, the updated stream/sky_mechanic_props.ytyp, both new audio configuration files, data/handling_editor_schema.json, the matching manifest, complete locales and complete built source folder. The manifest now points to the archetype inside stream/ and loads the Dyno audio mix. Do not carry an older manifest forward. No new provider secret is required.

  1. Start the matching dependencies and Mechanic, then verify all seven handling tables and both usable items. Place/cancel/pick up a Dyno and monitor, check duty and range rejection, prepare cooling fans, run seated and external tests, and check start/stop cleanup, temperatures, graphs, fan dragging, saved history and monitor sharing. Open /handlingeditor with an authorized administrator, apply two successive edits, reopen, test profile revisions, XML clipboard export/import, field limits, fleet rules and driving telemetry. Verify unsupported/failed live changes report an error, Escape closes only the open dropdown, and drivers can toggle installed Anti-Lag. Confirm smoke-color ordering is unavailable while historical refunds remain intact.

Version 1.26.0

Update sky_base to 1.37.0 and sky_jobs_base to 1.40.0 before updating sky_mechanicjob.

Highlights

  • Added persistent electronic exhaust-smoke color tuning with eleven levels and ECU Tuning Kit pricing.
  • Improved Two-Step so input detection remains responsive while idle polling is configurable and its torque effect composes with ECU tuning.
  • Improved live vehicle tuning so runtime vehicles retain applied settings through synchronization and ownership changes.
  • Added support for every runtime plate style, including the Enhanced plate variant.

Notable Changes

  • Added server-authorized anti-lag previews and ECU index diagnostics for safer electronic-tuning workflows.
  • Improved Job Creator refresh behavior so a saved configuration cannot trigger an unsafe recursive refresh.
  • Improved parts-delivery guidance when several completed orders are waiting.
  • Fixed engine-hoist behavior so attaching and moving a vehicle does not damage it.
  • Added an optional config/img directory contract for custom NUI tuning images.

Other Changes

  • Updated number inputs so browser spinner controls match the tablet interface.
  • Updated bundled locales for exhaust-smoke colors, Two-Step defaults, delivery guidance, plate styles, and tuning diagnostics.
  • Improved electronic-tuning persistence and preview cleanup across resource and player lifecycle changes.

Changed Files

  • sky_mechanicjob/config/adv_config.lua
  • sky_mechanicjob/config/config.lua
  • sky_mechanicjob/config/img/README.md
  • sky_mechanicjob/config/locales/*
  • sky_mechanicjob/fxmanifest.lua
  • sky_mechanicjob/source/* — delete and reinsert
Update InstructionsWhat to copy, what to keep and what to check1.25.01.26.0

Simplified update

Update sky_mechanicjob safely

Read the complete update instructions in one continuous guide.

  1. Install sky_base 1.37.0 and sky_jobs_base 1.40.0, stop the server, and back up the complete Mechanic resource, Job Configurator data, tuning data, and intentional configuration edits.
  2. Delete the old folder and install the complete 1.26.0 package. Do not mix 1.25.0 manifest, advanced config, standard config, locales, UI, or source files with this release.
  3. Let the first start migrate saved /jobconfig profiles, then confirm electronic_exhaust_smoke_color under each intended job's tuningCostProfile.optionCostByOptionId. Level 0 is free with no item; levels 1 through 10 use a cost value of 4.65 and require ecu_tuning_kit. Do not create a parallel tuningCostProfile.options table.
  4. Add Config.TwoStep.defaultEnabled = false and Config.TwoStep.inactiveCheckIntervalMs = 125 to config/adv_config.lua. /jobconfig manages only the coarse Config.ToggleFeatures.twoStep switch; these low-level values remain plaintext deployment settings.
  5. Add custom tuning artwork below config/img only when needed. No SQL migration or new inventory item is required; the new tuning option reuses ecu_tuning_kit.
  6. Restart Base, Jobs Base, and Mechanic in order. Verify exhaust-smoke colors and persistence, anti-lag previews, ECU diagnostics, Two-Step defaults/input/torque, runtime plate styles, creator refresh, queued deliveries, and engine-hoist handling.

Version 1.25.0

Update sky_base to 1.36.0 and sky_jobs_base to 1.39.0 before updating sky_mechanicjob.

Highlights

  • Added persistent electronic tuning for anti-lag variants, two-step, throttle response, wheelie behavior, engine output, idle speed, interior lighting, headlight brightness, radio power, brake lights, horn high beams, automatic hazards, and preset or custom RGB mood lighting with intensity and disable control.
  • Added staged brake overheating with configurable vehicle and brake-upgrade multipliers, glowing discs, critical sparks, short brake fade, and a debug display.
  • Added a parts-delivery mode that can place the complete collected order directly into the player's inventory instead of using the physical pallet flow.
  • Changed the former Anti-Lag Kit into one ECU Tuning Kit that supplies anti-lag, two-step, and every new electronic upgrade.

Notable Changes

  • Improved tuning orders so required item quantities are visible, carried repair items can be consumed, advanced installations work with parts delivery disabled, and live prices refresh after Job Configurator changes.
  • Improved vehicle repair and service persistence so self-service work and Quasar parking retain completed repairs without overwriting unrelated vehicle data.
  • Improved workshop deliveries so the pallet appears at the configured spawn position and direct-inventory collection grants the full validated order once.
  • Fixed an issue where seated customers could be removed from their vehicle during billing and where a partially paid invoice could remain open after completion.
  • Added system-actor entries to vehicle history so automated service actions remain distinguishable from employee changes.
  • Improved fake plates so a qualifying collision can detach the plate even when body-health loss is small.

Other Changes

  • Improved xenon synchronization, repaired-window updates, transactional stance changes, and wheel geometry so nearby clients see the same vehicle state without changing door angles.
  • Removed the lingering limp-mode speed cap after the underlying vehicle condition recovers.
  • Improved the tuning interface with functional categories, dedicated ECU artwork, clearer removal/order details, shared form controls, and consistent FiveM CEF rendering.
  • Updated bundled translations for ECU tuning, brake heat, parts delivery, exhaust work, catalytic converters, invoices, and vehicle-state messages.

Changed Files

  • sky_mechanicjob/compat/fakeplates_realplate_native.lua
  • sky_mechanicjob/config/adv_config.lua
  • sky_mechanicjob/config/config.lua
  • sky_mechanicjob/config/inventory/ecu_tuning_kit.png
  • sky_mechanicjob/config/locales/*
  • sky_mechanicjob/config/sv_functions.lua
  • sky_mechanicjob/fxmanifest.lua
  • sky_mechanicjob/import.sql
  • sky_mechanicjob/source/* — delete and reinsert
Update InstructionsWhat to copy, what to keep and what to check1.24.11.25.0

Simplified update

Update sky_mechanicjob safely

Read the complete update instructions in one continuous guide.

  1. Install sky_base 1.36.0 and sky_jobs_base 1.39.0, stop the server, and back up the complete Mechanic resource, inventory definitions/data, Job Configurator tables, mechanic tables, and intentional config/provider edits.
  2. Delete the old folder and install the complete 1.25.0 package. Do not mix the old manifest, built UI, locales, source, config defaults, or fake-plate compatibility files with this release.
  3. Add Config.ToggleFeatures.electronicTuning = true and Config.ToggleFeatures.brakeOverheating = true; both paths were absent in 1.24.1. With /jobconfig, the saved feature keys electronicTuning and brakeOverheating override these file defaults.
  4. Add this complete new plaintext/default brake block exactly as shipped:
    config/config.lua
    Config.BrakeOverheating = {
        simulationIntervalMs = 100,
        visualDistance = 55.0,
        maximumVisibleVehicles = 16,
        minimumSpeedKmh = 25.0,
        referenceSpeedKmh = 120.0,
        heatGainPerSecond = 8.0,
        coolingPerSecond = 0.34,
        coolingDelayMs = 5000,
        heatUp = {
            classes = {
                [0] = 0.9, [1] = 1.0, [2] = 1.1, [3] = 1.0, [4] = 1.0, [5] = 0.9,
                [6] = 0.85, [7] = 0.8, [8] = 0.5, [9] = 0.9, [10] = 0.7, [11] = 0.7,
                [12] = 1.0, [17] = 1.0, [18] = 0.7, [19] = 0.7, [20] = 1.0, [22] = 0.8
            },
            brakeUpgrade = { [-1] = 1.0, [0] = 0.8, [1] = 0.65, [2] = 0.6 }
        },
        cooldown = {
            classes = {
                [0] = 1.0, [1] = 1.0, [2] = 1.0, [3] = 1.0, [4] = 1.1, [5] = 1.1,
                [6] = 1.15, [7] = 1.25, [8] = 1.5, [9] = 1.0, [10] = 1.0, [11] = 1.0,
                [12] = 1.0, [17] = 1.0, [18] = 1.15, [19] = 1.15, [20] = 1.0, [22] = 1.25
            },
            brakeUpgrade = { [-1] = 1.0, [0] = 1.1, [1] = 1.25, [2] = 1.5 }
        },
        stages = { warm = 35.0, hot = 60.0, critical = 85.0 },
        glow = {
            [1] = { radius = 0.16, red = 255, green = 105, blue = 20, intensity = 0.45 },
            [2] = { radius = 0.19, red = 255, green = 65, blue = 8, intensity = 0.7 },
            [3] = { radius = 0.22, red = 255, green = 32, blue = 3, intensity = 1.0 }
        },
        sparks = {
            asset = "des_scaffolding",
            effect = "ent_ray_scaf_spark_bursts",
            scale = 0.5,
            minimumIntervalMs = 180,
            maximumIntervalMs = 420
        },
        brakeFade = {
            chancePerSecond = 0.45,
            minimumDurationMs = 300,
            maximumDurationMs = 700,
            cooldownMs = 1800
        },
        wheelBones = {
            "wheel_lf", "wheel_rf", "wheel_lr", "wheel_rr",
            "wheel_lm1", "wheel_rm1", "wheel_lm2", "wheel_rm2"
        },
        excludedVehicleClasses = { [13] = true, [14] = true, [15] = true, [16] = true, [21] = true }
    }
    

    /jobconfig stores the two feature flags plus these exact settings: brakeOverheatingMinimumSpeedKmh, brakeOverheatingReferenceSpeedKmh, brakeOverheatingHeatGainPerSecond, brakeOverheatingCoolingPerSecond, brakeOverheatingCoolingDelayMs, brakeOverheatingHeatClassMultipliers, brakeOverheatingHeatBrakeUpgradeMultipliers, brakeOverheatingCooldownClassMultipliers, brakeOverheatingCooldownBrakeUpgradeMultipliers, brakeOverheatingWarmThreshold, brakeOverheatingHotThreshold, brakeOverheatingCriticalThreshold, brakeOverheatingVisualDistance, brakeOverheatingSparkMinimumIntervalMs, brakeOverheatingSparkMaximumIntervalMs, brakeOverheatingFadeChancePerSecond, brakeOverheatingFadeMinimumDurationMs, brakeOverheatingFadeMaximumDurationMs, and brakeOverheatingFadeCooldownMs. The simulation interval, visible-vehicle limit, glow colors, particle asset/scale, wheel bones, and excluded classes remain plaintext-only.
  5. Add Config.PartsDelivery.deliveryMode = "standard" after deliveryTimeSeconds = 60. This path was absent in 1.24.1; "standard" keeps the physical flow and "player_inventory" grants the complete collected delivery directly. With /jobconfig, the saved key is partsDeliveryMode and overrides the file.
  6. Replace antilag_kit with ecu_tuning_kit in every Config.Jobs[*].shop, partsDeliveryShop, and tuning required-item row. Change the default pricing category key from antilag to ecu_electronics while keeping 70% supplier share, 25% margin, 1400 labor, complex, minimum 400, and maximum 90000. Saved /jobconfig jobs are migrated on start, but inspect every configured job afterward.
  7. Replace the tuning-option defaults with these exact levels, percent costs, and required items; none means no required item:
    Option ID1.25.0 level configuration
    antilag_enabled0=0/none, 1=18.6/ecu_tuning_kit, 2=20.93/ecu_tuning_kit, 3=23.26/ecu_tuning_kit, 4=27.91/ecu_tuning_kit
    twostep_enabledenabled, 16.28/ecu_tuning_kit
    electronic_throttle_response0=0/none, 1=4.65/ecu_tuning_kit
    electronic_wheelie_tune0=0/none, 1=9.3/ecu_tuning_kit, 2=13.95/ecu_tuning_kit
    electronic_engine_tune0=0/none, 1=18.6, 2=34.88, 3=65.12, 4=93.02, each paid level requiring ecu_tuning_kit
    electronic_idle_rpm0=0/none, 1=4.65, 2=5.58, 3=6.98, 4=8.37, each paid level requiring ecu_tuning_kit
    electronic_interior_light0=0/none, 1=1.12/ecu_tuning_kit
    electronic_headlight_brightness0=1.12, 1=1.12, 2=1.12, 3=0/none, 4=1.86, 5=2.79; every non-default paid level requires ecu_tuning_kit
    electronic_radio_power0=1.12/ecu_tuning_kit, 1=0/none
    electronic_brake_lights0=0/none, 1=2.79/ecu_tuning_kit, 2=2.79/ecu_tuning_kit
    electronic_highbeams_on_horn0=0/none, 1=2.33/ecu_tuning_kit
    electronic_automatic_hazards0=0/none, 1=3.72/ecu_tuning_kit
    electronic_mood_color0=0/none; levels 1..16=4.65/ecu_tuning_kit
    electronic_mood_intensity0=0/ecu_tuning_kit, 1=0/none, 2=1.12/ecu_tuning_kit

    In config/adv_config.lua, remove the obsolete Config.AntiLag.activationRpm = 0.7 and Config.AntiLag.minGear = 2 paths; anti-lag behavior now comes from the installed level rather than those global gates.
  8. Register ecu_tuning_kit in the active inventory with label ECU Tuning Kit, weight 2000, and the supplied PNG. Migrate stored antilag_kit items according to the active provider. For ESX item tables, replace the old insert row with ('ecu_tuning_kit', 'ECU Tuning Kit', 2000, 0, 1); INSERT IGNORE does not rename existing rows automatically.
  9. No mechanic table schema changes in this release. Restart Base, Jobs Base, and Mechanic in order, then verify the ECU menu, all option levels, saved tuning, brake heat, both delivery modes, item consumption, invoice completion, Quasar/self-service repair persistence, stance/windows/xenon sync, fake-plate falloff, and post-repair limp-mode recovery.

Version 1.24.1

Update sky_base to 1.35.1 and sky_jobs_base to 1.38.1 before updating sky_mechanicjob.

Highlights

  • Improved the built-in frontend fallback catalogue so missing translated tuning, delivery, invoice, registry, and tablet keys remain readable.

Notable Changes

  • Fixed an issue where a complete 1.24.0 feature installation could still show blank or placeholder Mechanic labels.

Other Changes

  • Updated the package manifest for the 1.24.1 compatibility set.

Changed Files

  • sky_mechanicjob/config/locales/*
  • sky_mechanicjob/fxmanifest.lua
Update InstructionsWhat to copy, what to keep and what to check1.24.01.24.1

Simplified update

Update sky_mechanicjob safely

Read the complete update instructions in one continuous guide.

  1. Update Base to 1.35.1 and Jobs Base to 1.38.1, stop the server, and back up Mechanic.
  2. Delete the old resource and install the complete 1.24.1 package, especially its manifest, built UI, and locale defaults.
  3. No public config value, /jobconfig key, SQL statement, item, image, stream asset, or provider setting changed.
  4. Restart dependencies and Mechanic, then verify tuning, delivery, invoices, registry, and tablet screens show usable text.

Version 1.24.0

Update sky_base to 1.35.0 and sky_jobs_base to 1.38.0 before updating sky_mechanicjob.

Highlights

  • Cross-job vehicle records - mechanics can create richer owner/model/color records and share selected profiles read-only with other jobs.
  • Quantity-aware tuning parts - performance stages can require increasing quantities instead of one item for every level, including repeated legacy item entries.
  • Improved invoice and delivery workflows - invoice registry history, normalized timestamps, custom quantities, stacked delivered parts, customer subscription names, and clearer delivery pallets are supported.
  • Tyre-only persistence - JG garage tyre saves sanitize bounded tyre fields, require a persisted owned plate when ownership checks are enabled, and update only tyre data without overwriting other tuning properties.

Notable Changes

  • Advanced pricing can keep selected parts-shop categories available without an active tuning order; Service items are enabled by default.
  • Vehicle records support editing for their owner job and read-only access for configured share targets.
  • Tuning orders can source quantities from job storage, enforce price caps consistently, and show clearer item labels and dark-mode surfaces.
  • Subscription lists retain customer names and vehicle history includes owner-scoped invoice entries.
  • Wheel size/width scaling was removed; normal Stancer camber, track width, suspension, and alignment remain.

Other Changes

  • Dropdown, opacity, delivery, subscription, invoice, registry, pricing, tuning, and locale behavior was corrected.
  • The Tuning menu includes dedicated Extras artwork in the rebuilt interface.
  • Custom tuning diagnostics now follow the shared Base logging path.
  • Tyre persistence updates only tyre-related fields in the stored property document so ordinary tyre saves preserve unrelated tuning data.
  • Database schemas now inherit the active database character set and collation; no new inventory item or streamed asset is required.

Changed Files

  • sky_mechanicjob/config/adv_config.lua
  • sky_mechanicjob/config/config.lua
  • sky_mechanicjob/config/locales/*
  • sky_mechanicjob/fxmanifest.lua
  • sky_mechanicjob/import.sql
  • sky_mechanicjob/source/* — delete and reinsert

Removed Config Paths

  • Config.ToggleFeatures.stanceWheelSize
  • Config.ToggleFeatures.stanceWheelWidth
  • Config.WheelSizeOptions
  • Config.Jobs[*].tuningCostProfile.optionCostByOptionId.wheel_size
  • Config.Jobs[*].tuningCostProfile.optionCostByOptionId.wheel_width
Update InstructionsWhat to copy, what to keep and what to check1.23.01.24.0

Simplified update

Update sky_mechanicjob safely

Read the complete update instructions in one continuous guide.

  1. Update sky_base to 1.35.0 and sky_jobs_base to 1.38.0. Stop the server and back up the complete Mechanic resource, Job Configurator data, and all sky_mechanic_* tables.
  2. Delete the old folder and install the complete 1.24.0 package. Do not restore 1.23.0 source, built UI, generated defaults, manifest, or locale files.
  3. Remove all five paths listed under Removed Config Paths. Saved Job Configurator values for the two removed stance features are no longer used. Wheel-size/width tuning data is intentionally not applied; normal Stancer controls remain.
  4. Add this complete sharing default before Config.Jobs, then set sharing = mechanic_sharing_defaults on each intended mechanic job:
    config/config.lua
    local mechanic_sharing_defaults = {
        enabled = true,
        records = {
            vehicleRecords = { enabled = true, jobs = {}, groups = { "mechanic" } }
        }
    }
    

    Empty jobs = {} shares nothing outside the Mechanic group. Choose actual read-only target jobs in /jobconfig on the Share tab.
  5. Replace the shipped performance-stage item requirements. Engine levels require quantities 1,2,3,4; brakes 1,2,3; transmission 1,2,3; suspension 1,2,3,4; armor plating 1,2,3,4,5. Use the new shape on each stage:
    config/config.lua
    items = { { name = "engine", quantity = 1 } }
    

    Replace the item and quantity for each stage. Remove the former fourth brake, fifth suspension, and sixth armor rows because those rows did not map to real GTA upgrade levels. Legacy string lists remain valid and repeated names still count as multiple units.
  6. Add this complete advanced-pricing child inside Config.TuningCostProfile.advancedPricing:
    config/config.lua
    alwaysAvailableShopItems = {
        enabled = true,
        categories = { "Service" }
    },
    

    /jobconfig stores these as advancedPricingAlwaysAvailableShopItemsEnabled and advancedPricingAlwaysAvailableShopItemCategories. Saved values override Lua defaults.
  7. With Config.AutoExecuteQuery = true, restart adds customer_name VARCHAR(120) NULL to sky_mechanic_subscriptions and adds owner_name, owner_identifier, model, color, shared_with_jobs, created_at, and updated_at to sky_mechanic_vehicle_profiles. With automatic migration disabled, execute the complete new import.sql. Manual and automatic schemas now inherit the active database character set and collation.
  8. No separately installed item or image is required; the new Extras artwork is contained in the rebuilt interface under source. Existing performance items must have enough stock for the new quantities. Restart dependencies and Mechanic in order; verify performance-stage consumption, Service-category purchasing without an order, vehicle record sharing/edit protection, invoices, subscriptions, stacked deliveries, JG tyre persistence, and removed wheel-size/width controls.

Version 1.23.0

Update sky_base to 1.34.0 and sky_jobs_base to 1.37.0 before updating sky_mechanicjob.

Highlights

  • Server-authoritative advanced pricing - optional quotes combine supplier share, margin, labor, difficulty, vehicle class, mechanic grade, stock, demand, tax, discount caps, and price limits; class-based prices, order-bound procurement, returns, refunds, and workshop profit analytics use the same validated calculation. Public server exports are CreatePricingQuote, GetPricingQuote, ValidatePricingQuote, GetPricingAnalytics, and GetSupplierCatalog; server integrations can observe sky_mechanicjob:server:pricingQuoteCreated, sky_mechanicjob:server:pricingQuoteExpired, and sky_mechanicjob:server:supplierStockChanged.
  • Extended workshop billing - invoices support estimates, deposits, partial payments, manual lines, due dates, reminders and fees, tax, per-grade limits, cancellation permissions, analytics, and optional recipient-name privacy. Public server exports are CreateInvoice, CreateEstimate, GetInvoice, GetPlayerInvoices, PayInvoice, RespondToEstimate, SendInvoiceReminder, CancelInvoice, and GetBillingAnalytics; server integrations can observe sky_mechanicjob:server:invoiceCreated, sky_mechanicjob:server:invoiceStatusChanged, sky_mechanicjob:server:invoiceOverdue, sky_mechanicjob:server:invoicePaymentRecorded, sky_mechanicjob:server:estimateResponded, sky_mechanicjob:server:invoiceReminderSent, and sky_mechanicjob:server:invoiceCancelled.
  • Customer and company subscriptions - configurable workshop memberships provide one strongest non-stacking discount, personal or job-wide ownership, society payment, expiry, a configurable NPC terminal, and workshop-specific models; the responsive tablet app is marked New, its runtime is loaded explicitly, and its SVG assets plus public NPC setup documentation are included. Server integrations can resolve the effective discount through GetSubscriptionDiscount.
  • Parts deliveries in the tablet - the old single-order timer HUD was replaced with a synchronized overview of every workshop delivery, while configured carriers can sprint with delivery boxes.

Notable Changes

  • External LB Tablet and RoadPad surfaces support authorization, inherited sessions, retries, message relay, safe routes, lifecycle return/close, and tuning focus preservation; their runtime module is loaded explicitly.
  • Drift tuning now requires the dedicated drift_tyres item instead of a stance kit; the item is included in shop defaults and SQL inventory seeds.
  • Oil absorbent and brooms are stocked in mechanic shops, including migration into existing configurator-managed shops without duplicates.
  • Vehicle persistence batches orphan-tyre cleanup, reapplies tuning after a server/client startup handshake, avoids shutdown-time saves, preserves add-on stance baselines, and restores stance after garage retrieval.
  • Motorcycle tuning exposes rear-wheel changes instead of treating the vehicle as front-wheel-only.
  • The public server-authoritative /antilag command toggles the persisted state only when Anti-Lag is enabled, the player is the driver of their own vehicle, and that vehicle has an installed Anti-Lag kit; every rejected requirement returns a clear result.
  • Self-service validation follows creator-defined workshop points rather than static job locations.
  • Plates in Config.TuningRestrictions.blockedPlates are rejected by mechanic, self-service, instant, and admin tuning flows.
  • Owned vehicles can send rate-limited maintenance reminders when wear reaches the configured threshold.
  • Oil-leak relays use the configured integration resource and now ship with the Fire resource as the default target; an unavailable provider rejects the relay and writes an English debug diagnostic with its resource state.

Other Changes

  • All newly added and revised user-facing feedback received locale coverage; Italian was added.
  • Shared input, selection, switch, checkbox, range, and date-range controls were made responsive and theme-consistent.
  • Regression coverage was expanded across the release's server, client, persistence, UI, and integration paths.

Changed Files

  • sky_mechanicjob/README.md
  • sky_mechanicjob/config/adv_config.lua
  • sky_mechanicjob/config/config.lua
  • sky_mechanicjob/config/locales/*
  • sky_mechanicjob/fxmanifest.lua
  • sky_mechanicjob/import.sql
  • sky_mechanicjob/source/* — delete and reinsert
Update InstructionsWhat to copy, what to keep and what to check1.22.01.23.0

Simplified update

Update sky_mechanicjob safely

Read the complete update instructions in one continuous guide.

  1. Update sky_base to 1.34.0 and sky_jobs_base to 1.37.0. Stop the server, then back up the complete Mechanic resource, generated creator settings, and every sky_mechanic_* database table.
  2. Delete the old sky_mechanicjob folder and install the complete 1.23.0 package. Do not restore the old manifest, source, built UI, generated defaults, delivery HUD, or locale files.
  3. Start from the new config/config.lua and config/adv_config.lua, then apply every change below. An entry marked Absent -> New did not exist in 1.22.0; do not omit it.

Direct value and item changes

Exact path1.22.01.23.0
Config.ToggleFeatures.vehicleMaintenanceNotificationsAbsenttrue
Config.ToggleFeatures.subscriptionsAbsenttrue
Config.Jobs[*].shopNo release itemsAdd drift_tyres (500), oil_absorbent (35), and broom (25)
Config.Jobs[*].partsDeliveryShopNo release itemsAdd drift_tyres (500, Wheels), oil_absorbent (35, Service), and broom (25, Service)
Config.Jobs[*].tuningCostProfile.optionCostByOptionId.handling_drift_tuning.items{ "stance_kit" }{ "drift_tyres" }
Config.PartsDelivery.timerHudPresent with enabled, position.left, and position.topRemoved completely
Config.PartsDelivery.allowsprintAbsenttrue
Config.OilLeaks.integration.resource"sky_mechanicjob""sky_firejob"
Config.InstantTuning.tuningCostProfile in config/adv_config.luaAbsentnil; inherit the first configured mechanic job profile
Config.TuningCostProfile.priceType"percentage""percentage" remains the default; "fixed" remains supported and "class" is new

Add these exact rows to both job item lists:

config/config.lua
-- Config.Jobs[*].shop
{ name = "drift_tyres", label = "Drift Tyres", price = 500 },
{ name = "oil_absorbent", label = "Oil Absorbent", price = 35 },
{ name = "broom", label = "Broom", price = 25 },

-- Config.Jobs[*].partsDeliveryShop
{ name = "drift_tyres", label = "Drift Tyres", price = 500, category = "Wheels" },
{ name = "oil_absorbent", label = "Oil Absorbent", price = 35, category = "Service" },
{ name = "broom", label = "Broom", price = 25, category = "Service" },

Replace the complete delivery block. The old timerHud child is intentionally gone:

config/config.lua
Config.PartsDelivery = {
    deliveryTimeSeconds = 60,
    allowsprint = true,
    paymentMethods = {
        own_card = true,
        company_card = true
    },
    openDurationMs = 5500
}

Add the complete new interaction entry inside Config.Interactions:

config/config.lua
subscription_terminal = {
    public = true,
    interaction = true,
    interactionDistance = 2.5,
    unique = false,
    marker = {
        enabled = false,
        type = 1,
        offset = vector3(0.0, 0.0, 0.0)
    },
    blip = {
        enabled = false,
        name = "Workshop Memberships",
        sprite = 446,
        color = 5
    },
    npc = {
        enabled = true,
        name = "Workshop Memberships",
        pedHash = "s_m_m_autoshop_01",
        scenario = "WORLD_HUMAN_CLIPBOARD"
    }
},

Add the complete new restriction and maintenance tables:

config/config.lua
Config.TuningRestrictions = {
    blockedPlates = {
        -- "POLICE01",
        -- "EMS01"
    }
}

Config.MaintenanceNotifications = {
    enabled = true,
    dueThresholdPercent = 25,
    cooldownMinutes = 180
}

Add the complete new subscription defaults:

config/config.lua
Config.Subscriptions = {
    enabled = true,
    allowJobSubscriptions = true,
    currency = "bank",
    maximumModels = 12,
    maximumDurationsPerModel = 6,
    npc = {
        pedModel = "s_m_m_autoshop_01",
        scenario = "WORLD_HUMAN_CLIPBOARD",
        emote = {
            dict = "",
            clip = ""
        }
    },
    models = {
        {
            id = "basic",
            label = "Basic",
            description = "A reliable discount for regular maintenance and tuning.",
            discountPercent = 10,
            enabled = true,
            durations = {
                { days = 14, price = 2500, jobPrice = 10000 },
                { days = 30, price = 4500, jobPrice = 18000 }
            }
        },
        {
            id = "premium",
            label = "Premium",
            description = "The best workshop discount for frequent customers.",
            discountPercent = 20,
            enabled = true,
            durations = {
                { days = 14, price = 4500, jobPrice = 18000 },
                { days = 30, price = 8000, jobPrice = 32000 }
            }
        }
    }
}

Replace each job's complete billingSettings table with these defaults. The first four fields existed in 1.22.0; every following field and gradeRules is new:

config/config.lua
billingSettings = {
    enabled = true,
    maxDiscountPercent = 15,
    allowImmediatePayment = true,
    allowCustomPrices = true,
    allowManualItems = true,
    allowEstimates = true,
    allowPartialPayments = true,
    depositPercent = 30,
    minimumPartialPayment = 100,
    defaultDueDays = 7,
    estimateLifetimeHours = 24,
    reminderGraceDays = 2,
    reminderFee = 250,
    maximumReminders = 3,
    taxPercent = 0,
    minimumInvoiceAmount = 100,
    maximumInvoiceAmount = 250000,
    maximumManualItems = 20,
    analyticsPeriodDays = 30,
    allowAnalytics = false,
    gradeRules = {
        { grade = 0, maximumInvoiceAmount = 15000, maximumDiscountPercent = 5, allowEstimates = true, allowManualItems = false, allowCancellation = false, allowReminders = false, allowAnalytics = false },
        { grade = 1, maximumInvoiceAmount = 50000, maximumDiscountPercent = 10, allowEstimates = true, allowManualItems = true, allowCancellation = false, allowReminders = false, allowAnalytics = false },
        { grade = 2, maximumInvoiceAmount = 125000, maximumDiscountPercent = 15, allowEstimates = true, allowManualItems = true, allowCancellation = true, allowReminders = true, allowAnalytics = true },
        { grade = 3, maximumInvoiceAmount = 250000, maximumDiscountPercent = 15, allowEstimates = true, allowManualItems = true, allowCancellation = true, allowReminders = true, allowAnalytics = true }
    }
},

Replace the complete fallback billing table. showRecipientName, the extended invoice fields, and gradeRules are new; the other leading fields retain their prior values:

config/config.lua
Config.Billing = {
    enabled = true,
    showRecipientName = false,
    maxDiscountPercent = 15,
    allowImmediatePayment = true,
    allowCustomPrices = true,
    requireOnDutyWork = true,
    allowManualItems = true,
    allowEstimates = true,
    allowPartialPayments = true,
    depositPercent = 30,
    minimumPartialPayment = 100,
    defaultDueDays = 7,
    estimateLifetimeHours = 24,
    reminderGraceDays = 2,
    reminderFee = 250,
    maximumReminders = 3,
    taxPercent = 0,
    minimumInvoiceAmount = 100,
    maximumInvoiceAmount = 250000,
    maximumManualItems = 20,
    analyticsPeriodDays = 30,
    allowAnalytics = false,
    gradeRules = {}
}

Add the complete new advanced-pricing table. It ships disabled:

config/config.lua
Config.TuningCostProfile.advancedPricing = {
    enabled = false,
    supplierSharePercent = 65.0,
    roundingStep = 50,
    defaultMarginPercent = 25.0,
    minimumMarginPercent = 10.0,
    maximumMarginPercent = 35.0,
    minimumRetailPrice = 100,
    maximumRetailPrice = 150000,
    taxPercent = 0.0,
    quoteLifetimeMinutes = 30,
    maximumDiscountPercent = 15.0,
    returnRefundPercent = 80.0,
    analyticsPeriodDays = 30,
    previewCostPercent = 10.0,
    previewCompactVehicleValue = 40000,
    previewSportsVehicleValue = 80000,
    previewSuperVehicleValue = 120000,
    inventory = {
        enabled = true,
        baseStock = 40,
        lowStockThreshold = 10,
        lowStockMarkupPercent = 20.0,
        demandMarkupPerUnitPercent = 0.5,
        maximumDemandMarkupPercent = 25.0,
        restockPerDay = 5,
        demandDecayPerDay = 3
    },
    difficultyRules = {
        { key = "simple", laborFee = 0 },
        { key = "standard", laborFee = 250 },
        { key = "complex", laborFee = 750 },
        { key = "expert", laborFee = 1500 }
    },
    categoryRules = {
        { key = "bodywork", supplierSharePercent = 60.0, marginPercent = 25.0, laborFee = 500, difficulty = "standard", minimumPrice = 100, maximumPrice = 60000 },
        { key = "engine", supplierSharePercent = 75.0, marginPercent = 20.0, laborFee = 2500, difficulty = "expert", minimumPrice = 500, maximumPrice = 150000 },
        { key = "brakes", supplierSharePercent = 70.0, marginPercent = 20.0, laborFee = 1200, difficulty = "complex", minimumPrice = 300, maximumPrice = 80000 },
        { key = "transmission", supplierSharePercent = 75.0, marginPercent = 20.0, laborFee = 2000, difficulty = "expert", minimumPrice = 500, maximumPrice = 120000 },
        { key = "suspension", supplierSharePercent = 70.0, marginPercent = 22.0, laborFee = 1500, difficulty = "complex", minimumPrice = 300, maximumPrice = 90000 },
        { key = "armor", supplierSharePercent = 80.0, marginPercent = 15.0, laborFee = 3000, difficulty = "expert", minimumPrice = 1000, maximumPrice = 150000 },
        { key = "wheels", supplierSharePercent = 60.0, marginPercent = 25.0, laborFee = 750, difficulty = "standard", minimumPrice = 200, maximumPrice = 60000 },
        { key = "stancing", supplierSharePercent = 65.0, marginPercent = 25.0, laborFee = 1000, difficulty = "complex", minimumPrice = 300, maximumPrice = 70000 },
        { key = "turbo", supplierSharePercent = 75.0, marginPercent = 20.0, laborFee = 1800, difficulty = "expert", minimumPrice = 500, maximumPrice = 120000 },
        { key = "antilag", supplierSharePercent = 70.0, marginPercent = 25.0, laborFee = 1400, difficulty = "complex", minimumPrice = 400, maximumPrice = 90000 },
        { key = "lights", supplierSharePercent = 55.0, marginPercent = 30.0, laborFee = 400, difficulty = "simple", minimumPrice = 100, maximumPrice = 40000 },
        { key = "colors", supplierSharePercent = 50.0, marginPercent = 30.0, laborFee = 350, difficulty = "simple", minimumPrice = 100, maximumPrice = 40000 },
        { key = "custom_tuning", supplierSharePercent = 70.0, marginPercent = 25.0, laborFee = 1600, difficulty = "complex", minimumPrice = 300, maximumPrice = 100000 }
    },
    vehicleClassRules = {
        { classId = 0, marginAdjustmentPercent = -3.0, laborMultiplier = 0.8 },
        { classId = 1, marginAdjustmentPercent = -2.0, laborMultiplier = 0.9 },
        { classId = 2, marginAdjustmentPercent = 0.0, laborMultiplier = 1.0 },
        { classId = 3, marginAdjustmentPercent = -1.0, laborMultiplier = 0.95 },
        { classId = 4, marginAdjustmentPercent = 0.0, laborMultiplier = 1.0 },
        { classId = 5, marginAdjustmentPercent = 1.0, laborMultiplier = 1.1 },
        { classId = 6, marginAdjustmentPercent = 3.0, laborMultiplier = 1.3 },
        { classId = 7, marginAdjustmentPercent = 5.0, laborMultiplier = 1.5 },
        { classId = 8, marginAdjustmentPercent = -2.0, laborMultiplier = 0.8 },
        { classId = 9, marginAdjustmentPercent = 1.0, laborMultiplier = 1.2 },
        { classId = 10, marginAdjustmentPercent = 1.0, laborMultiplier = 1.2 },
        { classId = 11, marginAdjustmentPercent = 0.0, laborMultiplier = 1.0 },
        { classId = 12, marginAdjustmentPercent = 0.0, laborMultiplier = 1.0 },
        { classId = 13, marginAdjustmentPercent = -4.0, laborMultiplier = 0.6 },
        { classId = 14, marginAdjustmentPercent = 2.0, laborMultiplier = 1.3 },
        { classId = 15, marginAdjustmentPercent = 4.0, laborMultiplier = 1.5 },
        { classId = 16, marginAdjustmentPercent = 4.0, laborMultiplier = 1.5 },
        { classId = 17, marginAdjustmentPercent = 0.0, laborMultiplier = 1.0 },
        { classId = 18, marginAdjustmentPercent = 0.0, laborMultiplier = 1.0 },
        { classId = 19, marginAdjustmentPercent = 3.0, laborMultiplier = 1.4 },
        { classId = 20, marginAdjustmentPercent = 2.0, laborMultiplier = 1.3 },
        { classId = 21, marginAdjustmentPercent = 0.0, laborMultiplier = 1.0 },
        { classId = 22, marginAdjustmentPercent = 3.0, laborMultiplier = 1.4 }
    },
    mechanicGradeRules = {
        { grade = 0, label = "Apprentice", marginAdjustmentPercent = -5.0, laborMultiplier = 0.9, maximumDiscountPercent = 5.0 },
        { grade = 1, label = "Mechanic", marginAdjustmentPercent = 0.0, laborMultiplier = 1.0, maximumDiscountPercent = 10.0 },
        { grade = 2, label = "Senior Mechanic", marginAdjustmentPercent = 3.0, laborMultiplier = 1.1, maximumDiscountPercent = 15.0 },
        { grade = 3, label = "Master Mechanic", marginAdjustmentPercent = 5.0, laborMultiplier = 1.2, maximumDiscountPercent = 15.0 }
    }
}

Add the complete class-pricing defaults. They do nothing until priceType is deliberately changed to "class":

config/config.lua
Config.TuningCostProfile.priceType = "percentage"
Config.TuningCostProfile.vehicleClassPricing = {
    [0] = { priceType = "percentage", multiplier = 1.0 },
    [1] = { priceType = "percentage", multiplier = 1.0 },
    [2] = { priceType = "percentage", multiplier = 1.0 },
    [3] = { priceType = "percentage", multiplier = 1.0 },
    [4] = { priceType = "percentage", multiplier = 1.0 },
    [5] = { priceType = "percentage", multiplier = 1.0 },
    [6] = { priceType = "percentage", multiplier = 1.0 },
    [7] = { priceType = "percentage", multiplier = 1.0 },
    [8] = { priceType = "percentage", multiplier = 1.0 },
    [9] = { priceType = "percentage", multiplier = 1.0 },
    [10] = { priceType = "percentage", multiplier = 1.0 },
    [11] = { priceType = "percentage", multiplier = 1.0 },
    [12] = { priceType = "percentage", multiplier = 1.0 },
    [13] = { priceType = "percentage", multiplier = 1.0 },
    [14] = { priceType = "percentage", multiplier = 1.0 },
    [15] = { priceType = "percentage", multiplier = 1.0 },
    [16] = { priceType = "percentage", multiplier = 1.0 },
    [17] = { priceType = "percentage", multiplier = 1.0 },
    [18] = { priceType = "percentage", multiplier = 1.0 },
    [19] = { priceType = "percentage", multiplier = 1.0 },
    [20] = { priceType = "percentage", multiplier = 1.0 },
    [21] = { priceType = "percentage", multiplier = 1.0 },
    [22] = { priceType = "percentage", multiplier = 1.0 }
}

Saved /jobconfig values and capability flags

  • The Features section saves the feature switches vehicleMaintenanceNotifications and subscriptions; those saved switches override the matching Config.ToggleFeatures defaults.
  • Saved global keys are maintenanceNotificationsEnabled, maintenanceNotificationsThreshold, maintenanceNotificationsCooldownMinutes, subscriptionsEnabled, subscriptionsAllowJobSubscriptions, subscriptionsCurrency, subscriptionsMaximumModels, subscriptionsMaximumDurations, subscriptionsNpcPedModel, subscriptionsNpcScenario, subscriptionsNpcEmoteDict, subscriptionsNpcEmoteClip, tuningBlockedPlates, allowsprint, priceType, and vehicleClassPricing.
  • The exact saved advanced-pricing keys are advancedPricingEnabled, advancedPricingSupplierSharePercent, advancedPricingRoundingStep, advancedPricingDefaultMarginPercent, advancedPricingMinimumMarginPercent, advancedPricingMaximumMarginPercent, advancedPricingMinimumRetailPrice, advancedPricingMaximumRetailPrice, advancedPricingTaxPercent, advancedPricingQuoteLifetimeMinutes, advancedPricingMaximumDiscountPercent, advancedPricingReturnRefundPercent, advancedPricingAnalyticsPeriodDays, advancedPricingPreviewCostPercent, advancedPricingPreviewCompactValue, advancedPricingPreviewSportsValue, advancedPricingPreviewSuperValue, advancedPricingInventoryEnabled, advancedPricingInventoryBaseStock, advancedPricingInventoryLowStockThreshold, advancedPricingInventoryLowStockMarkupPercent, advancedPricingInventoryDemandMarkupPerUnitPercent, advancedPricingInventoryMaximumDemandMarkupPercent, advancedPricingInventoryRestockPerDay, advancedPricingInventoryDemandDecayPerDay, advancedPricingDifficultyRules, advancedPricingCategoryRules, advancedPricingVehicleClassRules, and advancedPricingMechanicGradeRules.
  • Saved per-job values are shop, partsDeliveryShop, billingSettings, tuningCostProfile, and allowedVehicleClasses. The defaults migration adds missing oil_absorbent and broom rows without duplicating existing rows; add or verify drift_tyres separately and then verify all three items once. Saved self-service points additionally hold their own allowedVehicleClasses; an empty list means all GTA classes.
  • Config.Interactions.self_service_tuning.vehicleClassWhitelist = true is a capability flag that exposes the per-point class editor. It is not the saved class list. Config.Interactions.subscription_terminal likewise defines which point the creator can place; each saved terminal position is separate creator data.
  • Subscription models are initialized from Config.Subscriptions.models and then managed in the Subscriptions tablet/database. They are not ordinary /jobconfig model rows.
  • When Config.UseJobConfigurator = true, review and resave every workshop because saved overrides win over the Lua defaults. When it is false, the Lua values above are authoritative.

Permissions, command, and public server integrations

  • After enabling subscriptions, assign View subscriptions to every workshop role that may open the tablet app and Manage subscriptions to every workshop role that may edit availability, models, durations, prices, or discounts. A player purchasing a company-wide subscription additionally needs Manage money in the purchasing company job; the permission is checked against that company, not the selling workshop.
  • /antilag is available only while Config.ToggleFeatures.antiLag is enabled. The player must run it in-game as the driver of their own vehicle, and the persisted vehicle tuning must contain an installed Anti-Lag kit. The command rejects passengers, non-owned vehicles, vehicles without the kit, and concurrent toggles for the same plate.
  • Pricing and supplier server exports: CreatePricingQuote, GetPricingQuote, ValidatePricingQuote, GetPricingAnalytics, and GetSupplierCatalog.
  • Billing server exports: CreateInvoice, CreateEstimate, GetInvoice, GetPlayerInvoices, PayInvoice, RespondToEstimate, SendInvoiceReminder, CancelInvoice, and GetBillingAnalytics.
  • Subscription server export: GetSubscriptionDiscount(sourceOrIdentifier, jobName) returns the strongest applicable discount percent and its subscription record.
  • Server-local integration events: sky_mechanicjob:server:pricingQuoteCreated, sky_mechanicjob:server:pricingQuoteExpired, sky_mechanicjob:server:supplierStockChanged, sky_mechanicjob:server:invoiceCreated, sky_mechanicjob:server:invoiceStatusChanged, sky_mechanicjob:server:invoiceOverdue, sky_mechanicjob:server:invoicePaymentRecorded, sky_mechanicjob:server:estimateResponded, sky_mechanicjob:server:invoiceReminderSent, and sky_mechanicjob:server:invoiceCancelled.

Integration state

Keep Config.OilLeaks.enabled = true only when Config.OilLeaks.integration.resource names the intended compatible provider. The relay accepts resource states starting and started; every other state rejects it and writes an English debug diagnostic containing the provider and state. No player-facing notification is emitted for this rejection. Start the configured provider before Mechanic, choose another compatible provider, or deliberately disable Config.OilLeaks.enabled.

Database and inventory

Run the complete import.sql before startup when Config.AutoExecuteQuery = false. It makes every one of these schema changes:

  • Creates sky_mechanic_subscription_settings with society_job, enabled, models, updated_by, and updated_at; primary key society_job.
  • Creates sky_mechanic_subscriptions with id, identifier, society_job, model_id, model_label, discount_percent, price_paid, purchased_at, expires_at, and updated_at; one customer/workshop unique key plus expiry and workshop/expiry indexes.
  • Creates sky_mechanic_job_subscriptions with id, customer_job, society_job, model_id, model_label, discount_percent, price_paid, purchased_by_identifier, purchased_by_name, purchased_at, expires_at, and updated_at; one company/workshop unique key plus expiry and workshop/expiry indexes.
  • Adds document_type, amount_paid, deposit_required, due_at, valid_until, accepted_at, declined_at, reminder_count, reminder_fees, last_reminder_at, and updated_at to sky_mechanic_invoices.
  • Adds category and cost_type to sky_mechanic_invoice_items.
  • Creates sky_mechanic_invoice_payments with id, invoice_id, amount, payment_method, payer_identifier, payer_name, and created_at; indexes invoice/time and creation time.
  • Creates sky_mechanic_pricing_entries with id, order_id, part_index, order_uid, society_job, part_id, part_label, category, vehicle_class, mechanic_grade, retail_revenue, supplier_cost, labor_cost, margin_amount, tax_amount, discount_amount, refund_amount, status, created_at, and updated_at; unique order/part plus job/time, part/time, and status indexes.
  • Creates sky_mechanic_supplier_stock with society_job, item_name, stock, demand, last_restock_at, and updated_at; composite primary key plus update-time index.
  • Adds only the ESX items seed drift_tyres (Drift Tyres, weight 15000, not rare, removable). Register it manually in QBCore, Qbox, ox_inventory, or any other active inventory.

oil_absorbent and broom are pre-existing cleanup items and are not inserted by Mechanic SQL. Confirm both are already registered before enabling their new shop rows. Do not drop or recreate existing invoice, order, tuning, or membership data.

Add a subscription_terminal point to every intended workshop. Restart sky_base, sky_jobs_base, and sky_mechanicjob in that order. Before production use, test item purchases, drift tuning, delivery sprinting, blocked plates, maintenance notices, subscriptions, billing/partial payments, class pricing, advanced pricing, and the configured oil relay with disposable data.

Version 1.22.0

Update sky_base to 1.33.0 and sky_jobs_base to 1.36.0 before updating sky_mechanicjob.

Highlights

  • Reliable parts deliveries - partial deliveries preserve their remaining items, pallets keep their targets after movement, carried boxes clean up correctly, and failures return a clear result.
  • Server-side mechanic integrations - trusted server resources can repair vehicles or wheel damage, inspect and repair wear/condition, check whether tuning exists, and react to completed mechanic operations.
  • Global Stance control - Stance can be disabled as one complete feature and reacts to Job Configurator changes without a resource restart.
  • Per-location vehicle-class enforcement - self-service tuning points can apply their configured class whitelist before opening.

Notable Changes

  • Test-drive vehicles are excluded from persistent wear and wheel-damage processing.
  • Full repairs preserve custom native engine audio and reapply saved Stance values.
  • Orphaned tyre damage, tuning state, welding animations, delivery-box movement, and billing-spec updates are handled more consistently.
  • Workshop lifts and Stance items respond to live configuration changes.
  • Ordered item and vehicle image sources are used throughout shops, diagnostics, tuning, and dealer views.
  • Added a complete Serbian locale.

Other Changes

  • Removed obsolete tyre-reset SQL guidance; no database reset is part of this release.
  • Added focused regression checks for engine audio, install animations, server integrations, and Stance gating.

Changed Files

  • sky_mechanicjob/config/config.lua
  • sky_mechanicjob/config/locales/*
  • sky_mechanicjob/fxmanifest.lua
  • sky_mechanicjob/source/* — delete and reinsert
Update InstructionsWhat to copy, what to keep and what to check1.21.01.22.0

Simplified update

Update sky_mechanicjob safely

Read the complete update instructions in one continuous guide.

  1. Update sky_base to 1.33.0 and sky_jobs_base to 1.36.0.
  2. Back up Mechanic, delete the old folder, and install the complete 1.22.0 package including UI, locales, generated defaults, and manifest.
  3. Without /jobconfig, add Config.ToggleFeatures.stance = true and Config.Interactions.self_service_tuning.vehicleClassWhitelist = true to the new config/config.lua.
  4. With /jobconfig, review and save the managed Stance feature. vehicleClassWhitelist = true is not a normal saved setting: it enables per-location class-whitelist editing for self_service_tuning, so review the allowed vehicle classes on every affected self-service location.
  5. No existing public value was changed or removed. No SQL migration, item, image, or stream asset is required.
  6. Restart Base, Jobs Base, and Mechanic in that order.

Version 1.21.0

Update sky_base to 1.32.0 and sky_jobs_base to 1.35.0 before updating sky_mechanicjob.

Highlights

  • Unpaid public tuning orders - workshops that hide public prices can now accept an unpaid customer order for a mechanic to review and invoice later instead of showing zero-cost work.
  • Lift bypass for unsuitable vehicles - configurable vehicle classes and models, including motorcycles by default, can complete lift-dependent service work without forcing them onto a workshop lift.
  • Better workshop lift placement - creator lifts support gizmo placement, initialize vehicle control before lifting, and handle order/service actions more reliably.
  • Clearer drivetrain tuning - the active drivetrain and drivetrain presets are visible in the correct Handling and Performance sections.

Notable Changes

  • Custom wheels are installed and displayed correctly in tuning flows.
  • Parts deliveries use the active job's delivery bay instead of another workshop's location.
  • Public-order price visibility now clearly distinguishes paid self-service orders from mechanic-invoiced unpaid orders.
  • Nitro no longer repeats a missing-system notification while the control key is held.
  • Missing Base or Jobs Base dependencies are reported clearly during startup.

Other Changes

  • Restored German characters and refreshed the setup documentation.
  • Updated the resource version to 1.21.0.
Update InstructionsWhat to copy, what to keep and what to check1.20.01.21.0

Simplified update

Update sky_mechanicjob safely

Read the complete update instructions in one continuous guide.

  1. Update sky_base to 1.32.0 and sky_jobs_base to 1.35.0.
  2. Download sky_mechanicjob 1.21.0 and create a resource backup.
  3. Delete the old resource folder and install the complete new folder.
  4. Transfer your server-specific values into the new config files. Keep placementGizmo = true and do not restore the removed drivetrainWhitelist.
  5. Without /jobconfig, add liftBypassVehicleClasses = { 8 } and liftBypassVehicleModels = {} under Config.OrderInstall, then choose the intended publicUsersSeePrices behavior. With /jobconfig, review those settings there.
  6. No SQL migration or new inventory item is required.
  7. Restart sky_base, sky_jobs_base, and sky_mechanicjob in that order.

Version 1.20.0

Update sky_base to 1.31.0 and sky_jobs_base to 1.34.0 before updating sky_mechanicjob.

Highlights

  • Fake plates survive compatible garage storage - new compatibility helpers let garage resources resolve the real stored plate while Police, radar, dispatch, and visible UI can continue to see the active fake plate.
  • Safer RGB controller tuning - mechanics can only edit installed neon directions, unavailable controls are disabled, and vehicles without compatible neon are rejected clearly.
  • Workshop management in Job Configurator - workshop entries now have a dedicated creator section with localized labels and job-aware filtering.
  • Optional mechanic-first repair policy - repair-kit use by non-mechanics can be blocked while a mechanic is on duty, with a clear localized message.

Notable Changes

  • Added the Full Dark theme across Mechanic tablet apps.
  • Fake plate state can be restored after compatible garage flows instead of being lost during storage.
  • Vehicle ownership queries now use owned_vehicles on ESX and player_vehicles on QB-based frameworks.
  • Custom chrome paint is hidden and rejected when the active tuning profile does not allow it.
  • Mechanic item and vehicle artwork now supports PNG and WebP fallbacks.

Other Changes

  • Added public compatibility files and setup guidance for fake-plate-aware garage resources.
  • Updated the resource version to 1.20.0.

Version 1.19.0

Update sky_base to 1.30.0 and sky_jobs_base to 1.33.0 before updating sky_mechanicjob.

Highlights

  • Complete fake plate system - mechanics can create and install temporary display plates with ownership, distance, engine, duplicate, cooldown, expiry, crash-loss, blacklist, and audit controls.
  • Synchronized engine-sound previews - preview revs are relayed to nearby players so engine-sound tuning can be evaluated together before purchase.
  • Safer workshop deletion - jobs with active deliveries, tuning work, invoices, or vehicle service obligations cannot be removed until their operational records are resolved.

Notable Changes

  • Framework-spawned vehicles now restore broken tyres, doors, and windows along with their other saved properties.
  • Overdue delivery orders are promoted when ready orders are fetched, and on-duty staff receive refreshed ready pallets.
  • Duplicate vehicle-lift props are prevented after reconnects and creator-owned lift props disappear when their creator entry is deleted.
  • The mechanic tablet closes correctly after invoice payment.
  • Sliders update visually when a tuning option is reset to its default.
  • Registered Job Configurator defaults now cover the complete current mechanic configuration.
  • Added an administrator command permission for resetting an active fake plate.

Other Changes

  • Added configurable optional risk and illegal-market rules for fake plates.
  • Added audit storage and default item records for blank plates, fake-plate kits, plate scanners, and plate printers.
  • Updated the resource version to 1.19.0.

Version 1.18.0

Before updating, make sure sky_base and sky_jobs_base are up to date. The updated Job Configurator defaults and config import flow require the matching shared-resource release.

Highlights

  • Tyre repairs now follow each damaged wheel. Missing and burst tyres are tracked individually, mechanics work on the affected side with the car jack, and Vehicle Diagnostics shows the remaining tyre condition and repair progress.
  • Optional vehicle-fire integration with Sky Fire Job. Critical engine damage and severe frontal impacts can create configurable vehicle fires when sky_firejob is available, while mechanic repairs clear matching fire and entrapment states.
  • Safer Job Configurator defaults and imports. Shipped defaults remain stable even when local config files are customized, and existing local values can be imported deliberately through the matching jobs-base workflow.

Notable Changes

  • Added configurable workshop map blips, including station labels, sprite, color, scale, display mode, and short-range behavior.
  • Added optional mechanic notifications when customers place self-service tuning orders, with an optional vehicle plate in the message.
  • Added configurable non-minigame installation rules for large vehicles and selected vehicle models.
  • Vehicle washing and waxing now support large vehicles more reliably.
  • Tire smoke color changes now preview live during tuning, with smoother preview updates and restoration when the preview is cancelled.
  • Added /fix as an admin repair alias.
  • Instant Tuning now consistently rejects Stance wheel-size and wheel-width options when those features are disabled.

Other Changes

  • Improved tyre repair restoration so unrelated body, engine, window, door, dirt, and remaining wheel damage are preserved correctly.
  • Improved oil-leak diagnostics for frontal-impact and active-leak flows.
  • Wear, oil-leak, fire, and wheel-damage effects no longer apply to invulnerable vehicles.
  • Pressing the Nitro control no longer shows a missing-installation notification when Nitro is disabled for the current job.
  • Job Configurator fire settings are hidden automatically when the optional Fire Job integration is unavailable.
  • Workshop Creator-owned settings remain sourced from customer configuration during generated-default builds.

Version 1.17.0

Before updating, make sure sky_base and sky_jobs_base are up to date. Several billing and storage improvements require the matching jobs-base release.

Highlights

  • Billing was expanded as one complete workflow. Mechanic billing now supports protected default prices, Bossmenu custom positions, editable custom invoice prices, saved labels, and cleaner Billing settings inside the Job Configurator.
  • Order parts can be taken from job storage. Mechanic jobs can choose whether tuning-order parts are consumed from the player's inventory or from the workshop's shared storage.
  • Vehicle and Nitro systems were tightened up. Wheel tasks now follow the real vehicle wheel count, diagnostics repairs have a safer vehicle-class fallback, pushed vehicles align better with stance height, and external Nitro HUDs have a supported API.

Notable Changes

  • Added a Custom position dropdown to the mechanic tablet Billing app for boss-created custom prices.
  • Custom invoice positions support editable prices when custom prices are enabled and are stored as normal invoice items.
  • Added a new inventory image for engine_sound_kit.
  • Added the per-job Order item source setting for Player inventory or Storage.
  • Storage mode shows combined job-storage item amounts in Orders and consumes installed parts directly from storage.
  • Mechanic default billing rows are now protected in Bossmenu and keep their labels and prices synchronized.
  • Mechanic billing price controls are shown inside the Billing settings page instead of a separate Billing Prices tab.
  • Added Config.Nitro.externalUpdateIntervalMs in config/adv_config.lua for external Nitro HUD update timing.
  • Vehicle wheel tasks now adapt to the real vehicle wheel count, so motorcycles use front/rear tasks while cars keep four wheel positions.
  • Vehicle persistence was adjusted to avoid engine sound dropouts and fuel HUD value jumps while driving.
  • Vehicle push animations now stay aligned better on vehicles with raised stance settings.
  • Vehicle Diagnostics repairs now work better on server artifacts where the server cannot read the vehicle class directly.
  • Added an external Nitro HUD API for resources that want to display their own Nitro interface.

Version 1.16.0

Before updating, make sure sky_base and sky_jobs_base are up to date. The configurable Instant Tuning profile and workshop vehicle-class selection require the matching shared-resource releases.

Highlights

  • Configurable Instant Tuning. Administrators can now control the performance stages, appearance modifications, wheel types, special options, and individual values available at global Instant Tuning locations. Client menus use the dedicated profile, and purchases are validated by the server.
  • Workshop vehicle specializations. Each mechanic workshop can be limited to selected GTA vehicle classes. The restriction applies to tuning, removal, diagnostics repairs, and order installation, while an empty selection continues to allow every class.
  • Configurable vehicle fluid leaks. Severely damaged engine-oil or transmission-fluid parts can create fluid trails while driving. Heavy frontal impacts can also create an immediate spill and start a configurable timed leak for combustion vehicles.

Notable Changes

  • Existing Job Configurator entries are migrated automatically to add engine_sound_kit to the normal mechanic shop and tablet Parts Shop. The migration is idempotent and preserves custom items and prices.
  • Added configurable thresholds, probabilities, intervals, speed and distance limits for wear-based oil leaks under Config.OilLeaks.
  • Added configurable frontal-impact detection using impact speed, speed loss, vehicle damage, optional front deformation, trigger chance, cooldown, leak duration, and spill radius.
  • Added all vehicle fluid leak and frontal-impact settings to the global in-game Job Configurator under Vehicle Fluid Leaks.
  • Added configurable provider routing plus SetFluidLeakProvider and ResetFluidLeakProvider client exports for external spill systems.
  • Added inventory definitions for engine_sound_kit to the ox_inventory, qs-inventory, QB-Core, and ESX documentation examples.

Fixes and Improvements

  • Fixed custom xenon RGB colors reverting to white after server restarts or garage cycles. Persisted indexed and custom colors are now reapplied after late garage property updates, and transient white values no longer overwrite the saved color.
  • Fixed txAdmin vehicle repair leaving Vehicle Diagnostics parts damaged. Repairing the occupied vehicle now restores all wear parts, clears catalytic-converter damage when required, and synchronizes the repaired state to clients.
  • Fixed mechanic debug messages appearing while sky_base debug mode was disabled. Debug helpers now consistently use the shared gated logger without suppressing production warnings or errors.
  • Fixed /debugwearzero engine_oil being interpreted as a vehicle plate. The command now supports both /debugwearzero [part] for the current vehicle and /debugwearzero [plate] [part].
  • Improved frontal-impact detection with a short sampling window and removed reliance on GTA's short-lived collision flag.

Version 1.15.0

Before updating, make sure sky_base and sky_jobs_base are up to date — install the matching releases first. This release also aligns the inventory calls with the matching sky_base release; running it against an older sky_base can break item add/remove.

Highlights

  • Self-service engine sound orders. Customers can now buy custom engine sounds through self-service tuning, fulfilled as a mechanic tablet order. The install flow opens the hood, plays a mechanic work animation, applies the selected sound, and closes the hood. A new engine_sound_kit item is required for the order.
  • Configurable engine sound prices. Each custom engine sound can have its own fixed price, including fallback and stock-restoration prices. Prices show correctly in the tuning basket and respect the instant-tuning price multiplier.
  • Physical brake installs. Normal and ceramic brake tuning now use the same workshop-lift workflow as stance installs — the vehicle must be raised, and the mechanic is guided through all four wheel positions with brake-specific checklist and radial text before the install completes.
  • Plate installs at the plate. License-plate tuning (plate holder, vanity plate, plate style) now requires the mechanic to stand at the front or rear license plate instead of the vehicle side, with a dedicated checklist step, a contextual radial action, and front/rear distance checks.

Notable Changes

  • Stance wheel size & width toggles — separate mechanic feature toggles for Stance wheel size and wheel width, disabled by default. When off (via config.lua or the in-game Job Configurator), the related Stance sliders are removed from tuning menus and their values are ignored everywhere, so wheel-scale tuning is not applied.
  • Engine sound preview no longer touches the radio — applying or previewing a custom engine sound no longer turns the GTA vehicle radio on or switches stations. A dedicated EngineSounds.disableVehicleRadio toggle optionally suppresses only the normal vehicle radio, without changing the custom engine audio itself.
  • Plate install positioning — new Config.OrderInstall.plateInstallDistance and plateInstallSideTolerance tune how close and how centered on the plate the mechanic must stand for plate installs.

Fixes and Improvements

  • Fixed engine hoist props not always appearing after a server start or player join until sky_mechanicjob was restarted — the hoist props are now re-synced and respawned reliably during startup.
  • Fixed custom engine sounds not always persisting for tuning orders or after a vehicle was spawned from a garage — live engine-sound state is now saved and reapplied after restore, so late garage writes can't leave the vehicle on stock audio.
  • Fixed mechanic paint and persisted tuning not applying immediately to vehicles spawned through Quasar AdvancedGarages map parking — saved paint, stance, RGB, and performance tuning are now reapplied before the player enters the vehicle.
  • Fixed vehicle mileage resetting when a player drove a vehicle and then disconnected or restarted the resource without a normal driver-exit — mileage is now saved periodically while driving and once more on resource stop.
  • Migrated internal item add/remove calls to the new sky_base inventory signature (slot + metadata).

Version 1.14.0

Before updating, make sure sky_base and sky_jobs_base are up to date. This release uses the latest shared interaction, Job Configurator, and tablet notification behavior.

Highlights

  • Added synchronized custom engine sounds with an audible tuning preview for the mechanic and nearby players.
  • Added a multiplayer vehicle push system for heavily damaged vehicles, including steering, stamina, terrain effects, and support for up to three players.
  • Added finer per-job tuning controls for individual upgrade stages, values, and paint ranges such as Chameleon colors.
  • Improved Stancer synchronization, tuning preview protection, Parts Delivery notifications, and overall client performance.

Notable Changes

  • Custom engine sounds are now replicated through the vehicle state so nearby players hear the selected sound. The engine continuously revs while an Engine Sound option is focused, making sounds easier to compare before purchase.
  • Engine sound entries accept common field formats and case-insensitive matching while preserving the configured GTA audio name.
  • Disabled vehicles can be pushed from the front or rear with E, steered with A/D, moved with W/S, and boosted with SHIFT.
  • Vehicle pushing supports weight classes, slopes, stamina, helper bonuses, synchronized three-player formations, automatic cancellation, and a dedicated status HUD.
  • Tuning profiles can enable or disable individual upgrade stages and use allowedValues or blockedValues for exact values and ranges.
  • The Job Configurator now provides value controls and presets for Standard and Chameleon paint ranges without requiring manual JSON editing.
  • Realistic Wheel Damage multipliers now update immediately after saving Job Configurator changes and support decimal values such as 0.1.
  • Secondary tuning sections are grouped under a localized More menu, while the main categories and basket stay directly accessible.

Fixes and Improvements

  • Unpaid tuning previews now freeze the connected vehicle and restore its original state if the player exits, changes driver, moves the vehicle, or leaves the workshop area.
  • Stancer wheel size, wheel width, camber, track width, and suspension height remain more reliable after rim changes, installation, garage spawning, vehicle damage, stream-in, and driver changes.
  • Parts Delivery notifications now validate that a delivery still exists before creating a waypoint. Valid notifications mark the pickup location instead of reopening the Parts Shop.
  • Mechanic tablet apps are registered for mechanic jobs created only through /jobconfig, not only jobs listed in config.lua.
  • Reduced idle client usage for Stancer updates, vehicle persistence, vehicle push detection, Parts Delivery checks, and self-service tuning interactions.
  • Healthy vehicles can no longer be pushed only because their engine was switched off.

Version 1.13.0

Before updating, make sure sky_base and sky_jobs_base are up to date.

Highlights

  • Added partial tuning-order refunds for individual uninstalled positions or all remaining uninstalled positions while keeping installed tuning paid.
  • Added live inventory counters for every required part in the mechanic tablet's tuning-order details.
  • Added per-job Nitro access overrides with inherit, enabled, and disabled modes.
  • Added configurable account or inventory-item payouts for the stolen parts dealer.
  • Added configurable Stancer slider scales, bounds, and defaults.
  • Added an external HUD visibility hook for tuning sessions.

Notable Changes

  • Refunded tuning positions now keep their amount, timestamp, and responsible employee for a complete audit trail.
  • Order totals and statuses are recalculated after partial refunds, and refunded positions can no longer be installed.
  • Server-side order locking prevents refund and installation actions from modifying the same order simultaneously.
  • Required-part counters total matching items across all inventory slots and display (0) when an item is missing.
  • Parts Delivery now waits for valid network IDs, recreates invalid delivery entities, retries client resolution, and requests a fresh sync when necessary.
  • Delivery resolver threads are cancelled when deliveries are removed, preventing missing or resurrected pallets and repeated network-object warnings.
  • Wheel size and width synchronization now handles late-streaming garage vehicles, delayed property restoration, changed wheel setups, and superseded state updates.
  • Instant Tuning now has its own localized menu title while preserving the existing Admin Tuning, Self Service Tuning, RGB Controller, and Stance Kit titles.
  • Stance wheel adjustments on Workshop Lifts now use the dedicated streamed tune/anim animation and continue when FiveM reports a custom clip duration of 0.0.
  • Per-job Nitro access is enforced for boost use, Nitro Kit installation, installation callbacks, and state updates without restricting other workshop tuning features.
  • Stolen parts dealer item payouts validate inventory capacity and restore the sold part if the payout item cannot be added.
  • Saved vehicle-specific Stance values remain higher priority than configured slider defaults, while Reset Stance still restores the captured factory state.

Other Changes

  • Added Config.Functions.SetExternalHudVisible(visible) so external HUDs can be hidden while tuning is open and restored through every central close path.
  • External HUD export failures are logged without blocking the tuning menu.
  • Existing tuningCostProfile.nitroAccess values remain supported as a compatibility fallback.
  • Added detailed stolen parts dealer diagnostics for configurator updates, payout targets, inventory checks, framework results, and balances.
  • Added validation for invalid Stancer scales and reversed slider bounds.
  • Added the localized Instant Tuning title to every bundled mechanic locale and rebuilt the production NUI.

Version 1.12.0

Before updating, make sure sky_base and sky_jobs_base are up to date.

Highlights

  • Added support for GTA V's VMT Lightbar tuning slot, including pricing, required items, previews, installation, localization, and persistence.
  • Added automatic Workshop Lift detection for configured MLO/YMAP lift props and support for multiple lift model sets.
  • Reworked Stance installation into a physical four-wheel Workshop Lift workflow for tuning orders and the usable Stance Kit.
  • Added optional police dispatch alerts for successful wheel and catalytic converter thefts.

Notable Changes

  • Stance changes are now installed at all four wheel positions while the vehicle is raised on a configured Workshop Lift.
  • A localized Stance checklist and contextual radial actions track each completed wheel position before the selected Stance is applied and saved.
  • Existing matching MLO/YMAP lift props can now be reused instead of spawning duplicate lift objects.
  • Configured lift prop pairs can be discovered automatically without placing a workshop_lift point in Workshop Creator.
  • Compatible vehicles now show Lightbar variants from modification slot 49 in the Bodywork tuning section; vehicles without variants remain unchanged.
  • Repair Kits can now separately control normal vehicle damage, realistic wheel damage, and every mechanic wear part they restore.
  • Persisted engine, brake, transmission, suspension, turbo, armor, and Custom Handling upgrades are restored more reliably after garage spawning.
  • Self-service tuning markers are restored correctly when older Job Configurator data contains self_service_tuning.interaction=false.
  • Successful parts thefts can send configurable police dispatches with custom jobs, title, message, and cooldown.

Other Changes

  • Added Config.Functions.SendPartsTheftDispatch(source, data) so server owners can replace the default sky_jobs_base dispatch integration.
  • Existing MLO lift props are preserved during cleanup, refreshes, and resource stops.
  • Added periodic lift prop discovery for MLO objects that stream in after resource start.
  • Added detailed stolen parts dealer payout diagnostics for the active payout account, inventory changes, framework payout result, and before/after balances.
  • Added performance tuning values to vehicle persistence debug logs.

Version 1.11.0

Before updating, make sure sky_base and sky_jobs_base are up to date.

Highlights

  • Added new admin and server-owner tools for repairs, rollover behavior, and delivery visibility.
  • Improved Workshop Lift reliability and several mechanic install flows.
  • Improved saved tuning reliability for job garage vehicles, Stancer, Custom Handling, and custom lights.

Notable Changes

  • Admins can now use /repair, /repair me, or /repair [id] to fully repair a vehicle.
  • Full repairs now also clear mechanic damage effects that could make a repaired vehicle still feel slow, stuck, or undriveable.
  • Server owners can now disable GTA's default rollover recovery through Config.VehicleRolloverRecovery.
  • Workshop Lifts now clean up old lift props better and recover raised vehicles after a sky_mechanicjob restart.
  • Lift controls are easier to reach when standing beside the platform or vehicle.
  • Parts Delivery now has a small optional timer HUD with remaining time, progress, status, and order reference.
  • The delivery timer can be turned on/off and moved through the Job Configurator.
  • Spoiler installs now happen at the rear of the vehicle and no longer require opening the hood.
  • Underbody neon installs no longer ask for the lift step again if the vehicle is already raised.
  • Job garage vehicles can now correctly save and load mechanic tuning such as Stancer, Custom Handling, RGB, Nitro, Anti-Lag, and Two-Step.
  • Stancer reset and saved defaults are safer now, especially for vehicles that previously had broken wheel size or width values.
  • Stancer changes should now sync more reliably for nearby players and no longer cause wheel scale issues after reset or parking out.
  • Stancer is now ignored for unsupported vehicle types such as bikes, boats, helicopters, planes, and trains.
  • Custom xenon colors now save with the correct RGB color, so red no longer comes back as green and yellow no longer comes back as cyan.
  • RGB Controller changes now save automatically when the controller menu is closed.

Other Changes

  • Added more debug information for Workshop Lift troubleshooting.

Version 1.10.0

Before updating, make sure sky_base and sky_jobs_base are up to date.

Highlights

  • Improved vehicle repair reliability so fix kit repairs now also reset mechanic wear consequences and limp-mode states.
  • Stabilized Stancer defaults, persistence, wheel size, and wheel width handling across tuning, checkout, parking, and restarts.
  • Added stronger RGB xenon and neon persistence guards so saved light settings are not overwritten by temporary stock-like vehicle reads.
  • Added Workshop Lift debug diagnostics to help investigate invisible, duplicated, or incorrectly synced lift props.
  • Improved Job Configurator integration by disabling the legacy Workshop Creator when the configurator flow is active.

Notable Changes

  • Fixed normal fix_kit repairs so they clear transmission limp mode, electric limp mode, engine damage, undriveable state, and related wear effects.
  • Fixed stale physical carry item states so mechanics can take parts from storage again without needing to reconnect.
  • Updated the mileage HUD runtime toggle so it appears or disappears immediately for active drivers after Job Configurator changes.
  • Reworked Stancer reset/default handling so vehicle defaults are captured once and custom stance changes are saved separately.
  • Preserved persisted Stancer values when unstable native reads return stock-like values during save or restore windows.
  • Improved Wheel Size and Wheel Width handling with dedicated Stancer option detection, tire/rim collider updates, and debug readback output.
  • Protected saved xenon and underbody neon settings from being replaced by transient disabled/default live reads outside active tuning sessions.
  • Added localized Workshop Creator disabled messages for all supported mechanic locale files.
  • Added detailed debug-only lift logs for model names, hashes, entities, coordinates, nearby objects, cleanup, creator sync, and attach/detach broadcasts.

Version 1.9.0

Before updating, make sure sky_base and sky_jobs_base are up to date.

Highlights

  • Improved mechanic tuning, carry-item, parts delivery, and instant tuning flows.
  • Added Engine Hoist support for engine installs.
  • Added better Instant Tuning management through the Job Configurator.

Notable Changes

  • Fixed engine installs so carried engines and inventory engines are both handled correctly.
  • Fixed moved parts delivery pallets so they can still be unpacked.
  • Fixed tuning freecam focus so players can return to the tuning UI more reliably.
  • Fixed tuning basket removal so other preview changes are not lost.
  • Fixed unpaid light previews so they are restored when tuning is closed.
  • Added stancer support to the applied tuning list in the mechanic tablet.
  • Added an admin full vehicle repair export.
  • Improved customer name display by preferring in-game character names.
  • Fixed self-service tuning so it creates mechanic orders again.

Version 1.8.0

Before updating, make sure sky_base and sky_jobs_base are up to date.

Highlights

  • Added shared in-game job configurator support for mechanic jobs, features, interactions, pricing/settings, parts delivery, wear, wheel damage, vehicle care, and carry-item settings.

Notable Changes

  • Fixed Nitro, Anti-Lag, and Two-Step backfire effects on tuned exhausts through shared vehicle effect handling.
  • Added config/adv_config.lua and moved advanced/static settings out of the main config/config.lua.

Version 1.7.1

Before updating, make sure sky_base and sky_jobs_base are up to date.

Changes

  • Fixed vehicle color handling so selected paint, custom colors, pearlescent, wheel, dashboard, and interior colors are kept more reliably after tuning and restoring vehicles.
  • Reworked Stancer saving and loading so stance changes stay synced better, while self-service previews no longer save unpaid changes before checkout.

Version 1.7.0

Before updating, make sure sky_base and sky_jobs_base are up to date.

Highlights

  • Stancer persistence was fully stabilized across re-enter, garage outpark, impound retrieval, menu close/reopen, and resource restart.
  • Vehicle restore timing and guard flow were cleaned up to stop duplicate overwrite waves and workshop flicker behavior.
  • Core runtime systems (Anti-Lag, Nitro, Two-Step, Self-Service pricing, Instant Tuning access) were unified and made more reliable.

Notable Changes

  • Stancer persistence overhaul:
    • Added session snapshot + dirty-state handling to prevent transient GTA defaults from overwriting tuned stance.
    • Added immediate debounced save for camber, track width, suspension height, wheel size, and wheel width.
    • Added stronger delayed stance stability checks for suspension/camber/track after restore.
  • Persistence stability fixes:
    • Fixed runtime blockers around sanitizePlate and lastKnownStanceByPlate.
    • Fixed local guard scope/order in vehicle persistence to prevent purchase callback instability.
    • Reduced broad reapply storms and duplicate late restore paths.
  • Self-Service / Instant Tuning:
    • Public self-service pricing visibility is now controlled by Config.TuningCostProfile.publicUsersSeePrices.
    • Instant tuning now supports global and per-location job restrictions (mechanicOnly, allowedJobs/jobs) with client/server enforcement.
  • Two-Step / Anti-Lag / Nitro runtime:
    • Anti-Lag moved to config-driven runtime balancing.
    • Two-Step now includes configurable launch-control behavior and improved trigger consistency.
    • Nitro got live HUD/progress sync improvements, better hide behavior, and stronger config runtime control.

Other Changes

  • Reduced repeated paint apply bursts and restore spam in heavy spawn/re-enter windows.
  • Improved tuning close behavior so unpaid preview/reset flows do not persist unintended changes.
  • Reduced mechanic debug console noise by gating noisy traces behind debug mode.
  • Improved diagnostics tyre-item validation to enforce server-authoritative repair item checks.

Version 1.6.0

Before updating, make sure sky_base and sky_jobs_base are up to date.

Highlights

  • Reworked vehicle persistence and restore handling to make tuning states more stable after garage, impound, outpark, re-enter, and restart flows.
  • Improved paint, pearlescent, wheel color, xenon, RGB, and livery synchronization to reduce color resets and duplicated visual apply behavior.
  • Improved stance persistence for critical values such as camber, suspension, track width, wheel size, and wheel width.

Notable Changes

  • Added stronger one-shot restore guards so vehicles are not repeatedly overwritten after spawning or entering.
  • Reduced aggressive restore waves and apply storms that caused marker, menu, or workshop flickering.
  • Cleaned overlapping spawn, enter, delayed restore, and restart apply paths.
  • Improved Self-Service tuning flow so purchases, snapshots, and applied vehicle states stay more consistent.
  • Improved support for native liveries and mod slot 48 liveries while removing duplicate livery entries.

Other Changes

  • Reduced random stancer resets after seat changes, vehicle re-enter, garage, and impound transitions.
  • Improved persistence fallback for critical stance and vehicle appearance values.
  • Reduced repeated paint apply bursts after full vehicle restore.
  • Softened runtime stabilization to avoid unnecessary continuous forcing.
  • Decoupled broad global vehicle apply triggers such as entityCreated.
  • General cleanup of restore, save, load, and apply logic.

Version 1.5.0

Before updating, make sure sky_base and sky_jobs_base are up to date.

Highlights

  • Added optional physical item carrying through Config.CarryItems, where delivered orders must be unpacked and parts become physical objects that mechanics carry through the workshop by hand or transport in bulk with pallets and forklifts.
  • Added workshop prop placement support, including configurable props such as cones, barriers, work lights, and parts boxes for better rp.

Notable Changes

  • Added a forklift to the default mechanic vehicle list for workshops that use physical delivery handling.
  • Added optional drivetrain swap whitelisting through Config.CustomHandlingOptions.drivetrainWhitelist for vehicles that are safe to switch between drivetrain presets.
  • Tuning orders are now scoped per workshop, and the vehicle registry now keeps each mechanic business separated correctly.
  • Added Kiminaze Advanced Parking integration to avoid duplicate vehicles during stance resets.
  • Improved install flows by skipping hood-opening steps on vehicles without a hood and hiding armor tuning on bikes.

Other Changes

  • Improved persistence for window tint, liveries, underbody neons, anti-lag state, and paint data.
  • Fixed vehicles becoming chrome, windows breaking unexpectedly, and braking issues on some addon vehicles.
  • Fixed stance synchronization for nearby players.
  • Refunds are now limited to unstarted orders, and refunded orders can now be deleted.
  • Added Russian translations.

Version 1.4.0

Requires sky_base 1.14.0 or newer andsky_jobs_base 1.15.0 or newer. The admin permission system has been replaced - sky_base must be updated and the three bootstrap ACEs must be added to your server.cfg before ensure sky_base, otherwise /admintuning, /migrate, /workshopcreator, /setboss, and every other admin command will deny everyone except the server console.

Highlights

  • Added an Applied Tuning section to Vehicle Diagnostics App so mechanics can see and set installed tuning back to stock and receive configured install items back.
  • Tuning removal now uses the same install workflows as tuning installs, including wheel, brake, suspension, and simple checklist flows.
  • Added optional workshop-location enforcement for tuning installs and removals through Config.TuningWorkshopRequirement.
  • Added synced stance state so stance changes are visible to nearby players without them entering the vehicle.

Notable Changes

  • Command permissions now use sky_base ACE auto-wiring through Config.CommandPermissions, including the Workshop Creator permission.
  • Parts theft configuration was consolidated into Config.PartsTheft, including lug wrench item settings, stolen wheel item settings, and stolen parts dealer settings.
  • Instant tuning points can now force marker interaction through Config.InstantTuning.forceMarkerInteraction.
  • Vehicle lookup now includes a fallback for police vehicles, fixing car jack, wheel, nitro, and catalytic converter interactions on some vehicle classes.
  • Saved vehicle properties no longer re-apply persisted dirt level when vehicles are entered or tuning data is loaded.
  • Nitro HUD, order item images, and stolen parts dealer images now use the configured NUI item image base from sky_jobs_base.

Other Changes

  • Added Swedish translations.
  • Improved applied tuning loading for diagnostics.
  • Improved stance sync performance.

Version 1.3.0

Before updating, make sure sky_base and sky_jobs_base is up to date.

Highlights

  • Refactored custom handling tuning so saved presets apply more reliably and no longer stack repeatedly on normal vehicle entry.
  • Persisted tuning is now applied when vehicles spawn, so vehicles can receive saved tuning before the player enters them.
  • Added lower-game-build electric vehicle support through Config.ElectricVehicleFallback.models.

Notable Changes

  • Added Config.CustomHandlingOptions.overwriteHandling for servers that use another handling editor which resets vehicle handling on every entry.
  • Custom handling now stores selected profiles instead of raw handling snapshots, making it safer with external handling resources.
  • Added support for fInitialDragCoeff and nInitialDriveGears in custom handling presets.
  • Instant tuning prices now use Config.InstantTuning.priceMultiplier.
  • Performance tuning menus now respect the configured maximum upgrade stage from Config.TuningCostProfile.
  • The tuning UI now receives explicit allowed values for limited upgrade stages instead of assuming every value between min and max is available.
  • Stance suspension height is now re-applied during stance runtime.

Other Changes

  • Fixed custom handling baseline capture before saved tuning is applied.
  • Fixed wheel damage and wheel theft detach handling so stolen wheels keep theft-specific brick behavior.

Version 1.2.0

Before updating, make sure sky_base and sky_jobs_base is up to date.

Highlights

  • Added Vehicle Part Theft as a new criminal gameplay loop where catalytic converters and wheels can be stolen, sold, and repaired.
  • Added the stolen parts dealer interaction and UI so stolen wheels and catalytic converters can be sold to configured NPC dealers.
  • Added realistic theft consequences: stolen catalytic converters change vehicle sound and create smoke, while stolen wheels leave vehicles sitting on bricks.

Notable Changes

  • Added lug wrench theft selection so players can choose whether to steal a wheel or catalytic converter.
  • Added realistic catalytic converter removal and installation minigames using a jack, bolt interaction, and guided checklist flow.
  • Added wheel theft support using the existing wheel workflow, synced missing-wheel state, and inventory rewards.
  • Mechanics can repair stolen parts through diagnostics by replacing catalytic converters or missing wheels.
  • Added electric vehicle wear support for traction batteries and power inverters, including diagnostics labels and repair flows.
  • Tuning options can now be disabled individually and can define their own required install items directly in Config.TuningCostProfile.
  • Added Config.TuningCostProfile.freeVehicles for vehicles that should create free tuning orders.
  • Vehicle purchase price lookup is now configurable through Config.Functions.GetVehiclePurchasePrice.

Other Changes

  • Fixed vehicle paint saving and engine health restoration after re-entering vehicles.
  • Disabled stance support for motorbikes.
  • Self service tuning now always uses a marker instead of target.
  • Added lug_wrench.png, catalytic_converter.png, traction_battery.png, inverter.png, antilag_kit.png, and nitro_kit.png inventory images.
  • Added English, German, and French locale keys for part theft, catalytic converter work, wheel theft, stolen parts dealer, and electric vehicle wear parts.

Version 1.1.0

Before updating, make sure sky_base and sky_jobs_base is up to date.

Highlights

  • Added configurable instant tuning locations that can apply tuning directly without creating a workshop order.
  • Added tuning order refund and completed-order delete actions in the mechanic tablet.
  • Added a fix_kit usable item workflow for repairing nearby vehicles, including realistic wheel damage repair support.

Notable Changes

  • Tuning prices can now use percentage-based or fixed money values through Config.TuningCostProfile.priceType.
  • Tuning cost config keys were standardized from percentage-specific names to generic cost fields.
  • The mechanic tablet now shows order status and payment method, and supports refunded order state.
  • Currency display is now configurable through locale files.
  • Custom handling tuning options now save correctly and show as applied in the tuning menu.
  • Fix kit repairs can reset realistic wheel damage when Config.VehicleCare.repair.fixRealisticWheelDamage is enabled.

Other Changes

  • Added fix_kit.png inventory image.
  • Added society_job, refunded_at, refunded_by_identifier, and refunded_by_name columns to sky_mechanic_tuning_orders.
  • Added English, German, and French locale keys for instant tuning, order refunds, order deletion, fix kit, and configurable currency symbols.
  • Updated French translations.
  • Fixed wheel damage repair behavior when using the fix kit.

Version 1.0.0

Before updating, make sure sky_base and sky_jobs_base is up to date.

Highlights

  • Added a realistic wheel damage system with synced wheel damage state, popped tyres, detached wheels, and handling penalties.
  • Added damaged-wheel repair support through the vehicle diagnostics repair flow.
  • Improved workshop car lift synchronization so raised vehicles and lift attachments stay consistent for other players.

Notable Changes

  • Wheel damage now reacts to collisions and hard landings, with configurable multipliers per vehicle class and off-road wheel type.
  • Wheel damage is synchronized through vehicle state bags and can be reset by mechanic repair actions.
  • Only one wheel can detach from a vehicle at a time to reduce vehicle physics issues.
  • Wheel damage runtime performance was improved and the default config was cleaned up.
  • Sponge and wax inventory item images were added for the vehicle care items introduced in the previous update.
  • Fixed lift vehicle sync and duplicate lift prop issues.

Other Changes

  • Added source/client/wheel_damage.lua and source/server/wheel_damage.lua.
  • Added source/server/lift.lua.
  • Added Config.WheelDamage.
  • Updated the diagnostics tablet flow for damaged wheel repairs.
  • Added wash_sponge.png and vehicle_wax.png inventory images.

Version 0.6.0

Before updating, make sure sky_base and sky_jobs_base is up to date.

Highlights

  • Added vehicle wash and vehicle wax usable-item workflows, including dedicated wash/wax items, animations, particle effects, and a vehicle-care minigame.
  • Added realistic wheel-based brake and suspension install flows so brake and suspension work now uses jack, wheel detach, component install, wheel attach, and jack removal steps.
  • Added a configurable install duration and an on-screen progress bar for non-minigame install actions.

Notable Changes

  • Vehicle wax now keeps a clean vehicle clean for a configurable mileage window through Config.VehicleCare.wax.cleanKilometers.
  • Wash and wax items are now available in the mechanic shop and Parts Shop delivery catalog.
  • Brake pad and suspension wear repairs now use the wheel workflow instead of a simple repair flow.
  • Improved mechanic animations for under-hood repairs, engine swaps, oil draining, oil pouring, and underbody installs.
  • Added storage, locker, and trunk background images for the mechanic UI.
  • Fuel level is no longer overwritten when saving or restoring mechanic vehicle properties.

Other Changes

  • Added source/client/vehicle_care.lua and source/server/vehicle_care.lua.
  • Added Config.OrderInstall.nonMinigameDurationMs.
  • Added Config.VehicleCare for wash and wax item configuration.
  • Added English, German, and French translation keys for vehicle care and the new wheel checklist steps.
  • Fixed repaint workflow particle effects.
  • Updated the wheel attach minigame so brake and suspension workflows can reattach the existing wheel.

Version 0.5.0

Before updating, make sure sky_base and sky_jobs_base is up to date.

Highlights

  • Added the Parts Shop tablet app for mechanic part orders, including catalog browsing, category filters, basket checkout, own-card and company-card payment, and order history.
  • Added Parts Delivery points for Workshop Creator so ordered parts arrive as physical delivery boxes at configured workshop locations.
  • Added tablet push notifications when part deliveries are ready to collect.

Notable Changes

  • Parts purchases can now be logged in the boss menu, including order UID, price, and ordered item summary.
  • Parts deliveries now support delivery ETA, pending/ready/claimed status tracking, claim history, and ready-delivery lookup by delivery point.
  • Delivery box props now scale by order size so larger orders use larger box piles.
  • Company-card checkout now uses the PURCHASE_SUPPLIES job permission and validates company balance before placing an order.
  • The Parts Shop app now reopens correctly after closing the tablet, and app permission routing was fixed.
  • Tuning freecam now blocks player controls while keeping camera look controls available.
  • Wheel lug nut indicators are easier to see in the wheel detach minigame.

Other Changes

  • Added the sky_mechanic_part_deliveries database table and automatic migration support.
  • Added English translation keys for Parts Shop, Parts Delivery, checkout errors, order history, and delivery notifications.
  • Fixed order history timestamps.
  • Improved delivery interaction logic.
  • Refined Parts Shop navbar, color theming, and overall design.

Version 0.4.0

Before updating, make sure sky_base and sky_jobs_base is up to date.

Highlights

  • Added synced custom xenon colors across players, including re-application when vehicles stream in or players join.
  • Added German and French translations.
  • Added a tuning menu reset button for stancing so vehicles can be restored to default stance values directly from the UI.

Notable Changes

  • Improved stancing persistence when leaving and re-entering vehicles, including wheel size, wheel width, camber, track width, suspension height, and wheel rotation values.
  • Improved performance for nitro, anti-lag, two-step, RGB effects, vehicle wear, and general in-vehicle idle loops.
  • Nitro now uses keymapping support through Config.Nitro.activationKey, with separate timing controls for active ticks, input checks, local effects, and remote effects.
  • Engine hoist props created through the Workshop Creator now spawn and sync more reliably from configured placement points.
  • Fixed unwanted neon installs during the order workflow.

Other Changes

  • Fixed stance reset behavior in the tuning menu.
  • Fixed engine hoist placement in the Workshop Creator flow.
  • Cleaned up stancing and nitro runtime logic for better maintainability.
  • Updated two-step default flame scale values.

Version 0.3.0

Before updating, make sure sky_base and sky_jobs_base is up to date.

Highlights

  • Added paid tuning revenue deposits into the mechanic society account through Config.TuningCostProfile.addRevenueToSociety.
  • Added a dedicated vehicle_lights item for light installations, including the item image and tablet/localization labels.
  • Neon, drivetrain, and suspension installs now use the workshop lift flow so mechanics must work below the raised vehicle.
  • Added client and server mileage exports via GetVehicleMileage.

Notable Changes

  • Default tuning install items are now consumed after use through Config.OrderRequiredItems.*.removeAfterUse = true.
  • Neon installation pricing is now included in the tuning cost profile.
  • Mileage HUD design has been refreshed for a more realistic in-vehicle look.
  • Vehicle plate labels now resolve correctly in mechanic state and interaction flows.
  • Shared tuning database helper logic was centralized to reduce duplicate server code.

Other Changes

  • Fixed a database migration primary-key error for vehicle profiles.
  • Fixed fxmanifest warnings.
  • Fixed a tablet navigation issue that could leave players stuck in the tablet.
  • Removed the unused NPC mechanic example from the default config.

Version 0.2.0

Before updating, make sure sky_base and sky_jobs_base is up to date.

Highlights

  • Added the Vehicles App to the mechanic tablet with searchable, paginated vehicle records, linked tuning orders, service history, tags, notes, and gallery image assignment.
  • Added automatic database migration support through Config.AutoExecuteQuery.
  • Added /migrate command for importing tuning data from previous mechanic scripts such as jg-mechanic.

Notable Changes

  • Vehicle history is now logged for order installs, nitro installs/refills, and wear repairs, including used items, mechanic details, duty state, and action metadata.
  • Tuning orders can now link back into the Vehicles App, and vehicle records only list vehicles that have mechanic orders.
  • Tablet apps now reopen and close more reliably, including direct order selection from linked vehicle records.
  • Self-service tuning now supports multiple placement points and requires the player to be the driver.
  • Added optional off-duty job configuration per mechanic job.
  • Xenon color changes now calculate order pricing correctly.

Other Changes

  • Added sky_mechanic_vehicle_profiles and sky_mechanic_vehicle_history database tables.
  • Added /migrate command permission.
  • Added Config.Interactions.self_service_tuning.unique.
  • Removed the example cardealer job from the default config.
  • Improved wear database readiness handling by moving schema setup into the shared mechanic migration flow.

Version 0.1.0

Highlights

  • Initial release of Sky Mechanic Job.
  • Added full workshop-based tuning flow with creator placement support through sky_jobs_base.
  • Added persistent tuning, tuning orders, mileage tracking, and vehicle wear.

Notable Changes

  • Added self-service tuning and mechanic workshop interactions.
  • Added engine swaps, repaint flow, wheel changes, workshop lifts, and engine hoists.
  • Added nitro, anti-lag, two-step, RGB controller support, and custom handling options.
  • Added persistent storage of tuning data in sky_mechanic_vehicle_tuning.
  • Added tuning order persistence in sky_mechanic_tuning_orders.

Other Changes

  • Added admin tools: /admintuning, /debugwearzero, /debugwearzeroall, and /workshopcreator.