Browse docs

Changelog

Full change history for sky_jobs_base.
Before updating, make sure sky_base is up to date.
Current

Version 1.52.0

Highlights

  • Added the full supply storefront and delivery app for ordinary jobs, with job-specific artwork, a shopping basket, order history and personal or company payment.
  • Added physical supply deliveries with boxes, configurable carried items and pallets, partial collection and transfer into authorized job storage.
  • Added multiple access points for shared storage, lockers, shops, wardrobes, duty terminals, boss menus and public forms while preserving existing storage contents.
  • Improved Crime configuration with grouped systems, a single Drug System section and direct navigation to settings with only one page.
  • Added editable prop limits for each garage vehicle, with remaining-stock counts, visible exhausted equipment and a clear unlimited-stock label.
  • Added Collect all to return nearby equipment from the selected vehicle to its stock while leaving other vehicles' and inventory-placed props untouched.

Notable Changes

  • Fixed an issue where changing the online shop switch in General did not remain saved or agree with the Shop tab.
  • Added a configurable direct radio shortcut with no default key, while preserving each player's existing bindings.
  • Improved unavailable radial actions so supported interactions can explain missing requirements while remaining blocked.
  • Fixed an issue where one incoming native phone call could be recorded in multiple dispatch centres at the same time.
  • Fixed an issue where directly assigning a dispatch unit failed while recording the activity message.
  • Fixed an issue where a prepared tablet notification could appear for another character or job after switching context.
  • Added optional Chezza and Hex inventory integrations that recognize Sky restraints without requiring the original Jaksam Jobs Creator.
  • Fixed an issue where removing placed vehicle equipment did not restore its available stock.
  • Improved vehicle prop selectors so stock changes appear while the menu is open and delayed responses cannot overwrite another vehicle's selection.

Other Changes

  • Improved standalone form controls and floating selectors with neutral backgrounds and the configured job colour.
  • Improved shop categories, information cards, prices and product images with matching job colours and neutral image backgrounds.
  • Added a dedicated restraint-tool image and expanded supply-delivery and Crime setting translations.
  • Changed insufficient-funds boss-menu notices to informational logs while retaining error logs for actual failed transactions.
  • Added translated vehicle-stock labels, collection controls and prop-limit descriptions across all seventeen supplied languages.

Changed Files

  • sky_jobs_base/config/config.lua
  • sky_jobs_base/config/inventory/README.md
  • sky_jobs_base/config/inventory/chezza_restraints.lua
  • sky_jobs_base/config/inventory/hex_restraints.lua
  • sky_jobs_base/config/inventory/restraint_tool.png
  • sky_jobs_base/config/locales/*
  • sky_jobs_base/fxmanifest.lua
  • sky_jobs_base/import.sql
  • sky_jobs_base/source/* — delete and reinsert
Update InstructionsWhat to copy, what to keep and what to check1.51.01.52.0

Simplified update

Update sky_jobs_base safely

Read the complete update instructions in one continuous guide.

1. Back up and stop the server

Update sky_jobs_base from 1.51.0 to 1.52.0. For an older installation, complete the intervening guides first.

  1. Download 1.52.0 and extract the ZIP.
  2. Back up the installed resource folder and game database outside resources/.
  3. Stop the whole server in txAdmin or your hosting panel.
  4. Update Base to 1.49.0 during the same maintenance. If you use Sky Mechanic, also update it to 1.38.0; the shared supply owner and the Mechanic adapter must match.

2. Install the complete runtime and support files

Inside the installed sky_jobs_base folder:

  1. Delete source/ and copy the complete new source/ folder from 1.52.0 into its place.
  2. Replace fxmanifest.lua and import.sql with the files from the same download.
  3. Replace the complete config/locales/ folder, including the Job Configurator language packs. Transfer only your edited wording from the backup into matching new entries and keep new keys.
  4. Copy config/inventory/README.md, config/inventory/chezza_restraints.lua, config/inventory/hex_restraints.lua and config/inventory/restraint_tool.png to the same paths. The hook files are optional integrations; copying them does not enable them in your inventory.
  5. Keep your existing config/config.lua, jobs, item definitions and other unchanged configuration. Follow the settings step for its new options.

No streamed models need replacing for this update. The delivery props use the configured GTA models.

3. Preserve saved settings and add file-based options

Open the installed sky_jobs_base/config/config.lua and find Config.UseIngameConfigurator.

true (normal setup): keep it enabled. Existing saved settings remain, and missing new defaults are supplied automatically. No /jobconfigimport is required. Do not import the download just to obtain new settings, because that can overwrite your saved choices. The optional in-game changes below can be made after startup.

Only when Config.UseIngameConfigurator = false: open the installed sky_jobs_base/config/config.lua and make these additions. Keep every existing job, location, provider secret and other setting.

  1. Find Config.Tablet = { ... }, then its apps = { ... } table. Immediately after the existing online_shop = ... entry, add online_shop_deliveries = true, if it is missing. Use false instead if you deliberately hide the new delivery app.
  2. Find Config.Bells = { ... }. After that table's closing }, and before Config.Interactions = {, add this complete block if Config.OnlineShopDelivery does not already exist:
Config.OnlineShopDelivery = {
    allowsprint = true,
    openDurationMs = 5500,
    interactionDistance = 2.0,
    boxModel = "prop_cs_cardbox_01",
    carryItems = {
        enabled = true,
        storageDistance = 2.5,
        forkliftModels = { "forklift" },
        items = {},
        deliveryPallet = { enabled = true, prop = "prop_boxpile_02c" },
    },
}
  1. Within the existing Config.Interactions table, find boss_menu, duty_terminal, wardrobe, storage, locker, wholesale_shop and public_forms. Add unique = false, immediately after each entry's opening { if you want more than one access point of that type. Replace an existing unique = true, instead of adding a duplicate. Keep an explicit true where a single point is intentional. Multiple storage points in the same station open the same stock.
  2. The direct radio binding is optional. Find Config.JobRadial.keybinds and add this entry beside handcuff if it is absent. An empty key leaves the action unbound; change only key if you want a server default:
dispatch_radio_operate = {
    enabled = true,
    command = "sky_jobs_dispatch_radio",
    key = "",
    description = "Jobs: Operate radio"
},
  1. Find the existing Config.PropPlacement = { ... } table. Immediately below its vehicleAccess = ... line, add vehicleCollectDistance = 30.0, if it is missing. Keep your existing vehicleAccess value and all other entries. This is the collection radius around the vehicle in metres; choose a value from 1 to 200 if you want a different radius. The default is 30.0.

These delivery-handling defaults apply to ordinary jobs. Mechanic keeps its own transport configuration. A job's existing onlineShopSettings now also accepts deliveryMode = "standard" for physical collection or deliveryMode = "player_inventory" for collection directly into the player's inventory. An omitted value uses physical collection. Keep the existing catalogue, collection points, delivery time and payment settings.

Existing ordinary-job online shops: an omitted delivery mode now uses physical collection. To keep collection directly into the employee's inventory, select Player inventory in the job's Online shop → Delivery mode setting after startup and save. Mechanic retains its existing mode unless you override it for the job.

Optional — configure the supply shop after startup: run /jobconfig, select the resource and job, then open Online shop. Keep existing access, catalogue and collection points. Choose Delivery mode → Physical delivery for boxes/pallets or Player inventory to put the collected order into the employee's inventory, then save. Ordinary jobs remain disabled until you enable their Online shop. The new delivery app uses the same job access. Company payment still requires the supply purchase permission.

For shared handling, open Jobs Base → Jobs & Storage → Supply delivery handling. This controls parcel opening time, pickup distance, parcel model, sprinting, storage distance, allowed forklifts, carried-item models/attachments and the delivery pallet. Save only deliberate changes. Mechanic retains its existing handling settings.

Optional — radio shortcut: open Jobs Base → Radial & Alerts → Job radial menu → Direct keybinds → Operate radio and set its key, then save. Players can set their own key in FiveM settings → Key bindings → FiveM → Jobs: Operate radio. The new default is unbound and does not replace saved player bindings.

Optional — set vehicle prop limits after startup: run /jobconfig, select the job's resource and the job, then open Vehicles. Find the existing vehicle by its spawn name. Under Prop limits, choose Add prop limit, enter a model from the job's existing Props list and set its limit. 0 disables that model for this vehicle; a model without a limit remains unlimited. Remove its limit row to make it unlimited again. Save, collect any equipment already placed from that vehicle, then park it and take it out again. New limits apply to the next vehicle spawn, not the one already outside.

Only if you maintain that job in Lua instead of /jobconfig: open the job resource's installed config/config.lua, for example sky_ambulancejob/config/config.lua. Inside Config.Jobs, find the matching job, then its vehicles list and the existing entry with the required model = .... Beside that vehicle's model line, add this complete table if propCounts is missing; if it already exists, adjust only the model keys you want to change and retain its other entries:

propCounts = {
    ["prop_roadcone02a"] = 4,
    ["prop_barrier_work05"] = 0,
},

Use model names from that job's existing prop catalogue. This example allows four cones and disables the listed barrier; omitted models stay unlimited. Existing custom per-vehicle props or trunkProps catalogues keep their explicit quantities and take precedence over propCounts. Do not remove custom catalogues during this update. Collect equipment, then park and take out the vehicle again to apply deliberate changes.

Optional — change the shared collection radius: run /jobconfig and open Jobs Base → World Interactions → Prop Placement → Collect-all radius (m). Keep the default 30 or choose 1–200, then save. This shared value measures distance from the vehicle. With Config.UseIngameConfigurator = false in Jobs Base, use the Config.PropPlacement.vehicleCollectDistance file entry described above instead.

Using Collect all: go on duty, stand beside the current job vehicle and open Radial → Vehicle interactions → Props. The selector shows remaining stock against its limit, or Unlimited; exhausted limited entries remain visible but unavailable. Collect all (count) returns that current vehicle's nearby placed equipment to its stock. Props taken from another vehicle spawn, props placed from inventory items and props outside the configured radius stay where they are. Removing one of the vehicle's props individually also returns its stock once. These vehicle-prop changes add no SQL migration or inventory item registration.

4. Update the database and check optional inventory hooks

Required database update: this version adds claim_reservations to the existing sky_mechanic_part_deliveries table so interrupted physical collection can be tracked. The historical table name is also used for ordinary jobs. Keep existing rows and order IDs.

  1. In sky_jobs_base/config/config.lua, find Config.AutoExecuteQuery.
  2. If it is true, do not run SQL manually. Start the updated server in the next step and wait for the database update to finish successfully.
  3. If it is false, open your database tool and select the actual game database before starting the server. On MariaDB, run the new sky_jobs_base/import.sql. On MySQL, open sky_mechanic_part_deliveries in the table editor and check whether claim_reservations exists. Only if it is absent, run:
ALTER TABLE `sky_mechanic_part_deliveries`
ADD COLUMN `claim_reservations` LONGTEXT NULL;

Do not add it twice, delete orders or run clear.sql. This MySQL step applies to an already complete 1.51.0 database; older installations must complete their earlier migrations first.

Inventory: no new item registration is required for this release. Existing restraint_tool registrations remain valid. The supplied restraint_tool.png is an additional image; keep your current configured item image unless you deliberately choose to use it.

Optional — Chezza Inventory 4.3.9: after Jobs Base is installed, open that inventory's fxmanifest.lua. In its existing client_scripts list, add '@sky_jobs_base/config/inventory/chezza_restraints.lua', before client/*.lua and after its shared configuration loads. If you customized Config.isHandcuffed, transfer your additional restraint checks into the downloaded hook before enabling it. This hook also disables the original Jaksam-only trunk bridge when its owner is stopped.

Optional — Hex Inventory 1.1.7: in that inventory's fxmanifest.lua, add '@sky_jobs_base/config/inventory/hex_restraints.lua', immediately after client/os_functions.lua in client_scripts. The hook keeps the original checks and adds Sky restraint denial. Use only the hook for your inventory; no other inventory files need replacing. Neither hook requires Sky Job Creator.

5. Start and verify the installed features

  1. Finish all installed resource updates. In server.cfg, start the framework, database connector and chosen providers first, then Base 1.49.0, Jobs Base 1.52.0 and the installed job resources. If used together, keep DOJ before Police and Ambulance before Crime.
  2. Start the server, wait for database migration to finish and resolve the first console error before players join. Confirm Jobs Base reports 1.52.0.
  3. Reconnect. Open /jobconfig and confirm your existing jobs and locations remain. Save only deliberate optional changes from the settings step.
  4. Open a job's tablet and garage. If its Online shop is enabled, place a small test order, collect it using the selected delivery mode and confirm it reaches the intended inventory or authorized station storage. With Mechanic installed, check an existing order and its delivery app too.
  5. Check your dispatch unit assignment and radio shortcut if used. If you enabled an inventory restraint hook, confirm a restrained player cannot open that inventory.
  6. If vehicle props are enabled for the job, go on duty and take out a job vehicle. Stand beside it, open Radial → Vehicle interactions → Props, place a limited prop and check that its available count drops. Use Collect all nearby and confirm the prop disappears and the count returns. Check that another vehicle's props and any props outside the collection radius remain placed.

Keep the backup until these checks pass. Configurator saves do not install SQL, items or inventory manifest entries.

Version 1.51.0

Highlights

  • Added an optional online supply shop for ordinary jobs with catalogues, orders, collection points and personal or company payment.
  • Added configurable public and job Farming points for gathering, processing and selling, including optional repetition, routes and portable setups.
  • Added document templates, revisioned job records and shared printing for compatible Job Creator jobs.
  • Added configurable tools for freeing another player from handcuffs or zipties.

Notable Changes

  • Improved the Job Configurator with a resource overview, help links, clearer feature groups and direct creator actions that preserve pending edits.
  • Improved marker and blip selection with visible selected assets, clearer display modes and preserved opacity values.
  • Added bell sound and volume controls with temporary prop previews that preserve saved positions.
  • Fixed an issue where model-specific attachment editors were unavailable or failed to restore configurator focus.
  • Changed vehicle prop selection to the radial vehicle interactions menu without requiring the trunk to open.
  • Fixed an issue where a selected prop or vehicle action switched to an adjacent object after the original selection became unavailable.
  • Added transport of carried unconscious players into vehicles and removal of unrestrained unconscious occupants.
  • Improved personal push-to-talk support while the built-in tablet captures input.
  • Improved document readers with mouse-wheel navigation, resolved participant names and retained archived snapshots.
  • Fixed an issue where the tablet camera shutter sound was missing from the delivered files.
  • Fixed an issue where opening management changed the native grade catalogue or accepted invalid grades.
  • Removed the salary input limit of 20,000 while retaining server-side access checks.
  • Fixed an issue where an existing off-duty job was recreated instead of linked with its native definitions intact.
  • Improved cooperative dispatch notices for available field units under the dispatch centre's actual policy.
  • Added minimum-grade defaults for Crime role permissions while preserving explicit saved role decisions.
  • Added teleport buttons for placed shop-robbery clerk, till and safe positions in the Job Configurator.

Other Changes

  • Improved compatibility with portable Creator job setups and the renamed Creator runtime while preserving stored job identities.
  • Fixed an issue where optional Vehicle Studio image failures interrupted garage operations.
  • Fixed an issue where business announcements displayed the wrong job label or a failed deposit lacked useful feedback.
  • Reduced repeated map messages while the tablet is closed and unnecessary rebuilding of unchanged dispatch snapshots.
  • Improved narrow cloakroom labels, shared form layouts, colour controls and bundled translations.

Changed Files

  • sky_jobs_base/config/config.lua
  • sky_jobs_base/config/init.lua
  • sky_jobs_base/config/inventory/README.md
  • sky_jobs_base/config/inventory/items_ox.lua
  • sky_jobs_base/config/locales/*
  • sky_jobs_base/config/printers.lua
  • sky_jobs_base/fxmanifest.lua
  • sky_jobs_base/import.sql
  • sky_jobs_base/source/* — delete and reinsert

Renamed Files

  • sky_jobs_base/config/locales/jobconfigurator/sky_jobscreator/ar.lua → sky_jobs_base/config/locales/jobconfigurator/sky_jobcreator/ar.lua
  • sky_jobs_base/config/locales/jobconfigurator/sky_jobscreator/cn.lua → sky_jobs_base/config/locales/jobconfigurator/sky_jobcreator/cn.lua
  • sky_jobs_base/config/locales/jobconfigurator/sky_jobscreator/cz.lua → sky_jobs_base/config/locales/jobconfigurator/sky_jobcreator/cz.lua
  • sky_jobs_base/config/locales/jobconfigurator/sky_jobscreator/de.lua → sky_jobs_base/config/locales/jobconfigurator/sky_jobcreator/de.lua
  • sky_jobs_base/config/locales/jobconfigurator/sky_jobscreator/en.lua → sky_jobs_base/config/locales/jobconfigurator/sky_jobcreator/en.lua
  • sky_jobs_base/config/locales/jobconfigurator/sky_jobscreator/es.lua → sky_jobs_base/config/locales/jobconfigurator/sky_jobcreator/es.lua
  • sky_jobs_base/config/locales/jobconfigurator/sky_jobscreator/fi.lua → sky_jobs_base/config/locales/jobconfigurator/sky_jobcreator/fi.lua
  • sky_jobs_base/config/locales/jobconfigurator/sky_jobscreator/fr.lua → sky_jobs_base/config/locales/jobconfigurator/sky_jobcreator/fr.lua
  • sky_jobs_base/config/locales/jobconfigurator/sky_jobscreator/hu.lua → sky_jobs_base/config/locales/jobconfigurator/sky_jobcreator/hu.lua
  • sky_jobs_base/config/locales/jobconfigurator/sky_jobscreator/it.lua → sky_jobs_base/config/locales/jobconfigurator/sky_jobcreator/it.lua
  • sky_jobs_base/config/locales/jobconfigurator/sky_jobscreator/nl.lua → sky_jobs_base/config/locales/jobconfigurator/sky_jobcreator/nl.lua
  • sky_jobs_base/config/locales/jobconfigurator/sky_jobscreator/pl.lua → sky_jobs_base/config/locales/jobconfigurator/sky_jobcreator/pl.lua
  • sky_jobs_base/config/locales/jobconfigurator/sky_jobscreator/pt.lua → sky_jobs_base/config/locales/jobconfigurator/sky_jobcreator/pt.lua
  • sky_jobs_base/config/locales/jobconfigurator/sky_jobscreator/rs.lua → sky_jobs_base/config/locales/jobconfigurator/sky_jobcreator/rs.lua
  • sky_jobs_base/config/locales/jobconfigurator/sky_jobscreator/ru.lua → sky_jobs_base/config/locales/jobconfigurator/sky_jobcreator/ru.lua
  • sky_jobs_base/config/locales/jobconfigurator/sky_jobscreator/se.lua → sky_jobs_base/config/locales/jobconfigurator/sky_jobcreator/se.lua
  • sky_jobs_base/config/locales/jobconfigurator/sky_jobscreator/sl.lua → sky_jobs_base/config/locales/jobconfigurator/sky_jobcreator/sl.lua
Update InstructionsWhat to copy, what to keep and what to check1.50.01.51.0

Simplified update

Update sky_jobs_base safely

Read the complete update instructions in one continuous guide.

1. Back up and stop the server

Update sky_jobs_base from 1.50.0 to 1.51.0. For an older installation, follow the intervening update guides in version order first.

  1. Download 1.51.0 and extract the ZIP.
  2. Copy your installed sky_jobs_base folder to a backup outside the server's resources folder. Export a backup of your game database too.
  3. Stop the whole server in txAdmin or your hosting panel.
  4. Complete the Base update to 1.48.0 during the same maintenance. If you use Sky Mechanic, update it to 1.37.0 too.

2. Copy the new files

Open the installed sky_jobs_base folder and the new download side by side. Copy from the download into the installed folder:

  1. Delete the installed source/ folder, then copy the complete new source/ folder here.
  2. Delete the installed config/locales/ folder, then copy the complete new config/locales/ folder here.
  3. Replace fxmanifest.lua and config/init.lua with the new files at the same paths.
  4. Replace import.sql with the new copy.
  5. Replace config/inventory/README.md and config/inventory/items_ox.lua with the new copies. These are reference files; copying them does not change your inventory's active item list.

Keep your other configuration files, including config/config.lua and config/printers.lua.

Only if you edited translations: copy your changed wording from the backup into the matching new language entries. Creator translations now belong in config/locales/jobconfigurator/sky_jobcreator/; the old sky_jobscreator/ locale folder must stay removed.

3. Check your settings

Open the installed sky_jobs_base/config/config.lua and find Config.UseIngameConfigurator.

  • true (normal setup): keep it as it is. Saved settings are retained and new settings are supplied automatically. No configuration import is needed.
  • false: find Config.Farming. If it is missing, add the following at the very end of the file, outside the other tables. If it already exists, keep your configured stations. Only if you also want the new restraint tool, copy the breakout = { ... } entry from the downloaded Config.PoliceCuffs table into that same table in your installed file; then register its item in step 4.
Config.Farming = {
    stations = {}
}

Your existing phone item setting still works. Shops, Farming points and document templates do not need to be set up to finish this update.

Only if you manually added trunkEnabled = false to a custom vehicle definition: replace that field with trunkEnabled = false, trunkPropsEnabled = false, in the same vehicle entry if vehicle props must also stay disabled. The trunk setting now controls trunk opening separately.

4. Update database and inventory

Database: in the same config/config.lua, find Config.AutoExecuteQuery and follow the matching line:

  • true: no manual SQL step. Jobs Base updates the database when the server starts; wait for it to finish.
  • false: before starting the server, open your database tool, select the game database and run the new sky_jobs_base/import.sql. Wait until it finishes without errors.

Keep all existing tables and orders. Do not run clear.sql.

Only if you want the new restraint tool: for ox_inventory, open the downloaded sky_jobs_base/config/inventory/items_ox.lua, copy only the complete ["restraint_tool"] entry, and insert it beside the other items inside the returned table in ox_inventory/data/items.lua. Copy sky_jobs_base/config/inventory/wire_cutter.png to ox_inventory/web/images/wire_cutter.png. For another inventory, use its item registration instructions in the supplied config/inventory/README.md.

If you do not want this tool, turn it off after startup as described in the next step. Existing printing items do not need to be registered again.

5. Start the server and check

  1. Start the server. In server.cfg, keep ensure sky_base before ensure sky_jobs_base, and Jobs Base before your job resources.
  2. Wait for the database update to finish. Check the server console for errors before letting players join.
  3. Join the server. If you manage jobs through /jobconfig, open it and check that your existing jobs and locations are still there.
  4. If Config.UseIngameConfigurator = true, open Jobs Base → Interactions → Handcuffs → Free another player. Turn Enabled off if you skipped the new tool. If you installed it, keep it enabled and test freeing another restrained player. Save any change. With the configurator disabled, leaving the new PoliceCuffs.breakout block absent keeps this feature off.
  5. Check a job garage and the tablet. If you use Mechanic, open an existing supply order and confirm it is still present.

Keep the backup until these checks pass. Optional new features can be configured afterwards.

Version 1.50.0

Highlights

  • Added configurable job doorbells with desk and wall models, seven sound presets, custom local sounds and staff requests that can set a waypoint to the caller.
  • Added a Business & announcements tablet app for authorized staff to manage opening status, publish notices, promotions and events, and review their job's announcement history.
  • Added customizable identity, license and service cards with character portraits, department styles and persistent service numbers that managers can assign or change.
  • Improved the radial menu with nested action rings, grouped player interactions and an optional center logo.
  • Improved the Dispatch workspace with responsive themed panels, an incident creation dialog and configurable postal-code lookup from bundled or custom local datasets.

Notable Changes

  • Added per-job salary intervals and funding choices while keeping Sky salaries separate from the framework's own payroll.
  • Added optional Dispatch settings to select or take newly created incidents, suggest vehicles automatically, prefer distance over crew size and account for units already assigned to a response plan.
  • Added independent public and administrator Discord outputs for business announcements, disabled by default and configured through server-only webhook settings.
  • Added personal placement settings for bell requests and business notices through tablet settings and /notifications.
  • Added shared tablet switches for all seven Crime apps while preserving their existing access rules.
  • Added support for compatible external radial menus to use shared job actions while retaining target selection and permissions.
  • Added optional JG Vehicle Studio images to garage previews while preserving existing image folders as fallbacks.
  • Added support for trusted citizen-office integrations to manage temporary and permanent vehicle registration while retaining inspection records, online-time permit limits and vehicle history.
  • Changed Forms so its inbox and read-only archive are available in one tablet app.
  • Improved Forms and drug-test lists to refresh after relevant changes and reopening while retaining authorized selections, unsaved input and scroll position.
  • Improved shared tablet headers, compact map, chat, gallery, CCTV and training layouts, theme contrast and keyboard-accessible controls while keeping the Camera's viewfinder and Back action.
  • Added job-specific default tablet wallpapers while preserving personal wallpaper choices.
  • Fixed an issue where shared invoice forms ignored the selected external billing provider, and made rejected or uncertain submissions visible.
  • Improved invoice recipient selection with nearby player names and distances instead of manual player IDs.
  • Fixed an issue where garage plates were normalized inconsistently, and added eight-character validation and clearer failed-spawn messages.
  • Fixed an issue where Dispatch vehicle selections were cleared by routine updates, and corrected displayed distances from meters to kilometers.
  • Fixed an issue where shift changes or saved Dispatch settings could repeat existing incident notifications, and prevented record closure when the required shift was busy.
  • Fixed an issue where radio status rejections were discarded, and moved radio show, hide and operate actions into the radial menu.

Other Changes

  • Fixed an issue where linked-job cuff hotkeys could be rejected despite an authorized cuff action, and corrected the placement of front handcuffs.
  • Improved leg restraint actions with a short animation that follows the configured duration.
  • Improved document checks and voluntary document showing while retaining job permissions, restrained-target requirements and character ownership.
  • Improved placed interaction objects with full three-axis rotation and placement editing that preserves the draft when cancelled.
  • Fixed an issue where character changes or unloads could leave stale names, job or duty information in shared views.
  • Fixed an issue where built-in tablet apps could disappear when the resource that started Jobs Base stopped, and corrected job cleanup during resource restarts.
  • Improved large Dispatch startup history loading without discarding existing incident logs.
  • Fixed an issue where empty named configuration maps, new job collections or shop location rows could be represented incorrectly in the editor.
  • Improved shop point placement so open rows, unsaved changes and scroll positions survive returning from the placement editor, with clear status for unplaced coordinates.
  • Fixed an issue where the Job Configurator omitted registered resources, failed to load restaurant translations or could not return from a directly opened settings page.
  • Improved configuration and Dispatch errors with concrete translated guidance and visible unknown rejection codes.
  • Updated shared tablet and job configuration translations to complete missing text and clarified vehicle display names, spawn names and payroll currency keys.
  • Updated the temporary tablet change notice so it stays dismissed, and removed the old NEW markers from established apps.
  • Improved shared date selection with optional scheduled time ranges and consistent popup styling.

Changed Files

  • sky_jobs_base/config/config.lua
  • sky_jobs_base/config/documents/README.md
  • sky_jobs_base/config/documents/documents.css
  • sky_jobs_base/config/documents/documents.js
  • sky_jobs_base/config/documents/identity.css
  • sky_jobs_base/config/documents/identity.html
  • sky_jobs_base/config/documents/licenses.html
  • sky_jobs_base/config/documents/logo.svg
  • sky_jobs_base/config/documents/preview.html
  • sky_jobs_base/config/documents/preview.js
  • sky_jobs_base/config/documents/service-security.svg
  • sky_jobs_base/config/documents/service.html
  • sky_jobs_base/config/init.lua
  • sky_jobs_base/config/locales/*
  • sky_jobs_base/config/player_actions.lua
  • sky_jobs_base/config/postal/LICENSE.NearestPostal.txt
  • sky_jobs_base/config/postal/LICENSE.Oulsen.txt
  • sky_jobs_base/config/postal/README.md
  • sky_jobs_base/config/postal/new-postals.json
  • sky_jobs_base/config/postal/ocrp-postals.json
  • sky_jobs_base/config/postal/old-postals.json
  • sky_jobs_base/config/postal/oulsen_satmap_postals.json
  • sky_jobs_base/config/sounds/bells/A1-warm-ding-dong.ogg
  • sky_jobs_base/config/sounds/bells/A2-dark-ding-dong.ogg
  • sky_jobs_base/config/sounds/bells/A3-short-ddm.ogg
  • sky_jobs_base/config/sounds/bells/A4-warm-three-notes.ogg
  • sky_jobs_base/config/sounds/bells/R1-a1-ding-ding-dong.ogg
  • sky_jobs_base/config/sounds/bells/R2-a1-slow-three-notes.ogg
  • sky_jobs_base/config/sounds/bells/R3-a1-small-bell-rhythm.ogg
  • sky_jobs_base/config/sounds/bells/custom/README.md
  • sky_jobs_base/config/sounds/bells/provenance.json
  • sky_jobs_base/config/webhooks.lua
  • sky_jobs_base/fxmanifest.lua
  • sky_jobs_base/import.sql
  • sky_jobs_base/source/* — delete and reinsert
  • sky_jobs_base/stream/sky_job_bells.ytyp
  • sky_jobs_base/stream/sky_job_deskbell.ydr
  • sky_jobs_base/stream/sky_job_doorbell.ydr
  • sky_jobs_base/vehicle_registry.sql
Update InstructionsWhat to copy, what to keep and what to check1.49.01.50.0

Simplified update

Update sky_jobs_base safely

Read the complete update instructions in one continuous guide.

  1. Prepare

These instructions cover sky_jobs_base 1.49.0 → 1.50.0. Complete applicable earlier migrations when upgrading from an older version. Back up the database, resources, custom settings/translations, document artwork, bell audio and saved jobs, grades, permissions, locations and shared /jobconfig settings. Test on staging and stop the server for replacement. Start the framework, database connector and selected inventory, keys, license, phone, banking and UI providers first, then Base 1.47.0, then Jobs Base 1.50.0 and wait for successful initialization. Start DOJ 0.5.0 before Police 1.39.0 for shared catalogue and court features, and Ambulance 2.46.0 before Crime 0.10.0 when using their medical integration. Mechanic 1.36.0 and Fire 1.18.0 follow both libraries. Treasure Hunt 1.1.0 and Pets 1.1.0 follow Base and their own listed dependencies. Install and start only resources you use.

  1. Replace files

Use the complete 1.50.0 customer package. Delete the entire sky_jobs_base/source/ folder and insert the new one, then replace sky_jobs_base/fxmanifest.lua from the same download. Refresh the complete config/locales/ tree, including every jobconfigurator/ subfolder for installed consumers, while merging your translations and keeping the Base language choice.

Merge config/config.lua and server-only config/webhooks.lua, update config/init.lua, add config/player_actions.lua, and install all new config/documents/, config/postal/, config/sounds/bells/ and three stream/ files listed in Changed Files. Update import.sql and vehicle_registry.sql. Keep custom document layouts, local sounds, image URLs, provider hooks and webhook/media secrets while retaining the supplied fixes and new fields.

Document HTML, CSS, JavaScript and SVG files are editable customer files; future edits do not need a frontend build, but restart Jobs Base to reload its resource/browser cache. Tablet wallpapers and generated interfaces arrive inside the complete source replacement. Keep existing personal wallpaper choices.

Use source and manifest from the same download even with diagnostics disabled. If an older profiler package changed files outside source/, restore them from this package once and reapply intentional settings; future profiler-only updates change source Lua and the manifest.

  1. Merge settings

Choose the effective settings owner. While the server is stopped, merge plaintext files and server-only secrets. Carry out the panel actions and role/unit grants in this section only after the SQL setup and the first full restart of the updated server have completed successfully. With Config.UseIngameConfigurator = true, open /jobconfig → Jobs Base and edit the saved shared sections. Their stored roots are Salary, Dispatch, Tablet, JobPlayerInteractions, LegRestraints, Nui, JobRadial, IncidentNotification, PlayerIdentityCard, Bells and Business; nested field names match the paths below. File replacement does not overwrite saved jobs or overrides. With Config.UseIngameConfigurator = false, merge these defaults in sky_jobs_base/config/config.lua instead. Use /jobconfigimport sky_jobs_base only for an intentional import of your reviewed file settings after backup; it is not a required reset and does not install SQL, sounds, models or provider secrets. Bootstrap, permissions/integration code and server-only webhook/media secrets remain file-based.

Exact config changes: “Absent” means the path was not in the previous shipped defaults. Preserve deliberate overrides rather than resetting an entire section.

Path in config/config.luaOld shipped value → new shipped value
Config.Nui.vehicleStudioImageSetAbsent → "default".
Config.Tablet.apps.forms_archivetrue → removed; delete this old entry.
Config.Tablet.apps.businessAbsent → true.
Config.Tablet.apps.training.isNewtrue → false; enabled = true remains.
Config.Tablet.apps.dispatch.isNewtrue → false; enabled = true remains.
Config.Tablet.apps.personal_notes.isNewtrue → false; enabled = true remains.
Config.Tablet.apps.crime_heist_planningAbsent → true.
Config.Tablet.apps.crime_pvp_eventsAbsent → true.
Config.Tablet.apps.crime_drug_marketAbsent → true.
Config.Tablet.apps.crime_drug_heatAbsent → true.
Config.Tablet.apps.crime_drug_contactsAbsent → true.
Config.Tablet.apps.crime_drug_businessAbsent → true.
Config.Tablet.apps.crime_darknet_marketAbsent → true.
Config.Dispatch.radioKeybind"F10" → removed; delete this old path.
Config.Dispatch.enhanced.map.nearestAvailableOnlyAbsent → true.
Config.Dispatch.enhanced.operations.selectCreatedIncidentAbsent → false.
Config.Dispatch.enhanced.operations.takeCreatedIncidentAbsent → false.
Config.Dispatch.enhanced.operations.suggestUnitsOnSelectAbsent → false.
Config.Dispatch.enhanced.operations.recommendationStrategyAbsent → "crew".
Config.Dispatch.enhanced.operations.responsePlanModeAbsent → "full".
Config.Dispatch.postalSearchAbsent → complete disabled block below.
Config.Salary.useGradeIntervalsAbsent → true.
Config.Salary.jobSocietyPaymentsAbsent → {}.
Config.JobPlayerInteractions.groups.police.identityAbsent → true.
Config.JobPlayerInteractions.groups.police.licensesAbsent → true.
Config.JobPlayerInteractions.groups.crime.identityAbsent → true.
Config.JobPlayerInteractions.groups.crime.licensesAbsent → true.
Config.LegRestraints.applyScenario"CODE_HUMAN_MEDIC_KNEEL" → removed; delete this old path.
Config.LegRestraints.animDictAbsent → "anim@amb@clubhouse@tutorial@bkr_tut_ig3@".
Config.LegRestraints.animNameAbsent → "machinic_loop_mechandplayer".
Config.BusinessAbsent → complete block below.
Config.BellsAbsent → complete block below.
Config.Interactions.<type>.object.pitchAbsent → 0.0 for all sixteen types below.
Config.Interactions.<type>.object.rollAbsent → 0.0 for all sixteen types below.
Config.PlayerIdentityCardAbsent → complete block below.
Config.JobRadial.logoAbsent → "".
Config.JobRadial.targetContext.playerToleranceRadius0.75 → 1.1.
Config.JobRadial.targetContext.playerToleranceAngleDegrees12.0 → 24.0.
Config.IncidentNotification.keyMappings.openMap"M" → "" (unbound for new personal mappings).

Apps, images and radial settings: Merge these assignments into the existing sections for file mode; they are the new/changed values, not replacements for your complete app list:

Config.Tablet.apps.business = true
Config.Tablet.apps.training = { enabled = true, isNew = false }
Config.Tablet.apps.dispatch = { enabled = true, isNew = false }
Config.Tablet.apps.personal_notes = { enabled = true, isNew = false }
Config.Tablet.apps.crime_heist_planning = true
Config.Tablet.apps.crime_pvp_events = true
Config.Tablet.apps.crime_drug_market = true
Config.Tablet.apps.crime_drug_heat = true
Config.Tablet.apps.crime_drug_contacts = true
Config.Tablet.apps.crime_drug_business = true
Config.Tablet.apps.crime_darknet_market = true
Config.Nui.vehicleStudioImageSet = "default"
Config.JobRadial.logo = ""
Config.JobRadial.targetContext.playerToleranceRadius = 1.1
Config.JobRadial.targetContext.playerToleranceAngleDegrees = 24.0
Config.IncidentNotification.keyMappings.openMap = ""

Keep intentional app enablement choices, including enabled = false for an app you hide. The full training/dispatch/personal-notes tables above also work when your older file used a boolean app switch. Delete Config.Tablet.apps.forms_archive; Forms now contains both inbox and read-only archive. Review roles/units that previously restricted only forms_archive and apply their intended access through forms. Existing archived records are retained, and the old archive URL redirects. Crime switches require the matching installed Crime apps and their existing grants. JG Vehicle Studio is optional: when it is started, its selected stored image set is used before existing local/CDN fallbacks; no new JG installation or media secret is required to retain current images. JobRadial.logo = "" hides the logo; an HTTPS image or path relative to the shipped interface selects one, and "logo.svg" uses the supplied artwork. Target maximum distance remains 3.0. Existing personal FiveM key bindings are retained. Comment-only explanations of JobRadial.enabled and JobRadial.targetContext.enabled do not change their true defaults; supported external radial integrations retain exports, direct hotkeys and normal permissions when Sky's native UI is disabled.

Dispatch: Remove Config.Dispatch.radioKeybind; the old dispatchradio and dispatchholster commands are retired. Use the radial Radio actions to show, hide or operate the radio. Add the following values inside the existing Dispatch settings, retaining unrelated map/operation options:

Config.Dispatch.enhanced.map.nearestAvailableOnly = true
Config.Dispatch.enhanced.operations.selectCreatedIncident = false
Config.Dispatch.enhanced.operations.takeCreatedIncident = false
Config.Dispatch.enhanced.operations.suggestUnitsOnSelect = false
Config.Dispatch.enhanced.operations.recommendationStrategy = "crew"
Config.Dispatch.enhanced.operations.responsePlanMode = "full"
Config.Dispatch.postalSearch = {
    enabled = false,
    resource = "sky_jobs_base",
    file = "config/postal/oulsen_satmap_postals.json",
    entries = {}
}

Optional nearestAvailableOnly = false includes occupied units in the nearest-unit search. The three new automation switches default off; taking a new incident follows normal ownership rules and does not replace another active incident. Optional recommendationStrategy = "distance" favors nearby units. Optional responsePlanMode = "remaining" counts staffed assigned/offered units before suggesting reinforcements. Keep existing service numbers, coverage and phone provider settings.

Postal lookup defaults off. To use it, select one dataset matching your server's map in Jobs Base → Dispatch → Postal lookup; all four shipped JSON files and both license notices must be copied. Bundled maps are alternatives and are not merged. No map textures or Nearest Postal script are required, and no data is downloaded at runtime. Add custom JSON files in config/postal/, choose the resource containing that folder, save and reopen the editor to discover them. The file format is:

[
  { "code": "1000", "x": 1644.1221923828, "y": 6456.0561523438 },
  { "code": "1001", "x": 1538.3503417969, "y": 6344.6381835938 }
]

Keep codes as strings for leading zeros; optional z and label are supported. Saved manual entries override matching codes. Duplicate codes use the last row with a warning. Files are limited to 8 MiB / 20,000 rows. Restart Jobs Base after editing the selected file.

Payroll: Add the two new shared defaults:

Config.Salary.useGradeIntervals = true
Config.Salary.jobSocietyPayments = {}

Keep your existing enabled state, account, amount and interval choices. useGradeIntervals = false uses the global default interval; an explicit per-job interval still takes precedence. jobSocietyPayments maps the exact job name to true for a society-funded payout or false for server-created money. Under a non-gang job's Payroll extension, the new stored default is:

payrollSettings = {
    intervalMinutes = 0,
    fundingMode = "inherit",
}

0 inherits the global/rank interval. Optional funding modes "society" and "server" override inherited funding. This is saved job data, not another global config table to paste over existing jobs. Review each rank's actual Sky salary: a missing Sky salary now means 0 rather than silently falling back to the framework's salary. Import native amounts only through an explicit job-definition takeover after reviewing them. Payroll currency expects a configured currency key such as bank, not a currency symbol; display formatting follows Base currency settings. Native framework pay remains separate. Native funding overrides require an already installed compatible framework paycheck hook; updating Jobs Base or adding the map alone does not install that hook or change native paycheck timing.

Player actions and leg restraints: Add the new shared action defaults:

Config.JobPlayerInteractions.groups.police.identity = true
Config.JobPlayerInteractions.groups.police.licenses = true
Config.JobPlayerInteractions.groups.crime.identity = true
Config.JobPlayerInteractions.groups.crime.licenses = true

Keep existing job/rank/duty restrictions and per-job enabled/minimum-grade settings. Nonvoluntary identity/license inspection requires an authorized actor and a restrained target within the allowed distance and routing bucket. Voluntary showing and viewing your own documents remain character-bound. Saved playerInteractions.identityRequireAcceptance and .licensesRequireAcceptance are retired; delete those paths from custom job data/imports. Old license:<type> action flags no longer choose which held licenses appear: use PlayerIdentityCard.licenseTypes below. Carry's consent setting remains. Install config/player_actions.lua to retain the supplied native, jsfour, UM and Qbox document integration hooks; merge intentional custom hooks and preserve each provider's authorization/items.

Delete Config.LegRestraints.applyScenario and merge the complete replacement block, keeping your deliberate item, distance and duration values:

Config.LegRestraints = {
    enabled = true,
    requireItem = false,
    item = "legcuffs",
    useItem = "radial",
    maxDistance = 2.0,
    requireCuffed = true,
    animDict = "anim@amb@clubhouse@tutorial@bkr_tut_ig3@",
    animName = "machinic_loop_mechandplayer",
    applyDurationMs = 1600
}

Bells and Business: Add both complete new shared blocks:

Config.Business = {
    enabled = true,
    durationSeconds = 8,
    cooldownSeconds = 300,
    position = "top-center",
    maxPending = 3,
    announceExclusionZones = true,
    discord = {
        publicEnabled = false,
        adminEnabled = false,
    },
}
Config.Bells = {
    enabled = true,
    keyMappings = { accept = "Y", dismiss = "RETURN" },
    requestCooldown = 30,
    customSounds = {},
}

No bell appears until one is placed. In a non-gang job's Bells extension, the new default bells = {} permits up to 32 configured placements. Choose the desk/wall model, preset/custom sound and recipients (nearby players, employees or both). Staff requests use Y to accept a waypoint and Enter to dismiss by default; personal bindings, request cooldowns and death/cuff/busy checks still apply. Copy custom OGG/WAV/MP3 files under config/sounds/bells/custom/, add a unique ID, label, local path and actual duration between 0.1 and 15 seconds in Jobs Base → Bells → Custom sounds, then restart Jobs Base. Example optional catalogue:

Config.Bells.customSounds = {
    { id = "reception", label = "Reception", file = "config/sounds/bells/custom/reception.ogg", duration = 2.0 },
}

Config export/import transfers the catalogue, so copy the audio files separately. Personal bell/business notification placement is available in tablet settings and /notifications.

In a non-gang job's Business extension, add/review this new stored default:

businessSettings = {
    statusEnabled = false,
    announcementsEnabled = false,
    requireOnDuty = true,
    imageUrl = "",
    openColor = 2,
    closedColor = 1,
    openSprite = 0,
    closedSprite = 0,
    closedAlpha = 180,
}

Both staff actions default disabled. Enable only the desired job actions and grant existing roles/units Business status (permission 34) or Business announcements (permission 35); keep existing grants. Opening state persists without an additional Business table. Optional announcements respect exclusion zones and retain their history.

In server-only sky_jobs_base/config/webhooks.lua, the previously absent Webhooks.businessAnnouncements now defaults to:

Webhooks.businessAnnouncements = {
    public = "",
    admin = "",
}

Add it without replacing existing media/provider secrets. Discord outputs default off in Config.Business.discord; enable the desired public/admin output in the effective Jobs Base settings and privately set its matching URL in this file, then restart. Use different webhook IDs for the public and private admin channels. Public messages omit staff admin data and suppress mentions. Failed Discord delivery does not undo an in-game announcement; empty URLs do not establish working delivery.

Document cards: Add the complete new shared card defaults:

Config.PlayerIdentityCard = {
    enabled = true,
    serviceEnabled = true,
    position = "right",
    x = 75,
    y = 50,
    scale = 85,
    issuer = "",
    logo = "",
    licenseTypes = { "dmv", "drive", "drive_bike", "drive_truck", "driver", "weapon", "business" },
    serviceCards = {
        { job = "police", template = "official", background = "matte", color = "#3177b7", logo = "", title = "", prefix = "PD", format = "{prefix}-{number}", digits = 3 },
        { job = "ambulance", template = "medical", background = "matte", color = "#bf465b", logo = "", title = "", prefix = "EMS", format = "{prefix}-{number}", digits = 3 },
        { job = "mechanic", template = "compact", background = "matte", color = "#a36a24", logo = "", title = "", prefix = "MECH", format = "{prefix}-{number}", digits = 3 },
        { job = "fire", template = "official", background = "matte", color = "#b84732", logo = "", title = "", prefix = "FD", format = "{prefix}-{number}", digits = 3 },
        { job = "doj", template = "official", background = "matte", color = "#775487", logo = "", title = "", prefix = "DOJ", format = "{prefix}-{number}", digits = 3 },
        { job = "*", template = "official", background = "matte", color = "#3e6770", logo = "", title = "", prefix = "", format = "{prefix}-{number}", digits = 3 }
    }
}

Exact job names take priority over "*"; review the shipped "fire" name against your actual job. Set your issuer, artwork, card position and department format in the effective shared settings. The listed license types show only held licenses; optional licenseTypes = { "*" } includes all held types. Managers assign/change persistent service numbers through employee management using the existing member-management permission; no new service-number permission is required. Keep document renderer/artwork files together, and preserve custom edits.

Interaction object rotation: For each existing Config.Interactions.<type>.object, add pitch = 0.0 and roll = 0.0. The sixteen exact types are job_garage, garage_vehicle_spawn, garage_vehicle_park, garage_helicopter_menu, garage_helicopter_spawn, garage_helicopter_park, garage_boat_menu, garage_boat_spawn, garage_boat_park, boss_menu, duty_terminal, wardrobe, storage, locker, wholesale_shop and public_forms. The full default object subtable is:

object = {
    enabled = false,
    model = "",
    pitch = 0.0,
    roll = 0.0,
    heading = 0.0,
    offset = vector3(0.0, 0.0, 0.0)
}

Keep each location's enabled/model/heading/offset, marker, blip and NPC choices. Old heading-only objects remain upright. Install Base 1.47.0 together with Jobs Base 1.50.0 for full placed-object rotation. config/init.lua also reloads the existing restaurant locale packs; there is no new language setting.

Optional profiling remains disabled by default. To enable it for a support investigation, put setr sky_profiler 1 in server.cfg before the Sky ensure lines and perform a full server restart. Start a recording manually with profiler record 1000, wait until profiler status reports completion, then run profiler saveJSON sky-release-20261014.json; choose a new filename for every capture. Disable it with setr sky_profiler 0 followed by another full server restart. This is not a /jobconfig value, and neither recording nor upload starts automatically.

  1. Database, items and assets

SQL: Back up first. The existing automatic Jobs Base migration creates four additional tables: sky_jobs_service_card_settings, sky_jobs_service_numbers, sky_jobs_vehicle_temporary_registrations and sky_jobs_vehicle_registration_payments. Keep your current migration policy and confirm successful migration/readiness before using the features. If automatic migration is intentionally unavailable, open your database manager, select the database used by this FiveM server, open its SQL/query editor, and execute these four additive statements from the matching new import.sql before starting the updated resource:

CREATE TABLE IF NOT EXISTS `sky_jobs_service_card_settings` (
    `job` VARCHAR(64) NOT NULL,
    `settings_json` TEXT NULL,
    `revision` INT UNSIGNED NOT NULL DEFAULT 0,
    `next_number` BIGINT UNSIGNED NOT NULL DEFAULT 0,
    PRIMARY KEY (`job`)
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `sky_jobs_service_numbers` (
    `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
    `job` VARCHAR(64) NOT NULL,
    `identifier` VARCHAR(128) NOT NULL,
    `service_number` BIGINT UNSIGNED NOT NULL,
    PRIMARY KEY (`id`),
    UNIQUE KEY `uq_service_character` (`job`, `identifier`),
    UNIQUE KEY `uq_service_number` (`job`, `service_number`)
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `sky_jobs_vehicle_temporary_registrations` (
    `vehicle_id` CHAR(36) NOT NULL,
    `holder_identifier` VARCHAR(128) NOT NULL,
    `remaining_seconds` INT UNSIGNED NOT NULL,
    `playtime_seconds` BIGINT UNSIGNED NOT NULL,
    `document_id` CHAR(36) NOT NULL,
    `document_version` INT UNSIGNED NOT NULL DEFAULT 1,
    `issued_at` BIGINT UNSIGNED NOT NULL,
    PRIMARY KEY (`vehicle_id`),
    UNIQUE KEY `uniq_temporary_document` (`document_id`)
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `sky_jobs_vehicle_registration_payments` (
    `operation_id` CHAR(36) NOT NULL,
    `holder_identifier` VARCHAR(128) NOT NULL,
    `amount` INT UNSIGNED NOT NULL,
    `state` VARCHAR(24) NOT NULL,
    `updated_at` BIGINT UNSIGNED NOT NULL,
    PRIMARY KEY (`operation_id`)
) ENGINE=InnoDB;

The matching vehicle_registry.sql contains the two registration tables but does not install the service-card tables. Do not drop/reset existing jobs, registry records, forms, grants or documents. No charset/collation override or data-clearing migration is required; the new tables inherit your active database settings. The existing oxmysql/InnoDB transaction path is required for service-number allocation and registration payment claims. /jobconfig does not create the tables.

Items and document images: Jobs Base introduces no mandatory inventory item or inventory image. Existing tablet, cuffs, leg-restraint and printing items keep their existing definitions. Optional native/third-party document providers need their own existing item/template setup. Install the complete editable document files and SVG artwork listed in Changed Files, retaining custom layouts and configured logo URLs.

Bell assets and postal data: Install all seven bundled OGG presets, their provenance.json, custom/README.md, and the three stream/sky_job_bells.ytyp, stream/sky_job_deskbell.ydr, stream/sky_job_doorbell.ydr files with the matching manifest. Bell placements are world locations, not new inventory items. Copy custom audio files separately from saved config exports. Install all four complete postal JSON datasets, their README and both license notices; select the dataset matching your map. No external map texture pack or postal script is bundled.

Optional citizen-office registration: This release supplies integration support, not a bundled citizen-office app or physical paper item. Use it only when a trusted server integration explicitly registers its authority and the existing Mechanic vehicle-inspection and registration features are enabled. No new config flag automatically enables that authority, and classic workshop registration remains when none is registered. In authority mode, a valid KUV inspection is required even if the optional workshop check is disabled. The integration owns document items, inventory capacity, presentation and xnPlates setup. Temporary permits default to 259,200 online seconds of the holder character, including parked vehicles; offline time pauses. Replacement papers do not extend the budget, ownership transfer preserves remaining time, and expired permits remain expired. Previously permanent registrations require transfer rather than a fresh temporary permit. Preserve the vehicle identity and inspection/history records. Reconcile unconfirmed payments/refunds against the actual bank ledger before retrying; never delete pending payment claims to force a repeat.

  1. Restart and check

Perform a full server restart to load new file lists, sounds and streamed assets, then reconnect clients. Start the framework, database connector and selected inventory, keys, license, phone, banking and UI providers first, then Base 1.47.0, then Jobs Base 1.50.0 and wait for successful initialization. Start DOJ 0.5.0 before Police 1.39.0 for shared catalogue and court features, and Ambulance 2.46.0 before Crime 0.10.0 when using their medical integration. Mechanic 1.36.0 and Fire 1.18.0 follow both libraries. Treasure Hunt 1.1.0 and Pets 1.1.0 follow Base and their own listed dependencies. Install and start only resources you use. Confirm the installed versions, all four additional tables, successful Jobs Base initialization and the first database/provider error before gameplay checks. Library restarts can stop dependent resources; restore previously used dependents in the same order.

After SQL setup and this first successful restart, open /jobconfig and verify preserved jobs, grades, locations, grants and effective shared overrides. Test one opt-in bell for nearby/employees recipients, Y waypoint acceptance, Enter dismissal, cooldowns, custom audio and removal. Enable Business only for a test job and authorized roles; verify duty restrictions, opening/closed blips, announcement history and exclusion zones. If you enabled Discord output, test the actual public/private channels separately; check secrets remain server-only.

Test identity/license inspection on both an allowed restrained target and a denied unrestrained target, voluntary showing, current character ownership and a service card with a persistent number after reconnect. Check customized card layouts at your actual FiveM resolution; browser previews do not prove CEF behavior. Verify an authorized manager can assign a unique department number. Check nested radial actions, cuff hotkeys, target changes while holding the menu, full prop rotation and placement confirm/cancel cleanup.

For Dispatch, verify radio show/hide/operate through the radial menu, incident creation/selection/ownership, preserved vehicle selection during background updates, nearest/response recommendations and actual phone call closure. Test a known/unknown postal code only if lookup was enabled, using the chosen map. Change shift or save settings and confirm existing incidents are not announced again. Check Forms inbox/archive access and drug-test changes while retaining a draft/selection; verify matching Crime apps and their permissions when installed.

Check every rank's actual Sky salary and one intended interval/funding choice without duplicating native framework pay. Test nearby invoice recipients with your chosen billing provider; a submitted invoice is not proof of payment. Known rejections should remain visible, while uncertain provider outcomes require ledger reconciliation before retrying. Test retrieval/storage for a real saved vehicle with an eight-character/spaced plate; keep its original record and correct any reported collision instead of rewriting all plates.

If a trusted registration integration is installed, test inspection, a parked vehicle's registration, paper replacement, sale/transfer, remaining online budget and confirmed fee handling. Check expiry and permanent transfer without resetting vehicle history. Standard resource/source checks do not establish third-party document, bank, billing, xnPlates, QB/Qbox or multiplayer acceptance; verify the providers actually used by your server.

Version 1.49.0

Highlights

  • Added configurable player actions for linked jobs, including carrying, invoices, identity checks and selected licence checks.
  • Added per-job duty control and visual profiles for location markers, blips, NPCs and props.
  • Improved dispatch call handling and the phone emergency form.

Notable Changes

  • Added action-specific minimum grades and optional consent for carry, identity and licence requests.
  • Added inspection-only searches without confiscation and separate identity and licence displays.
  • Improved membership updates so hiring, grade changes and removal retain other jobs, gangs and character assignments.
  • Fixed new or duplicated jobs inheriting unrelated location identifiers and failing to save.
  • Fixed deletion of standalone creator entries such as Dyno installations.
  • Improved emergency reports with visible validation and preserved edits while a request is pending.
  • Improved dispatch notifications to open the intended incident and show its actual map position.
  • Fixed shared bodycam access changes being applied before the corresponding handover was confirmed.
  • Fixed vehicle actions disappearing from the normal radial menu when their target options are registered by the job resource.
  • Improved Job Configurator reopening to restore the last available resource, entry, section and tab during the current interface session.

Other Changes

  • Improved shared File Explorer previews and background updates without clearing drafts or selection.
  • Improved tablet opening and closing to load secondary views on demand and stop their inactive timers.
  • Changed configurator branding to remain independent of in-game job colours.
  • Added a bundled fallback employee-card image.
  • Improved hotkeys to stay quiet when the requested action is unavailable or no dispatch action is pending.

Changed Files

  • sky_jobs_base/config/config.lua
  • sky_jobs_base/config/images/duty/README.md
  • sky_jobs_base/config/images/duty/employee_card.svg
  • sky_jobs_base/config/locales/*
  • sky_jobs_base/fxmanifest.lua
  • sky_jobs_base/source/* — delete and reinsert
Update InstructionsWhat to copy, what to keep and what to check1.48.11.49.0

Simplified update

Update sky_jobs_base safely

Read the complete update instructions in one continuous guide.

  1. Prepare

These instructions cover sky_jobs_base 1.48.1 → 1.49.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.49.0 customer package. Delete the entire sky_jobs_base/source/ folder and insert the new one, then replace sky_jobs_base/fxmanifest.lua from the same package. Refresh the complete sky_jobs_base/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, add config/images/duty/employee_card.svg and update its accompanying README.md. Refresh the complete config/locales/ tree, including jobconfigurator/ subfolders for every installed consumer; their configurator text is supplied by Jobs Base. Keep custom duty images and configured image URLs.

Deploy Ambulance 2.45.0 together with Jobs Base 1.49.0: hospital-bed Respawn labels now belong to Jobs Base's config/locales/jobconfigurator/sky_ambulancejob/ packs.

  1. Merge settings

When Config.UseIngameConfigurator = 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_jobs_base only if you intentionally want to import your edited plaintext configuration, after backing up and reviewing its replacement scope. With Config.UseIngameConfigurator = false, merge the settings into the supplied config files instead.

Existing job behaviour is retained unless you enable a new action. Open /jobconfig, select the linked job and its Player interactions extension (playerInteractions). All new actions default off; requireOnDuty defaults true for jobs, each enabled action's <action>MinGrade defaults 0, and carryRequireAcceptance, identityRequireAcceptance and licensesRequireAcceptance default true. Select each permitted license:<type> explicitly; these default false. Gangs do not gain job duty or billing settings. Search and confiscation are separate switches. Retain existing Police/Crime permissions; this editor adds explicit access for the selected linked group.

Per-job Duty system (dutySystemEnabled) defaults enabled under the resource's existing global duty policy. Disabling it keeps the capable group's members on duty and hides its duty terminals; saved off-duty aliases and locations remain. It cannot override a disabled global duty system. In location appearance, retain inherited defaults or set explicit Marker, Blip, NPC and Object values. Appearance changes do not grant access or change public/duty rules.

Global appearance is under /jobconfig → Jobs Base → Interactions. Config.Interactions.<type>.object is new for job_garage, garage_vehicle_spawn, garage_vehicle_park, garage_helicopter_menu, garage_helicopter_spawn, garage_helicopter_park, garage_boat_menu, garage_boat_spawn, garage_boat_park, boss_menu, duty, wardrobe, storage, locker, wholesale_shop and public_forms. Each defaults to:

object = {
    enabled = false,
    model = "",
    heading = 0.0,
    offset = vector3(0.0, 0.0, 0.0)
}

For plaintext mode, add the block to the corresponding existing Config.Interactions entry, preserving its marker, blip and NPC settings. No props are enabled by this update. Existing custom renderers retain their own behaviour. Keep dispatch service numbers, centre coverage, selected phone provider and saved access settings.

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 Jobs Base table, column or manual migration in this release. Preserve job settings, assignments, duty state, documents, locations and stored grants. Items: No new items. Assets: Add the supplied config/images/duty/employee_card.svg; configured custom cards keep their priority. Optional props require their configured models. No map or streamed-model replacement is required.

  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.

Reopen /jobconfig and confirm saved jobs, grades and locations. On staging, enable one linked-job action and test allowed and denied grades, duty, consent refusal and disconnect/character change. Both carry participants can use /cancelcarry or ESC to set down; also check pause-menu behaviour on your client. Check identity and only the enabled licence types, inspection-only search and the selected invoice recipient. Confirm per-job duty control and an inherited/overridden location appearance, including removal cleanup. Place and accept a real dispatch call using your selected provider; reopen the incident from its notification. Check normal folders while shared documents load and preserve a draft through a deadline update.

Open a job or creator entry, choose a tab, close /jobconfig and reopen it. Confirm the remembered available view loads current data. Navigation is kept for the current NUI session; it does not save an unsaved draft or survive a resource restart.

Version 1.48.1

Highlights

  • Fixed an issue where job resources permanently stopped initializing after 60 seconds on a slow server startup.

Notable Changes

  • Improved startup so failed schema and compatibility upgrades do not block independent job initialization while saved settings are preserved.
  • Fixed an issue where the Parts Delivery handling selector was missing from the Job Configurator.
  • Fixed an issue where standalone creator entries, including Dyno installations, could not be deleted in the Job Configurator.
  • Fixed an issue where new or duplicated jobs inherited another job's locations and access settings, preventing them from being saved.
  • Improved the phone emergency form with a compact layout and visible feedback for missing details or unavailable services.
  • Fixed an issue where sending an emergency report could clear changes typed while the request was pending.
  • Fixed an issue where selecting an emergency service could capture game input as if the player were typing.

Other Changes

  • Improved initialization failure messages so operators can distinguish a database warning from a failed dependency.
  • Updated the release package to keep the shared dependency bootstrap editable for support.
  • Added translated Job Configurator controls for vehicle purchase-price sources and the tuning free-camera option.
  • Added translated Job Configurator controls for laboratory limits per character and faction.

Changed Files

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

Simplified update

Update sky_jobs_base safely

Read the complete update instructions in one continuous guide.

  1. Prepare

These instructions cover sky_jobs_base 1.48.0 → the refreshed 1.48.1 package. If you installed an earlier 1.48.1 download today, download the current 1.48.1 package again and apply these steps. The manifest version stays the same, so the version number alone does not identify the refreshed package. Back up resources, the database, custom configuration, translations and saved Job Configurator/Creator data. Validate on staging and stop the server for replacement. Install the refreshed Base 1.45.1, then Jobs Base 1.48.1, then the matching updates for your installed jobs and Crime. Complete earlier migrations first when upgrading from an older version.

  1. Replace files

Use the complete 1.48.1 package. Delete the entire sky_jobs_base/source/ folder and insert its new version, then replace sky_jobs_base/fxmanifest.lua from the same package. Do not merge old generated interface files. Refresh the complete sky_jobs_base/config/locales/ tree and merge custom translations. Keep your existing selected language in sky_base/config/config.lua.

The dependency bootstrap ships as an editable file. Use the supplied file; do not restore an older custom bootstrap. Base also keeps its callback files editable for support. Install the source and manifest together.

  1. Merge settings

No new Jobs Base plaintext configuration keys or defaults are introduced. Keep existing jobs, grades, locations and saved overrides; no reset or configuration re-import is required. /jobconfig does not replace runtime files, install schema or reload changed manifests.

The refreshed Mechanic 1.34.1 supplies the global vehicle price settings vehiclePriceSource = "auto", vehiclePriceTable = "vehicles", vehiclePriceModelColumn = "model", vehiclePricePriceColumn = "price" and vehiclePriceHashColumn = "", at Mechanic Jobs → General → Database. Its new feature tuningFreeCamera defaults to true, at Mechanic Jobs → Features → Free camera in tuning menu. Jobs Base supplies these controls' translations; the matching Mechanic runtime and configuration must also be updated. Use the complete Mechanic 1.34.1 update instructions for the plaintext blocks, price hook and existing saved overrides.

The refreshed Crime 0.8.1 adds resource-wide laboratory limits, at Crime System → Drug System → General: drugMaxLaboratoriesPerCharacter = 0 and drugMaxLaboratoriesPerFaction = 0; 0 means unlimited. Jobs Base supplies the translated labels. Install the matching Crime runtime and follow the complete Crime 0.8.1 update instructions for its plaintext block and saved overrides. New controls alone do not install either resource's behaviour.

The existing Mechanic Jobs → Parts Delivery Shop → Delivery handling selector is restored. 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". Saved overrides remain authoritative when enabled.

Optional diagnostics are 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 not a /jobconfig setting; no recording or upload starts automatically.

  1. Database, items and assets

SQL: No new table, column or manual SQL update is introduced by this patch. Existing failed migrations still need their original database error repaired; continuing startup does not create a missing schema. Keep the existing automatic/manual migration policy. Do not replay a full import, clear tables, force success markers or reset saved job/Creator data. Items: No new definitions or inventory registrations. Assets: No new item images, models or stream assets; keep existing assets. Earlier release requirements still apply for older installations.

  1. Restart and check

Perform a full server restart after replacement so the changed manifests and file lists are reloaded. Start the framework, database connector and selected providers first, then Base 1.45.1, Jobs Base 1.48.1 and the installed consumers. Unrelated clothing, vehicle and map packs can remain after Sky in server.cfg. Reconnect clients. Open /jobconfig, check saved settings and an installed job. For Mechanic, open Parts Delivery Shop and confirm the Delivery handling selector shows your saved mode. A long dependency wait now continues until initialization completes; it no longer aborts at 60 seconds. Database migration warnings remain actionable, and failure to read saved settings remains a visible initialization error. Collect the first error, preceding lines and actual installed versions if a feature remains unavailable. On staging, create and duplicate a temporary job and confirm it can be saved with its own locations and access settings. Check deletion of a temporary standalone creator entry without deleting an existing production location. Open the phone emergency form, check service selection, required-message validation and unavailable-service feedback. For a permitted staging report, confirm success feedback and that text entered while submission is pending is retained. Check the matching Mechanic and Crime configurator controls in your selected language and confirm saved choices remain after reopening.

Version 1.48.0

Highlights

  • Added Sky Billing with personal invoice history through /billing and staff invoice management in supported job tablets.
  • Added optional installment plans so recipients can choose approved payment schedules before a Pay Later invoice becomes overdue.
  • Added configurable employee shares for confirmed society-to-player monetary invoice payments.
  • Added an option to restrict each dispatch center to the dispatcher's own department.
  • Improved configuration updates so clients receive changed settings without repeated full-state transfers.
  • Improved Job Configurator saves so unchanged pages disable Save and repeated clicks cannot start another save while one is pending.

Notable Changes

  • Added a /dispatchholster command to hide or show the dispatch radio while retaining its current unit state.
  • Added permission-protected review and deletion of stored dispatch incidents in the Job Configurator.
  • Fixed an issue where staffed dispatch calls were broadcast to busy crews instead of being routed to the active dispatcher.
  • Fixed an issue where direct dispatch assignments required crews to accept an offer before receiving navigation.
  • Fixed an issue where radio and bodycam state could be missing after the interface reloaded or finished mounting late.
  • Improved helicopter spotlight synchronization for nearby players.
  • Fixed an issue where interrupted hands-up animations could leave aiming and firing blocked.
  • Fixed an issue where tablet maps ignored configured colleague GPS and vehicle sharing restrictions.
  • Changed briefcases to remain hidden until players choose to show them.
  • Changed the default head-bag interaction to support both the inventory item and radial menu.
  • Added gang selectors to supported shared activity access lists while retaining job duty rules.
  • Improved storage transfer controls, provider-backed weight and capacity displays, and readable localized item quantities.
  • Improved radial labels with two-line text, full-label tooltips and uninterrupted hover feedback.
  • Improved Job Configurator layouts at different resolutions and aligned shared dark form controls.
  • Improved model selection and previews for supported speed-camera and nozzle settings.
  • Fixed an issue where job saves were blocked before a dispatch center had been assigned.
  • Fixed an issue where navigating configuration sections could discard already loaded locations.
  • Fixed an issue where editing existing role labels changed their technical rank identity and could invalidate related permissions.
  • Fixed an issue where a native rank change could fail its own authorization after the acting manager's rank had been remapped.
  • Fixed an issue where stopping a job resource could lose accrued duty time before the next normal salary run.

Other Changes

  • Removed database setup from /jobconfig so the startup schema switch is controlled only by config.lua.
  • Added DOJ to the Job Configurator's resource version checks.
  • Improved translated configuration labels and guidance for shared systems and supported job resources.
  • Improved shared description fields so they grow with their content.
  • Fixed an issue where configuration controls ignored their configured visibility.
  • Optimized startup database metadata checks and configuration state copying.
  • Improved optional Jobs Creator integration for native ranks, existing duty pairs, confirmed member actions and preserved location settings.
  • Improved Job Configurator update routing so each resource receives the profile changes it uses while existing global update events remain available.
  • Improved server locale loading so English and the configured language load initially and additional bundled languages load when requested.
  • Improved Job Configurator navigation and list styling with the shared form controls.

Changed Files

  • sky_jobs_base/config/config.lua
  • sky_jobs_base/config/init.lua
  • sky_jobs_base/config/inventory/README.md
  • sky_jobs_base/config/item_containers.lua
  • sky_jobs_base/config/locales/*
  • sky_jobs_base/fxmanifest.lua
  • sky_jobs_base/import.sql
  • sky_jobs_base/source/* — delete and reinsert
Update InstructionsWhat to copy, what to keep and what to check1.47.11.48.0

Simplified update

Update sky_jobs_base safely

Read the complete update instructions in one continuous guide.

  1. Prepare

These instructions cover sky_jobs_base 1.47.1 → 1.48.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.48.0 release package. Delete the entire sky_jobs_base/source/ folder and insert its new version; do not merge old generated interface files. Replace sky_jobs_base/fxmanifest.lua from the same package. Refresh the complete sky_jobs_base/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_jobs_base/config/config.lua
  • sky_jobs_base/config/init.lua
  • sky_jobs_base/config/inventory/README.md
  • sky_jobs_base/config/item_containers.lua
  • sky_jobs_base/config/locales/*
  • sky_jobs_base/fxmanifest.lua
  • sky_jobs_base/import.sql
  • sky_jobs_base/source/* — delete and reinsert
  1. Merge configuration

Jobs Base uses saved /jobconfig settings and shipped defaults while Config.UseIngameConfigurator = true. Saved overrides are retained. Manage the shared changes in Jobs Base inside /jobconfig; changing managed values only in config.lua does not replace saved values in this mode. If you intentionally work from files, set Config.UseIngameConfigurator = false in sky_jobs_base/config/config.lua and restart; saved settings are retained for later use. To deliberately import your plaintext shared settings into the saved configuration, review those values and use /jobconfigimport sky_jobs_base; this is an explicit replacement/import action, not a required automatic step for every update.

In sky_jobs_base/config/config.lua, Config.Billing did not exist in 1.47.1. Add this complete new table when maintaining an existing plaintext config:

Config.Billing = {
    enabled = true,
    command = "billing",
    openKey = "",
    defaultCurrency = "bank",
    depositToSociety = true,
    requireOnDuty = true,
    maxAmount = 1000000,
    range = 6.0,
    paymentTermDays = 7,
    autoPayOverdue = true,
    onsiteTimeoutSeconds = 120,
    installmentPlans = {},
    employeeShares = {},
}

With /jobconfig enabled, the key is Billing at Jobs Base → Administration → Billing. The new fields are enabled=true, command="billing", openKey="", defaultCurrency="bank", depositToSociety=true, requireOnDuty=true, maxAmount=1000000, range=6.0, paymentTermDays=7, autoPayOverdue=true, onsiteTimeoutSeconds=120, installmentPlans={} and employeeShares={}. Missing saved Billing fields receive these defaults. Plans and employee shares enable no jobs by default; add approved jobs deliberately. New invoice deadlines and percentages do not change the terms already stored on existing invoices. Command/key changes require a resource restart, and existing personal FiveM key bindings remain saved.

In the same file:

  • Config.HeadBag.useItem changes from "inventory" to "both". In /jobconfig, edit key HeadBag.useItem under Jobs Base → Interactions → Head bag if you want that new default. Existing saved "inventory" overrides stay as they are.
  • Config.StationBlip.useBlipPrefix is new; add useBlipPrefix = true, inside the existing StationBlip table. The /jobconfig key is StationBlip.useBlipPrefix, labelled Show blip prefix. false hides the prefix while keeping the configured label saved.
  • Config.Dispatch.centers[1].restrictToDispatcherJob (center central_dispatch) and Config.Dispatch.centers[2].restrictToDispatcherJob (center ems_dispatch) are new. Add restrictToDispatcherJob = true, beside each center's enabled field. The /jobconfig key is Dispatch.centers.<entry>.restrictToDispatcherJob, labelled Restrict to own job. Saved centers that omit the field inherit true from the new defaults. Set it explicitly to false for each center intended to coordinate multiple departments, and review its dispatcher/covered job lists. In plaintext mode a custom center that omits the field is not restricted; the bundled centers now explicitly set it to true.
  • Config.AutoExecuteQuery remains true; only its ownership/comment changed. It is now exclusively a startup value in this file, in both configurator modes. The old AutoExecuteQuery / Database Setup setting is removed from /jobconfig and import/runtime application. Existing saved overrides are ignored and disappear on the next settings write. Keep the plaintext value you require and restart after changing it.
  • The new comments describing gang:<internal_name> in activity and prop access lists change accepted selector guidance, not the shipped list values. Existing job/group selectors remain valid.

In sky_jobs_base/config/item_containers.lua, the first item sky_briefcase gains the file-based value Config.ItemContainers.items[1].hiddenByDefault = true; it was absent before. Add hiddenByDefault = true, beside autoShowWhenOwned = true,. Keep autoShowWhenOwned as true: after an explicit Show it still follows inventory ownership. Visibility resets to hidden for the next character session. This container configuration is not a /jobconfig setting.

Replace sky_jobs_base/config/init.lua from the same release download. It reuses already loaded language packs and loads the optional Jobs Creator configuration locale pack; it introduces no user option. Update the complete sky_jobs_base/config/locales/* folder, including all Job Configurator packs. Hungarian was already included before this release.

Bootstrap, permissions, Lua callbacks/metadata and provider secrets remain file-based. sky_jobs_base/config/webhooks.lua and config/printers.lua have no net changes in this release; retain your existing secrets and settings. Update config/inventory/README.md for the new briefcase visibility instructions. No current item definition needs a rename or reset.

The save protection, shutdown and update-routing changes introduce no additional plaintext settings, Job Configurator keys, default values or saved-override migrations. Replace config/init.lua to install the matching server and client locale loader, and replace the Job Configurator locale packs to install the save-in-progress and save-rate messages. The existing configured language is retained. Existing Job Configurator values remain with their current resource and saved revision. Saved Job Configurator values must still be reviewed separately from file defaults. Install the complete generated frontend and source package together; copying Lua alone does not install the Save controls. The optional Creator consumes the same stores but remains a separately unreleased product.

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: Back up the active database and select the same database used by the server. Choose exactly one route: automatic setup with Config.AutoExecuteQuery = true, or the manual block for your database engine with Config.AutoExecuteQuery = false. Do not run both manual dialects or repeat the manual update after successful automatic setup. This plaintext switch in sky_jobs_base/config/config.lua applies independently of /jobconfig mode.

Automatic route. Allow the startup migration to finish. It creates sky_jobs_invoices, adds department ownership to Dispatch audit/map/call/chat records and ensures InnoDB for the Dispatch map table. No manual SQL is needed for this route.

Manual route - MariaDB. With automatic setup disabled and job resources stopped, apply this complete targeted block to the selected server database. The new invoice table did not exist in release 1.47.1. The block creates it without seeding invoices and adds the new Dispatch columns; existing data and the database's charset/collation remain. Do not run unrelated historic import/seed operations. The ADD COLUMN IF NOT EXISTS syntax in this retained block is specific to MariaDB.

CREATE TABLE IF NOT EXISTS `sky_jobs_invoices` (
    `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
    `reference` VARCHAR(128) NOT NULL,
    `issuer_type` VARCHAR(16) NOT NULL,
    `job_name` VARCHAR(64) NOT NULL DEFAULT '',
    `job_label` VARCHAR(120) NOT NULL,
    `account` VARCHAR(128) NOT NULL DEFAULT '',
    `issuer_identifier` VARCHAR(128) NOT NULL DEFAULT '',
    `issuer_name` VARCHAR(120) NOT NULL,
    `actor_name` VARCHAR(120) NOT NULL,
    `actor_identifier` VARCHAR(128) NOT NULL DEFAULT '',
    `employee_share_percent` TINYINT UNSIGNED NOT NULL DEFAULT 0,
    `employee_share_paid` INT UNSIGNED NOT NULL DEFAULT 0,
    `employee_share_phase` VARCHAR(24) NULL,
    `employee_share_pending` INT UNSIGNED NULL,
    `employee_share_next_attempt_at_ts` BIGINT NOT NULL DEFAULT 0,
    `payment_mode` VARCHAR(16) NOT NULL DEFAULT 'later',
    `due_at_ts` BIGINT NOT NULL DEFAULT 0,
    `installment_count` TINYINT UNSIGNED NOT NULL DEFAULT 1,
    `installment_interval_days` SMALLINT UNSIGNED NOT NULL DEFAULT 0,
    `installment_start_at_ts` BIGINT NOT NULL DEFAULT 0,
    `next_attempt_at_ts` BIGINT NOT NULL DEFAULT 0,
    `collection_failure_code` VARCHAR(32) NOT NULL DEFAULT '',
    `collection_failed_at_ts` BIGINT NOT NULL DEFAULT 0,
    `reminder_at_ts` BIGINT NOT NULL DEFAULT 0,
    `recipient_type` VARCHAR(16) NOT NULL,
    `recipient_job` VARCHAR(64) NOT NULL DEFAULT '',
    `recipient_identifier` VARCHAR(128) NOT NULL DEFAULT '',
    `recipient_name` VARCHAR(120) NOT NULL,
    `reason` TEXT NOT NULL,
    `amount` INT UNSIGNED NOT NULL,
    `amount_paid` INT UNSIGNED NOT NULL DEFAULT 0,
    `currency` VARCHAR(64) NOT NULL,
    `deposit_to_society` TINYINT NOT NULL DEFAULT 1,
    `source_type` VARCHAR(64) NOT NULL,
    `status` VARCHAR(24) NOT NULL DEFAULT 'open',
    `payment_phase` VARCHAR(24) NULL,
    `pending_amount` INT UNSIGNED NULL,
    `pending_currency` VARCHAR(64) NULL,
    `payer_identifier` VARCHAR(128) NULL,
    `payer_job` VARCHAR(64) NULL,
    `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `paid_at` DATETIME NULL,
    PRIMARY KEY (`id`),
    UNIQUE KEY `uq_sky_invoice_reference` (`reference`),
    KEY `idx_sky_invoice_recipient` (`recipient_identifier`, `id`),
    KEY `idx_sky_invoice_sender` (`job_name`, `id`),
    KEY `idx_sky_invoice_society` (`recipient_job`, `id`),
    KEY `idx_sky_invoice_due` (`payment_mode`, `status`, `next_attempt_at_ts`, `due_at_ts`),
    KEY `idx_sky_invoice_employee` (`employee_share_phase`, `employee_share_next_attempt_at_ts`, `actor_identifier`)
) ENGINE=InnoDB;

ALTER TABLE `sky_jobs_dispatch_audit` ADD COLUMN IF NOT EXISTS `job` VARCHAR(80) NULL AFTER `center_id`;
ALTER TABLE `sky_jobs_dispatch_map_features` ADD COLUMN IF NOT EXISTS `job` VARCHAR(80) NULL AFTER `center_id`;
ALTER TABLE `sky_jobs_dispatch_calls` ADD COLUMN IF NOT EXISTS `job` VARCHAR(80) NULL AFTER `center_id`;
ALTER TABLE `sky_jobs_dispatch_center_chat` ADD COLUMN IF NOT EXISTS `job` VARCHAR(80) NULL AFTER `center_id`;

SET @dispatch_engine_upgrade = IF(
    (SELECT UPPER(ENGINE) FROM INFORMATION_SCHEMA.TABLES
        WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'sky_jobs_dispatch_map_features') = 'INNODB',
    'SELECT 1',
    'ALTER TABLE `sky_jobs_dispatch_map_features` ENGINE=InnoDB'
);
PREPARE dispatch_engine_upgrade FROM @dispatch_engine_upgrade;
EXECUTE dispatch_engine_upgrade;
DEALLOCATE PREPARE dispatch_engine_upgrade;

Manual route - MySQL 8. Run this complete alternative instead of the MariaDB block, with Config.AutoExecuteQuery = false and job resources stopped. Select the server's active database first and run all statements in the same SQL session. Each column is checked through INFORMATION_SCHEMA.COLUMNS in DATABASE() before it is added; existing columns are retained. The invoice table and conditional Dispatch engine upgrade are included here as well.

CREATE TABLE IF NOT EXISTS `sky_jobs_invoices` (
    `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
    `reference` VARCHAR(128) NOT NULL,
    `issuer_type` VARCHAR(16) NOT NULL,
    `job_name` VARCHAR(64) NOT NULL DEFAULT '',
    `job_label` VARCHAR(120) NOT NULL,
    `account` VARCHAR(128) NOT NULL DEFAULT '',
    `issuer_identifier` VARCHAR(128) NOT NULL DEFAULT '',
    `issuer_name` VARCHAR(120) NOT NULL,
    `actor_name` VARCHAR(120) NOT NULL,
    `actor_identifier` VARCHAR(128) NOT NULL DEFAULT '',
    `employee_share_percent` TINYINT UNSIGNED NOT NULL DEFAULT 0,
    `employee_share_paid` INT UNSIGNED NOT NULL DEFAULT 0,
    `employee_share_phase` VARCHAR(24) NULL,
    `employee_share_pending` INT UNSIGNED NULL,
    `employee_share_next_attempt_at_ts` BIGINT NOT NULL DEFAULT 0,
    `payment_mode` VARCHAR(16) NOT NULL DEFAULT 'later',
    `due_at_ts` BIGINT NOT NULL DEFAULT 0,
    `installment_count` TINYINT UNSIGNED NOT NULL DEFAULT 1,
    `installment_interval_days` SMALLINT UNSIGNED NOT NULL DEFAULT 0,
    `installment_start_at_ts` BIGINT NOT NULL DEFAULT 0,
    `next_attempt_at_ts` BIGINT NOT NULL DEFAULT 0,
    `collection_failure_code` VARCHAR(32) NOT NULL DEFAULT '',
    `collection_failed_at_ts` BIGINT NOT NULL DEFAULT 0,
    `reminder_at_ts` BIGINT NOT NULL DEFAULT 0,
    `recipient_type` VARCHAR(16) NOT NULL,
    `recipient_job` VARCHAR(64) NOT NULL DEFAULT '',
    `recipient_identifier` VARCHAR(128) NOT NULL DEFAULT '',
    `recipient_name` VARCHAR(120) NOT NULL,
    `reason` TEXT NOT NULL,
    `amount` INT UNSIGNED NOT NULL,
    `amount_paid` INT UNSIGNED NOT NULL DEFAULT 0,
    `currency` VARCHAR(64) NOT NULL,
    `deposit_to_society` TINYINT NOT NULL DEFAULT 1,
    `source_type` VARCHAR(64) NOT NULL,
    `status` VARCHAR(24) NOT NULL DEFAULT 'open',
    `payment_phase` VARCHAR(24) NULL,
    `pending_amount` INT UNSIGNED NULL,
    `pending_currency` VARCHAR(64) NULL,
    `payer_identifier` VARCHAR(128) NULL,
    `payer_job` VARCHAR(64) NULL,
    `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `paid_at` DATETIME NULL,
    PRIMARY KEY (`id`),
    UNIQUE KEY `uq_sky_invoice_reference` (`reference`),
    KEY `idx_sky_invoice_recipient` (`recipient_identifier`, `id`),
    KEY `idx_sky_invoice_sender` (`job_name`, `id`),
    KEY `idx_sky_invoice_society` (`recipient_job`, `id`),
    KEY `idx_sky_invoice_due` (`payment_mode`, `status`, `next_attempt_at_ts`, `due_at_ts`),
    KEY `idx_sky_invoice_employee` (`employee_share_phase`, `employee_share_next_attempt_at_ts`, `actor_identifier`)
) ENGINE=InnoDB;

SET @sky_release_add_column = IF(
    EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS
        WHERE TABLE_SCHEMA = DATABASE()
            AND TABLE_NAME = 'sky_jobs_dispatch_audit' AND COLUMN_NAME = 'job'),
    'SELECT 1',
    'ALTER TABLE `sky_jobs_dispatch_audit` ADD COLUMN `job` VARCHAR(80) NULL AFTER `center_id`'
);
PREPARE sky_release_add_column FROM @sky_release_add_column;
EXECUTE sky_release_add_column;
DEALLOCATE PREPARE sky_release_add_column;
SET @sky_release_add_column = IF(
    EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS
        WHERE TABLE_SCHEMA = DATABASE()
            AND TABLE_NAME = 'sky_jobs_dispatch_map_features' AND COLUMN_NAME = 'job'),
    'SELECT 1',
    'ALTER TABLE `sky_jobs_dispatch_map_features` ADD COLUMN `job` VARCHAR(80) NULL AFTER `center_id`'
);
PREPARE sky_release_add_column FROM @sky_release_add_column;
EXECUTE sky_release_add_column;
DEALLOCATE PREPARE sky_release_add_column;
SET @sky_release_add_column = IF(
    EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS
        WHERE TABLE_SCHEMA = DATABASE()
            AND TABLE_NAME = 'sky_jobs_dispatch_calls' AND COLUMN_NAME = 'job'),
    'SELECT 1',
    'ALTER TABLE `sky_jobs_dispatch_calls` ADD COLUMN `job` VARCHAR(80) NULL AFTER `center_id`'
);
PREPARE sky_release_add_column FROM @sky_release_add_column;
EXECUTE sky_release_add_column;
DEALLOCATE PREPARE sky_release_add_column;
SET @sky_release_add_column = IF(
    EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS
        WHERE TABLE_SCHEMA = DATABASE()
            AND TABLE_NAME = 'sky_jobs_dispatch_center_chat' AND COLUMN_NAME = 'job'),
    'SELECT 1',
    'ALTER TABLE `sky_jobs_dispatch_center_chat` ADD COLUMN `job` VARCHAR(80) NULL AFTER `center_id`'
);
PREPARE sky_release_add_column FROM @sky_release_add_column;
EXECUTE sky_release_add_column;
DEALLOCATE PREPARE sky_release_add_column;

SET @dispatch_engine_upgrade = IF(
    (SELECT UPPER(ENGINE) FROM INFORMATION_SCHEMA.TABLES
        WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'sky_jobs_dispatch_map_features') = 'INNODB',
    'SELECT 1',
    'ALTER TABLE `sky_jobs_dispatch_map_features` ENGINE=InnoDB'
);
PREPARE dispatch_engine_upgrade FROM @dispatch_engine_upgrade;
EXECUTE dispatch_engine_upgrade;
DEALLOCATE PREPARE dispatch_engine_upgrade;

Items: No Jobs Base item definition, container slot limit or item name changes in this release. The briefcase only gains its hidden-by-default attachment policy in config/item_containers.lua; existing Show/Hide item buttons remain usable. No inventory reimport is needed for that policy change.

Assets: Install source/* from the same completed release package so its rebuilt tablet/configurator files and police files icon are included. Existing external image URLs and inventory images remain your own settings. No new Jobs Base streamed model or separate image installation is required.

Providers and invoice scope: Select Sky Billing through Base Config.billing="sky" and use matching updated job resources for their supported billing workflows. Police/Ambulance/Fire keep their own saved billing-mode overrides; modes must reach the selected provider for new Sky invoices. Explicit external provider invoices are not automatically copied into /billing. Mechanic Advanced Billing keeps its own service invoices, payments and order completion; central installments and employee shares do not apply to those invoices. Plans and shares are opt-in by job; only confirmed qualifying payments earn a share, and offline employee payouts wait until login. A payment awaiting verification is not proof of a failed debit; check the invoice and provider account history before attempting manual recovery.

Permissions and dependencies: Existing invoice/management permissions still control staff actions; this release does not require reassigning new global permission IDs. Stop the server for the coordinated update, install matching Base 1.45.0 first, Jobs Base 1.48.0 second and updated affected job resources after them, then restart and reconnect clients. The optional Jobs Creator must be updated to a compatible build if its embedded editor/native administration is used. It remains a separate resource; these library notes do not publish its full product or promise a complete Hex/Jaksam replacement.

No additional SQL, inventory item definitions, item icons or streamed assets are required for these Jobs Base changes. The invoice and Dispatch schema instructions in this guide still apply. Shutdown records accrued work time and leaves unpaid salary intervals for the next normal payroll run; it does not issue a salary payment from an unloading resource. Jobs Creator remains a separate unreleased resource; its existing Archive/Restore behavior is unchanged.

  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. After restarting, confirm that startup migrations finish and both Base/Jobs Base show the expected release versions. Open /jobconfig → Jobs Base → Administration → Billing and confirm default empty plans/shares, intended command, duty policy and invoice limits. Check each Dispatch center's Restrict to own job setting, then compare two departments' visibility and a direct unit assignment. Verify /dispatchholster, radio/bodycam after reopening, map GPS/sharing rules and an interrupted hands-up pose. Own a briefcase, open its container, select Show/Hide, then switch characters to confirm the hidden start. Issue one Sky invoice, pay it through the selected bank/cash option and confirm a single income entry; separately retain the existing external/Mechanic path where used. Reopen saved settings/locations without manually refreshing. No new many-player, live CEF or provider acceptance is claimed by this publication.

Open Job Configurator, confirm an unchanged section has a disabled Save button, change one existing value, save once and reopen the same section to verify persistence. During a pending save, confirm a second click cannot submit another write and that a rejected save retains the draft. With a representative test character, clock in, stop the final resource owning that job, then restart it and verify the accrued duty time remains and the next normal payroll run pays only outstanding intervals. Confirm the configured language and English fallback still render the Job Configurator. The disposable database and source fixtures do not prove a live payroll or multi-player performance result.

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.47.1

Highlights

  • Changed shared job loading back to its previous behavior after the recent startup changes.

Notable Changes

  • Improved helicopter spotlight direction synchronization between players.

Other Changes

  • Updated Hungarian translations, including the Job Configurator and briefcase inventory buttons.

Changed Files

  • sky_jobs_base/config/inventory/ox_briefcase_buttons.lua
  • sky_jobs_base/config/locales/*
  • sky_jobs_base/fxmanifest.lua
  • sky_jobs_base/source/* — delete and reinsert
Update InstructionsWhat to copy, what to keep and what to check1.47.01.47.1

Simplified update

Update sky_jobs_base safely

Read the complete update instructions in one continuous guide.

  1. Prepare

These instructions cover sky_jobs_base 1.47.0 → 1.47.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.47.1 download. Delete the entire sky_jobs_base/source/ folder and insert the new folder. Replace sky_jobs_base/fxmanifest.lua from that same package. Refresh the complete sky_jobs_base/config/locales/ tree and reapply custom translations. Keep the new source and manifest together; do not merge old generated interface files into them.

Replace sky_jobs_base/config/inventory/ox_briefcase_buttons.lua. Existing ox_inventory item definitions continue to load that file; no item-definition rewrite is required.

  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. For Hungarian ox_inventory briefcase buttons, use the existing setr ox:locale "hu" in server.cfg before ox_inventory starts; this inventory language is separate from Config.locale.

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, check an installed job, and test helicopter spotlight direction with another player if you use it. If startup still fails, collect the first error and its preceding log lines together with the installed versions.

Version 1.47.0

Highlights

  • Added portable briefcases and case folders with separate inventories, transferable contents and controls for showing or hiding an owned briefcase.
  • Added configurable FiveM key bindings for panic alerts, position pings and incident actions, including direct dispatch acceptance with the player’s actual binding shown in notifications.
  • Added recognition of configured external hands-up animations for searches and zipties, independently of Sky’s own hands-up key.
  • Changed raids to start in the tablet and continue at authorized world storage and garage locations, with withdrawal-only storage and restricted garage actions.

Notable Changes

  • Improved the Job Configurator with consistent settings navigation, grouped options, clearer garage locations and targeted validation feedback while preserving saved values.
  • Fixed startup ordering so saved settings are loaded before dependent initialization and automatic database setup, with readable errors when loading fails.
  • Changed the default MultiJob administration commands to /skygivejob and /skyremovejob to avoid occupying framework command names.
  • Added /setcrimeboss and /removecrimeboss for Crime membership administration, while /setboss now handles regular-job rank permissions only.
  • Fixed employer duty terminals and persistent garage keys when players also hold Crime organization membership or switch their active access.
  • Fixed stale member-list responses after invitations and made failed membership changes visible to the affected players.
  • Improved printer placement with the placement gizmo, clearer document and case numbers, compatible custom printer providers and specific feedback when a printed copy cannot be collected.
  • Added support for printed certificate snapshots that retain the rendered layout, seal and name stamp from compatible document providers.
  • Added shared register support for resource-owned catalogs, searchable references and live person choices used by the matching DOJ update.
  • Added vehicle-certificate registry access for authorized on-duty DOJ employees without granting certificate editing permissions.
  • Fixed automatic-mission collection saves with the matching Fire Job update when saved lists are empty or ordered differently.
  • Optimized CCTV and bodycam status updates by combining changes for each authorized viewer and ignoring repeated revisions.
  • Fixed gallery and bodycam video queries that could fail when video URL patterns were treated as SQL placeholders.

Other Changes

  • Added Hungarian translations for shared job features, the Job Configurator and supported briefcase inventory actions.
  • Fixed GKSPhone dispatch text fields retaining or leaking keyboard input when changing fields or closing the phone.
  • Fixed vehicle-targeted radial actions losing the vehicle selected by the camera.
  • Fixed configured interaction visuals, empty labels and scenarios, NPC replacements and disabled parking markers being applied inconsistently.
  • Fixed inventory item image overrides being unavailable to dependent resources such as the camper manager.
  • Improved archived dispatch reports by loading their saved logs when a report is opened.
  • Fixed custom media providers represented by exported callbacks being rejected as invalid providers.
  • Improved cuffed interrogation poses so temporary gestures preserve the restraint state.
  • Fixed character-, paragraph- and line-anchored Word images appearing at the page origin.
  • Fixed saved HUD positions using their selected edge anchor correctly.
  • Added a temporary, once-per-character notice directing tablet users to apps grouped in File Explorer.
  • Added restart guidance after registered key or command changes and optional server diagnostics for investigating Job Configurator save errors.
  • Improved migration failure messages with stable caller information when encrypted source paths are unavailable.

Changed Files

  • sky_jobs_base/config/config.lua
  • sky_jobs_base/config/inventory/README.md
  • sky_jobs_base/config/inventory/items_ox.lua
  • sky_jobs_base/config/inventory/ox_briefcase_buttons.lua
  • sky_jobs_base/config/inventory/sky_briefcase.png
  • sky_jobs_base/config/inventory/sky_case_folder.png
  • sky_jobs_base/config/item_containers.lua
  • sky_jobs_base/config/locales/*
  • sky_jobs_base/fxmanifest.lua
  • sky_jobs_base/import.sql
  • sky_jobs_base/source/* — delete and reinsert
  • sky_jobs_base/stream/sky_briefcase_grip.ycd
Update InstructionsWhat to copy, what to keep and what to check1.46.01.47.0

Simplified update

Update sky_jobs_base safely

Read the complete update instructions in one continuous guide.

  1. Prepare the update

Back up your database and your existing sky_jobs_base folder. Also back up the inventory item definitions and images you will edit. Keep your existing settings, provider choices, webhooks and API keys.

Install Sky Base 1.44.0, Jobs Base 1.47.0, and the matching releases of your installed Sky job resources together. Install the matching Crime System update if you use raids or Crime organizations. Jobs Base now uses the updated Base migration and startup contracts; an older Base package is not compatible with this update. Keep optional resources installed only when you use them.

Before stopping the server, record the effective Jobs Base → General → Database setup (AutoExecuteQuery) value in /jobconfig; a saved override takes precedence over the file default. Stop the server during file replacement and database changes. Plan one full server restart after completing all steps below. Restarting only Jobs Base is insufficient for the command ownership changes in this release.

  1. Replace the package files

Delete the old sky_jobs_base/source/ folder and insert the complete new source/ folder. Copy the new fxmanifest.lua from the same package; its version must be 1.47.0 without a v. Update config/locales/ and merge your own translations. Copy import.sql and the changed config/inventory/ files listed above. Add config/item_containers.lua and stream/sky_briefcase_grip.ycd.

The complete source/ replacement includes the compiled tablet interface, the certificate name-stamp font and its license. Do not copy only individual Lua files or keep an older compiled interface. Merge the settings below into config/config.lua; do not replace your customized configuration with defaults. Keep your existing config/init.lua, config/webhooks.lua, provider secrets and printer customizations. No outside-source file must be removed or renamed for this update.

  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.

For the Show briefcase and Hide briefcase actions in ox_inventory, also update sky_jobs_base/config/inventory/ox_briefcase_buttons.lua. Its labels follow the inventory's ox:locale setting separately from Config.locale. To select Hungarian for those inventory actions, prepare setr ox:locale hu in server.cfg before the inventory starts; keep a different intentional inventory language if desired. Copy the helper and the Jobs Base hu.lua before the inventory loads its item catalog, then use the normal restart sequence. Existing item keys, callbacks and metadata stay the same.

Settings saved in /jobconfig are authoritative over file defaults. Updating config/config.lua alone does not replace a saved value. Missing settings inherit their new defaults; explicitly saved values and lists remain effective. After the server restarts, open /jobconfig, select Jobs Base, and check the sections below. Preserve your jobs, locations, ranks and saved overrides; do not reset or reimport them to install this update.

Admin command permissions — file only. Inside the existing Config.CommandPermissions table in config/config.lua, add the two new Crime command entries and rename the two old MultiJob entries. Preserve the administrator groups you already use. The shipped values for these four entries are:

setcrimeboss = { "god", "superadmin", "admin" },
removecrimeboss = { "god", "superadmin", "admin" },
skygivejob = { "god", "superadmin", "admin" },
skyremovejob = { "god", "superadmin", "admin" },

setcrimeboss and removecrimeboss were absent previously. givejob becomes skygivejob; removejob becomes skyremovejob. Remove the obsolete Sky entries after moving their groups. Leave other entries, including setboss, unchanged. These bootstrap permission entries are not managed through /jobconfig.

MultiJob command names — Jobs Base → Jobs → MultiJob. Change Config.MultiJob.giveJobCommand from "givejob" to "skygivejob" and Config.MultiJob.removeJobCommand from "removejob" to "skyremovejob". Update the corresponding saved settings if they contain the old default names. The runtime normalizes those legacy default names, while other custom command names remain unchanged. /jobs and /multijobadmin retain their names. Choose unused names if you use custom commands; a conflicting registration is skipped with a console warning.

If you maintain external ACE rules or admin menu shortcuts for Sky's old commands, change their command names and Sky ACE references: sky_jobs_base.givejob → sky_jobs_base.skygivejob, command.givejob → command.skygivejob, and the corresponding removejob → skyremovejob references. Preserve any separate framework/Qbox rules that intentionally refer to the framework's own commands.

/setboss <job> <grade> grants rank permissions for a regular job and no longer accepts a player assignment argument. Use /setcrimeboss <organization> <playerId> to assign the highest existing Crime rank. Use /removecrimeboss <organization> <playerId> to remove that player's membership in the named Crime organization; this removes membership rather than merely lowering the rank. Independent and native-gang providers retain the normal employer job. With a framework-job provider, assigning a Crime organization cannot replace an unrelated normal job, and removing that Crime membership returns the character to unemployed, rank 0. Existing admission requirements still apply. Existing organization definitions, ranks and permission grants do not need migration.

External hands-up detection — Jobs Base → Interactions → Handcuffs & hands up → Animation check. Config.PoliceCuffs.animationCheck is new. Insert this complete block inside your existing Config.PoliceCuffs table, alongside handsUp:

animationCheck = {
    enabled = true,
    animations = {
        { dict = "random@mugging3", name = "handsup_standing_base" },
        { dict = "missminuteman_1ig_2", name = "handsup_base" },
        { dict = "anim@mp_player_intuppersurrender", name = "idle_a_fp" },
        { dict = "anim@mp_rollarcoaster", name = "hands_up_idle_a_player_one" },
        { dict = "anim@scripted@bty2@ig2_beat_target@male@", name = "leaning_idle_bounty" },
        { dict = "anim@scripted@bty2@ig2_beat_target@male@", name = "standing_idle_bounty" }
    }
},

The exact managed settings are PoliceCuffs.animationCheck.enabled and PoliceCuffs.animationCheck.animations. Detection defaults to enabled and recognizes the listed RPEmotes hands-up animations for searches and zipties. It works even when PoliceCuffs.handsUp.enabled is disabled. The existing Sky hands-up defaults remain enabled, key H, hold time 3 seconds. For another emote, add its animation dictionary and clip name rather than its chat command or display label. Keep an intentional saved false or custom animation list.

Alert keys — Jobs Base → Radial & Alerts. Add keyMapping = "K", inside Config.Panic and keyMapping = "L", inside Config.Ping; these fields were absent before. Keep the remaining values, including Panic.useKeybind, unchanged. Add the complete new keyMappings table to Config.IncidentNotification; the full shipped notification block is:

Config.IncidentNotification = {
    durationMs = 30000,
    keyMappings = {
        acceptDispatch = "J",
        setWaypoint = "G",
        openMap = "M",
        dismiss = "BACK"
    }
}

Preserve your custom durationMs. The managed paths are Panic.keyMapping, Ping.keyMapping and IncidentNotification.keyMappings.acceptDispatch, .setWaypoint, .openMap, .dismiss. These values define defaults for new bindings. Existing personal bindings remain in Settings → Key Bindings → FiveM and can be changed there. J accepts the displayed dispatch, or the unit's pending radio assignment when no dispatch notification is shown; G only sets the waypoint. Saving a registered key or command change displays a restart notice. Restart the affected resource after later binding changes; this release itself requires the full server restart described below.

Garage spawn points — Jobs Base → World → Interactions. In Config.Interactions.garage_helicopter_spawn and Config.Interactions.garage_boat_spawn, add interaction = false,. The field was absent on both entries; the vehicle-spawn entry already used false. These are spawn positions, while menu and parking positions remain separate. Preserve your marker, blip and NPC choices. Review the corresponding saved interaction settings and any resource-specific location overrides so an intentional override is not mistaken for the new default. No location needs deletion or recreation.

Other repaired interaction settings retain their saved values: explicit empty labels/scenarios, marker offsets/scales, blip display/scale, NPC models and disabled parking markers are now applied consistently. Close and reopen existing configurator pages after the update before saving. With the matching Fire Job update, Automatic Missions lists now save correctly even when the saved list was empty or arranged differently; existing missions do not need to be recreated.

  1. Apply SQL, inventory and asset updates

config/item_containers.lua is a new plaintext, file-only configuration. It is not exposed through /jobconfig, and changes require a Jobs Base restart. Add the complete file. Its shipped configuration is:

Config.ItemContainers = {
    enabled = true,
    nativeOxProperties = true,
    items = {
        {
            name = "sky_briefcase",
            label = "Briefcase",
            description = "A lockable case for documents and work materials.",
            weight = 1500,
            slots = 24,
            maxWeight = 25000,
            allowlistEnabled = true,
            allowlist = { "sky_case_folder", "job_document", "doj_document", "doj_law_book" },
            blacklist = { "sky_briefcase" },
            autoShowWhenOwned = true,
            attachment = {
                model = "prop_ld_case_01",
                bone = 57005,
                offset = { x = 0.15, y = 0.0, z = -0.01 },
                rotation = { x = -90.0, y = -90.0, z = 0.0 },
                rotationOrder = 3, -- Native XZY matches the grip's Blender YZX transform.
                collision = false,
                animation = {
                    dict = "sky_briefcase_grip",
                    name = "grip",
                    flag = 305, -- Loop + upper body + secondary + additive; preserve normal body movement.
                },
            },
        },
        {
            name = "sky_case_folder",
            label = "Case Folder",
            description = "A folder for case files and loose documents.",
            weight = 450,
            slots = 12,
            maxWeight = 8000,
            blacklist = { "sky_briefcase", "sky_case_folder" },
            autoShowWhenOwned = false,
        },
    },
}

The briefcase accepts sky_case_folder, job_document, doj_document and doj_law_book by default. Set its allowlistEnabled to false only if you want other items to be allowed; its self-blacklist remains. The folder blocks both container item names. DOJ is not a dependency merely because its document names are listed. Register items you actually use through their owning product's instructions.

For ox_inventory or Qbox using ox_inventory, merge these two complete entries into the existing returned item table in ox_inventory/data/items.lua. Do not replace the whole inventory catalog, and do not duplicate existing entries:

["sky_briefcase"] = {
        label = "Briefcase",
        weight = 1500,
        stack = false,
        close = false,
        consume = 0,
        description = "A lockable case for documents and work materials.",
        client = { image = "sky_briefcase.png" },
        buttons = require "@sky_jobs_base.config.inventory.ox_briefcase_buttons",
    },
    ["sky_case_folder"] = {
        label = "Case Folder",
        weight = 450,
        stack = false,
        close = false,
        consume = 0,
        description = "A folder for case files and loose documents.",
        client = { image = "sky_case_folder.png" },
    },

Copy sky_jobs_base/config/inventory/sky_briefcase.png to ox_inventory/web/images/sky_briefcase.png and sky_jobs_base/config/inventory/sky_case_folder.png to ox_inventory/web/images/sky_case_folder.png. Keep the buttons = require "@sky_jobs_base.config.inventory.ox_briefcase_buttons" line on the briefcase and copy that helper file before the inventory loads its item catalog. It provides the localized Show briefcase and Hide briefcase actions. No ox core edit or second usable-item callback is required. Reloading the inventory definitions is included in the full server restart.

For other inventories, register the same two names in that provider's item catalog using its equivalent unique/non-stackable, reusable settings and copy the two PNGs into its image folder. Keep per-item metadata intact during storage and transfers. Each physical item owns a separate container identifier; do not clone that identifier or strip its metadata.

ox_inventory uses its native container metadata; Jobs Base also supports older ox versions without the runtime container-properties export through the native metadata path and a swap filter. CodeM V2, Core, One, Origen, PS, QB Inventory, QS and Tgiann use their metadata and stash APIs; filter enforcement depends on provider support. Jaksam and AK47 use their native item filters. Native ESX/VRP, JPR, CodeM V1 and custom adapters without both item metadata and stash support cannot open unique item containers. If your adapter lacks those capabilities, set Config.ItemContainers.enabled = false and omit these optional items until it supports them.

The default capacities are 24 slots / 25,000 weight units for a briefcase and 12 slots / 8,000 for a folder. The owned briefcase appears on the local player's hand after inventory loading. Hiding it persists until Show is selected or the character logs out; opening or closing its contents does not change visibility. Losing the last briefcase removes the prop. The folder has no prop by default. Add the items to your own shop or distribution system if you want players to obtain them; this update does not populate an existing shop automatically.

Apply the database change

This Jobs Base release adds one table, sky_jobs_tablet_notices, to remember per-character acknowledgements of the temporary File Explorer move notice. It adds no columns to existing tables, renames no existing table and requires no data reset.

When the effective Jobs Base AutoExecuteQuery setting is true, startup creates the table automatically. Use the effective Jobs Base → General → Database setup value recorded before shutdown; a saved override takes precedence over the file default. If you deliberately use AutoExecuteQuery = false, apply the following statement to the database used by your server before starting the updated resources:

CREATE TABLE IF NOT EXISTS `sky_jobs_tablet_notices` (
    `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
    `character_identifier` VARCHAR(128) NOT NULL,
    `notice_key` VARCHAR(64) NOT NULL,
    `acknowledged_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (`id`),
    UNIQUE KEY `uniq_character_notice` (`character_identifier`, `notice_key`)
) ENGINE=InnoDB;

The table inherits your database's character set and collation. Keep existing notice acknowledgements, tablet data and container metadata. Do not delete job tables or rerun an old destructive setup script. Follow the separate Crime System instructions for its raid data changes if that product is installed; those are not additional Jobs Base tables.

  1. Restart and verify

Complete the coordinated update, then fully restart the server. Start the framework, database/inventory and other required providers first, followed by sky_base, sky_jobs_base, and your installed Sky job resources. Keep their existing provider-specific start order requirements. A full restart releases the old shared command registrations; restarting Jobs Base alone does not do that for this update.

Check that Jobs Base reports 1.47.0, Base reports 1.44.0, and startup finishes without missing exports or migration errors. Open /jobconfig and confirm saved settings, locations and employer duty terminals remain present. If automatic SQL is disabled, check that sky_jobs_tablet_notices exists. Test your customized MultiJob commands and Crime administration with authorized accounts, then check the FiveM key bindings and one dispatch acceptance. If you enabled containers, give two separate test items, put different documents in each, transfer one to another player, and check that contents and Show/Hide controls work with your actual inventory provider.

If raids are used, update the matching Crime System package and test an authorized raid: the tablet starts the raid, while participants breach and access authorized storage or garages at the world locations. Raid storage permits withdrawals, and raid garage access does not grant the normal purchase, sale, transfer, plate-change or trunk-management actions. Preserve existing raid data and follow Crime's own migration instructions.

If /jobconfig still reports a save error, enable the optional diagnostic for one reproduction with set sky_jobconfig_trace 1 in the server console, reproduce the failing save, keep the complete Jobs Base error/traceback, then disable it with set sky_jobconfig_trace 0. It is disabled by default, is not a /jobconfig setting, and does not upload logs automatically.

Optional profiler capture

Profiler support is disabled by default. To collect a profile, place setr sky_profiler 1 in server.cfg before the Sky resource ensure lines, then restart the affected resources or the server. In the console for the side you are measuring, run profiler record 1000, reproduce the action, and use profiler status until recording has finished. Save the result manually with profiler saveJSON sky-release-profile.json and retain it for your support report. Recording and uploading do not start automatically.

After recording, change the setting to setr sky_profiler 0 and restart the affected resources or the server. This switch is not managed through /jobconfig. Keep source/ and fxmanifest.lua from the same release package. If you previously installed an older instrumented package that changed files outside source/, restore those shipped files once while merging back your custom settings; current profiler packages should not change plaintext configuration, locales, images or SQL.

Version 1.46.0

Highlights

  • Added interactive 3D printer maintenance with visible paper, ink and jam controls, together with a new Sky printer model for your locations.
  • Added a Save bodycam action to the radial menu and a dedicated gallery folder for saved recordings.
  • Added editable ranks for independent organizations, including rank names and order, without changing members' main framework job.

Notable Changes

  • Improved printers so their remaining paper and ink survive resource and server restarts.
  • Fixed an issue where queued print jobs could time out while waiting for another job, missing supplies or a paper jam.
  • Added an option to select an existing world printer and use its position and model without spawning a duplicate.
  • Added an optional setting to remove uncollected printouts when the printer service restarts.
  • Removed remote and temporary printer selection so printing and collection use your configured nearby printers.
  • Improved bodycam recording so the rolling video remains playable and adjusts its bitrate to the configured upload size limit.
  • Added sharing of bodycam recordings and supported older CCTV videos with authorized DOJ organizations, while keeping shared recordings available when they are hidden from the owner's gallery.
  • Improved organization access so an independent organization or supported secondary membership can use its facilities when the player's main job is off duty.
  • Improved organization member, unit and rank information used by connected job features so it reflects current memberships and saved ranks.
  • Fixed an issue where dispatch navigation could select a different incident instead of the incident chosen on the tablet or radio.

Other Changes

  • Improved printer settings with grouped paper, ink, placement and access controls, and increased the default ink capacity and refill amount to 1,200.
  • Fixed an issue where a printer could reappear after its location was changed or removed while its model was still loading.
  • Improved the Sky printer model and its paper and ink indicators, including the appearance of its distant model.
  • Fixed an issue where invoices with no item lines could fail to display.
  • Improved multiline settings so saved line breaks are preserved and long settings use the correct length limit.
  • Improved location editing so long catalogs remain usable and optional courtroom displays can be added individually.
  • Fixed an issue where cancelling placement could interfere with the free-camera controls.
  • Improved tablet forms and document signatures so controls remain usable inside dialogs and scale with the tablet at different screen resolutions.
  • Improved document signatures to display public-defender and custom role names correctly, and added support for custom spacing in free-layout legal documents.
  • Updated the default camera app access list to include DOJ organizations.
  • Updated translations for bodycam recordings, printers, organization ranks and job settings, including the missing DOJ configurator language packs.
  • Fixed an issue where older CCTV videos without an upload ID could not be shared or opened as shared recordings.

Changed Files

  • sky_jobs_base/config/config.lua
  • sky_jobs_base/config/printers.lua
  • sky_jobs_base/config/inventory/README.md
  • sky_jobs_base/config/inventory/items_ox.lua
  • sky_jobs_base/config/inventory/printer_ink.png
  • sky_jobs_base/config/locales/*
  • sky_jobs_base/fxmanifest.lua
  • sky_jobs_base/import.sql
  • sky_jobs_base/stream/sky_printer_01.ydr
  • sky_jobs_base/stream/sky_printers.ytyp
  • sky_jobs_base/source/* — delete and reinsert
Update InstructionsWhat to copy, what to keep and what to check1.45.01.46.0

Simplified update

Update sky_jobs_base safely

Read the complete update instructions in one continuous guide.

  1. Prepare the update

Back up the server KVP database (db/<sv_kvsName>) as well as SQL. Printer supplies now use that storage. Keep stable printer IDs, owning resource names and KVP data when moving servers.

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_jobs_base 1.45.0 → 1.46.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.46.0 package. Delete the old sky_jobs_base/source/ directory completely and insert the new directory. Replace sky_jobs_base/fxmanifest.lua from the same package. Refresh the entire sky_jobs_base/config/locales/ tree and merge your custom translations back. Include all nested job-configurator locale folders. Copy stream/sky_printer_01.ydr and stream/sky_printers.ytyp, import.sql, config/inventory/README.md, config/inventory/items_ox.lua and config/inventory/printer_ink.png. Merge config/config.lua and config/printers.lua as described here; preserve webhooks and other provider secrets. A full server restart loads the new streams, schema and consumers together.

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.

The complete executable Config.Cctv block before the update, with comments omitted only for readability:

Config.Cctv = {
    allowedJobs = { "police", "ambulance", "fire" },
    requireBodycamItem = false,
    bodycamItem = "bodycam",
    bodycamRecorderEnabled = true,
    recordBitrateKbps = 1500,
    bodycamViewJobs = nil
}

The new shipped block:

Config.Cctv = {
    allowedJobs = { "police", "ambulance", "fire", "doj" },
    requireBodycamItem = false,
    bodycamItem = "bodycam",
    bodycamRecorderEnabled = true,
    recordBitrateKbps = 1500,
    recordMaxSizeMb = 32,
    bodycamViewJobs = nil
}

Exact changes: Cctv.allowedJobs adds "doj" to the supplied array, and Cctv.recordMaxSizeMb is new with default 32 decimal MB. Preserve actual custom job/group names and custom visibility rules; add DOJ only when wanted. A nil allowlist still uses the existing police/ambulance fallback, so leaving it nil does not automatically add Fire or DOJ.

Cctv.recordBitrateKbps remains 1500, but is now the requested bitrate: the recorder lowers it when required to keep the rolling window within the upload budget. Match recordMaxSizeMb to the real media-provider maximum. Keep any custom recordBufferMinutes; this release does not add that key to the shipped public block, and the runtime's default rolling window remains five minutes. Existing recording enable/item/visibility choices remain valid.

Managed path when Config.UseIngameConfigurator = true: /jobconfig → Jobs Base → Tablet & Apps, with Allowed jobs, Video bitrate (kbit/s) and Maximum video upload (MB). Exact managed keys are Cctv.allowedJobs, Cctv.recordBitrateKbps, Cctv.recordMaxSizeMb.

If a custom configuration contains the obsolete bodycamSaveKey, remove it. The player action is Save bodycam in the radial menu.

Managed configuration, imports and file-only values

  • With Config.UseIngameConfigurator = true, stored /jobconfig overrides remain authoritative. Defaults can change only where there is no saved override; editing a public file alone does not replace a saved override. Review the new upload limit and camera allowlist in Jobs Base's configurator.
  • Shared policy managed since 1.44.0, including civilian use, carry, restraints/search and NUI image choices, remains managed there. This release does not change their defaults; preserve them rather than re-entering them unnecessarily.
  • Use /jobconfigimport sky_jobs_base only when you intentionally want to import the edited file configuration into the stored configurator state. Back up saved settings first. This command explicitly imports the file configuration; it is not required to reset existing overrides.
  • To continue managing shared settings in files, set Config.UseIngameConfigurator = false and maintain the file changes above. Bootstrap settings, configurator access/permission configuration and provider credentials remain file-based.
  • config/webhooks.lua and provider secrets have no diff in this range. Preserve their working values; do not replace secrets with defaults. Bodycam uploads still need the existing configured media provider. No new secret or webhook key is introduced.
  • Config.Printers below is file-based shared printer configuration. Per-job printerSettings and printers are separate job-configurator data and can override those shared defaults.

config/printers.lua — shared printer defaults and models

Old exact changed values:

inkCapacity = 100,
inkRefillAmount = 100,
models = {
    { model = "prop_printer_01", class = "office" },
    { model = "prop_printer_02", class = "office" },
    { model = "v_res_printer", class = "standard" },
    { model = "v_ret_gc_print", class = "standard" },
    { model = "prop_copier_01", class = "professional" },
    { model = "v_med_cor_photocopy", class = "professional" },
},

Complete new shared block, preserving shipped defaults:

Config.Printers = {
    enabled = true,
    resources = {
        sky_ambulancejob = true,
        sky_policejob = true,
        sky_mechanicjob = true,
        sky_dojjob = true,
        sky_firejob = true,
    },
    secondsPerDocument = 6.0,
    documentAppearance = { leftImage = "", rightImage = "", watermark = "" },
    queueEnabled = true,
    inkEnabled = false,
    inkCapacity = 1200,
    inkPerDocument = 1,
    inkRefillItem = "printer_ink",
    inkRefillAmount = 1200,
    queueTimeoutSeconds = 60,
    jamChance = 0.08,
    maintenanceTimeoutSeconds = 45,
    models = {
        { model = "sky_printer_01", class = "office" },
        { model = "prop_printer_01", class = "office" },
        { model = "prop_printer_02", class = "office" },
        { model = "v_res_printer", class = "standard" },
        { model = "v_ret_gc_print", class = "standard" },
        { model = "prop_copier_01", class = "professional" },
        { model = "v_med_cor_photocopy", class = "professional" },
    },
}

Merge into custom blocks instead of overwriting their resource allowlists, stationery or models. inkEnabled remains false by default. queueTimeoutSeconds remains 60; it now measures extra active printing time and pauses during FIFO waiting, missing supplies and jams. It is not a grace period that deletes a blocked job while a player obtains paper.

Per-job printer configuration and existing saved overrides

Use /jobconfig → owning job resource → Jobs → relevant job → Printers. Printer settings are grouped into paper and ink; per-printer sections cover printing/access and model/placement. Persisted explicit values are not silently reset by new shared defaults.

Exact keyPrevious stateNew state and operator action
printerSettings.inkCapacityShared default 100; a saved explicit override may be 100 or custom.Shared fallback 1200. Change the saved per-job value to 1200 only if desired; otherwise its custom value remains valid.
printerSettings.inkRefillAmountShared default 100; a saved explicit override may be 100 or custom.Shared fallback 1200. Match the desired cartridge amount in the saved per-job setting.
printers[i].deleteCopiesAfterRestartAbsent.New boolean, default false. Set true only for printers whose uncollected ready copies should be cleared when the service starts.
printers[i].remoteEnabledBoolean, default false; the old professional class default was true.Removed/ignored by normalization. Delete it from file-imported custom entries and use a persistent nearby printer.
printers[i].temporaryAllowedBoolean, default false.Removed/ignored by normalization. Delete it from file-imported custom entries and use a persistent configured printer.

The new field belongs inside the existing printer entry; no replacement table or coordinate is required:

deleteCopiesAfterRestart = false,

false preserves uncollected ready copies. true clears ready output only, not already collected documents or unrelated rows. The startup cleanup is applied when Jobs Base or the registered output owner starts. Saving normal configuration and merely disabling/re-enabling the printer do not repeatedly purge ready copies. The current matching DOJ consumer supports the same policy; older DOJ consumers do not (see compatibility).

For a new native printer, select Sky printer from the job location catalog. Its origin is at the bottom of the prop: place that origin on the table/surface. To reuse an MLO/existing object, choose Select existing printer, aim at the printer, confirm with Enter or cancel with Escape, then save the job settings. Selection captures model, position and heading and sets spawnProp = false; it does not move or duplicate the existing world object. Existing custom models/no-spawn locations remain valid. The new world paper/ink indicators apply to sky_printer_01 only.

Custom integrations and DOJ compatibility

Custom integrations using the removed GetAvailableRemotePrinters, CreateTemporaryPrinter or RemoveTemporaryPrinter APIs must use persistent configured nearby printers. Current DOJ packages that register their printer output storage require Jobs Base 1.46.0. Older DOJ packages can keep their existing printer workflow but do not implement the new ready-copy restart cleanup. Install a matching DOJ consumer only when using its new feature set; this release set does not introduce a new DOJ version.

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

Printer supplies and restarts

Paper and ink now persist by the owning config resource and stable printer ID in FiveM resource KVP storage. New printers, or printers without a saved stock entry on the first upgraded run, start at zero for enabled supplies and must be filled. Old volatile stock cannot be recovered retroactively. Existing KVP entries survive normal resource/server restarts; copying only SQL to another server is insufficient. Keep the server's KVP data and stable names/IDs. FIFO jobs, maintenance sessions and jams are still runtime state rather than a promise that in-flight work resumes after a server restart.

SQL and inventory

Apply these two additive schema changes while retaining existing data. They inherit the active database character set and collation.

  • With Config.AutoExecuteQuery = true, the normal automatic migration creates sky_jobs_organization_roles and adds sky_jobs_gallery.is_deleted; let migration complete before testing features.
  • With Config.AutoExecuteQuery = false, the automatic schema path is skipped. Back up the database and apply these changes manually before starting the new code.

New complete table:

CREATE TABLE IF NOT EXISTS `sky_jobs_organization_roles` (
    `organization` VARCHAR(64) NOT NULL,
    `grades` LONGTEXT NOT NULL,
    PRIMARY KEY (`organization`)
) ENGINE=InnoDB;

Check the existing gallery before adding the column:

SHOW COLUMNS FROM `sky_jobs_gallery` LIKE 'is_deleted';

If that returns no column, run:

ALTER TABLE `sky_jobs_gallery`
    ADD COLUMN `is_deleted` TINYINT(1) NOT NULL DEFAULT 0;

The updated import.sql contains the new column in its fresh table definition. Running CREATE TABLE IF NOT EXISTS against an existing gallery does not add the column, so that alone is not a manual upgrade. No SQL item insertion, data wipe, membership reset or permission-ID migration is required by these changes.

Independent organization grades are initialized from their configured grades/current framework catalog where available, otherwise member/boss defaults, and stored independently in the new table. This does not require changing a player's primary job. These organization ranks do not create framework salary payments. Review rank permissions after intentional edits; keep existing membership grants.

Inventory item and image

Servers using ink consumption must register the configured item. The new supplied entry in sky_jobs_base/config/inventory/items_ox.lua is:

["printer_ink"] = {
    label = "Druckerpatrone", weight = 200, stack = true, close = true, consume = 0,
    description = "Ersatzpatrone zum Nachfüllen eines Druckers.",
    client = { image = "printer_ink.png" },
},

For ox_inventory, merge this entry into ox_inventory/data/items.lua, copy sky_jobs_base/config/inventory/printer_ink.png to ox_inventory/web/images/printer_ink.png, then restart the inventory/server through the normal deployment process. Labels/descriptions may be translated for the server. If printerSettings.inkRefillItem/Config.Printers.inkRefillItem is customized, register that actual name and use its intended image instead.

For another supported inventory, add the equivalent stackable cartridge item without automatic use consumption. Jobs Base removes the cartridge after successful maintenance, so the inventory must not also consume it on use. Existing job_document and printer_paper definitions/images are unchanged in this range. A fresh install should merge all supplied entries and copy all three matching images; an update from 1.45.0 only introduces the ink entry/image. job_document must remain nonstackable with document metadata and consume = 0.

Bodycam retention and provider requirements

Bodycam Save requires the enabled recorder, an available buffered recording and the permitted active job/duty; the optional bodycam item requirement remains enforced. Use the existing configured media upload provider and keep its credentials. recordMaxSizeMb is a decimal limit, not an uploaded file guarantee; oversized output or provider rejection is shown as an error.

Sharing accepts bodycam recordings and supported legacy cctv video URLs, not arbitrary gallery photos or camera-folder videos. Gallery removal hides the recording from that owner's normal list while retaining accepted sharing/evidence references and media. Removing from the gallery is therefore not revocation. Revoke shares separately first if recipients must lose access; the UI confirmation explains this behavior. Removing a recording from the gallery does not free media storage or delete evidence that has already been accepted.

  1. Restart and verify

Start Base 1.43.0, Jobs Base 1.46.0 and the matching consumers after their dependencies. Check manifest versions, startup errors and migration completion. Refill enabled supplies for printers with no saved stock, then verify stock after a restart. Check a Sky printer and an existing world printer, queue waiting, a jam and collection of ready output. Verify an independent organization’s facilities and saved ranks if used.

Save a buffered bodycam recording through the radial menu, open it from the bodycam gallery and test authorized sharing. Removing a shared recording from the owner’s gallery does not revoke recipients’ access; revoke its shares separately if access must end. Confirm the configured upload limit matches the real media provider.

Version 1.45.0

Update sky_base to 1.42.0, then sky_jobs_base to 1.45.0, then the installed matching job releases: Ambulance 2.41.0, Police 1.34.0, Mechanic 1.31.0, Fire 1.13.0 and Crime 0.5.0.

Highlights

  • Added shared record browsing and document previews for the matching Police, Ambulance, Mechanic and Fire releases without requiring DOJ.
  • Added printable job records with collectible inventory copies that retain their original content after later record edits.
  • Added free camera movement while placing Creator and Job Configurator objects with the placement gizmo.
  • Added editable duty-card background images that can be replaced or extended for custom jobs without rebuilding the interface.

Notable Changes

  • Added custom radio-channel names and a radio-position reset that keeps the handset within the screen after resizing.
  • Added configurable document logos and watermarks for individual jobs while retaining consistent record layouts.
  • Changed record sharing to use explicit document recipients while retaining job-level sharing rules for training courses and qualifications.
  • Improved management logs with pages of 50 entries and searching and sorting across the stored history.
  • Improved shared record updates so open lists stay current, drafts are retained and outdated sharing edits cannot silently replace newer recipients.
  • Fixed an issue where mapped on-duty jobs could be treated as off duty during salary calculations.
  • Fixed an issue where a zero salary could inherit framework pay or later produce catch-up payments for previously unpaid work.
  • Fixed an issue where rank normalization could collide with obsolete permission rows and leave role permissions or member grades only partly updated.
  • Fixed shared storage so warehouse access is checked before reading, depositing or withdrawing stock.
  • Fixed an issue where carried-item withdrawals and differently capitalized weapon names could bypass role restrictions.
  • Improved open shared storage so role changes refresh restrictions or close the window when access is revoked, preserving selection and quantities while access remains.
  • Improved organization recruitment so the matching Crime admission requirements also apply to direct recruitment and accepted invitations.

Other Changes

  • Optimized configuration, Creator, printer, map and Dispatch updates to avoid resending unchanged data.
  • Improved the configurator so changing editor pages preserves confirmed saves and resource restarts discard outdated editor sessions.
  • Improved shared tablet controls with consistent editable tags, explicit 24-hour time entry and readable public-form sizing on larger displays.
  • Fixed an issue where shared dropdown menus could appear behind dialogs.
  • Changed off-duty ping and panic actions to remain silent while still enforcing duty requirements.
  • Improved Fire and Mechanic billing receipts with a shared layout and the configured currency format.
  • Updated configurator translations and editors for Fire billing, Crime reputation rewards, Police case numbering and optional registers, and DOJ courtroom settings.
  • Fixed an issue where an unsupported job-language pack could interrupt shared locale loading.

Changed Files

  • sky_jobs_base/config/config.lua
  • sky_jobs_base/config/locales/*
  • sky_jobs_base/config/printers.lua
  • sky_jobs_base/config/inventory/items_ox.lua
  • sky_jobs_base/config/inventory/job_document.png
  • sky_jobs_base/config/inventory/printer_paper.png
  • sky_jobs_base/config/inventory/README.md
  • sky_jobs_base/config/images/duty/README.md
  • sky_jobs_base/config/images/duty/card_ambulance.webp
  • sky_jobs_base/config/images/duty/card_doj.webp
  • sky_jobs_base/config/images/duty/card_fib.webp
  • sky_jobs_base/config/images/duty/card_fire.webp
  • sky_jobs_base/config/images/duty/card_mechanic.webp
  • sky_jobs_base/config/images/duty/card_police.webp
  • sky_jobs_base/config/images/duty/card_sheriff.webp
  • sky_jobs_base/config/images/duty/card_swat.webp
  • sky_jobs_base/config/images/duty/card_tuner.webp
  • sky_jobs_base/fxmanifest.lua
  • sky_jobs_base/import.sql
  • sky_jobs_base/source/* — delete and reinsert

Removed Files

  • sky_jobs_base/config/locales/jobconfigurator/sky_mechanicjob/hu.lua
Update InstructionsWhat to copy, what to keep and what to check1.44.01.45.0

Simplified update

Update sky_jobs_base safely

Read the complete update instructions in one continuous guide.

  1. Prepare the update

Update sky_base to 1.42.0, then sky_jobs_base to 1.45.0, then the installed matching job releases: Ambulance 2.41.0, Police 1.34.0, Mechanic 1.31.0, Fire 1.13.0 and Crime 0.5.0. These instructions cover 1.44.0 → 1.45.0; complete older migrations first. Stop the server and back up the resources, customized files, database and saved configurator/Creator data.

  1. Replace the package files

Install the matching 1.45.0 package. Replace every Changed Files path, delete and reinsert sky_jobs_base/source/*, and replace sky_jobs_base/config/locales/* completely. Explicitly remove sky_jobs_base/config/locales/jobconfigurator/sky_mechanicjob/hu.lua if copying over the old directory. Merge public configuration as described in this view.

The delivered sky_jobs_base/config/locales/* includes the new Nui.storage.errors.noAccess message and corrected Nui.management.roles.permissionOptions.weaponHint wording. Keep the generated UI, runtime source and locales from the same release.

Replace source/* and fxmanifest.lua from the same download even if optional diagnostics remain off. The profiler may change Lua inside source/ and the generated manifest; public configuration and integration files must match the clean source. If an older profiler package changed public files, restore those files once from the clean new package and merge your own changes. Keep customized configuration, writable data and private provider credentials backed up.

  1. Merge configuration

Jobs Base configuration ownership: in sky_jobs_base/config/config.lua, keep your existing Config.UseIngameConfigurator choice. true uses shipped defaults plus saved /jobconfig overrides for managed shared policy, including Config.CivilianUse, Config.PlayerCarry, restraints, searching and NUI image sources. false opts out and keeps these values file-based. To migrate your customized managed file values deliberately, keep those values in the file, use true, restart during maintenance and run /jobconfigimport sky_jobs_base, then check Jobs Base in /jobconfig. Do not import a stock file over wanted saved settings. The switch, command permissions, bootstrap job-group choices, callbacks and config/webhooks.lua provider credentials remain file-based; this release does not change their values or introduce new secrets.

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.

Radio channel names: add label = "" to each existing channel in Config.Dispatch.centers[*].channels in sky_jobs_base/config/config.lua. The field was absent; an empty string preserves the standard translated name or channel ID. A nonempty label supplies your display name and does not change the channel ID. In /jobconfig → Jobs Base, the setting key is Dispatch, nested path centers[*].channels[*].label; saved Dispatch overrides remain in effect. Edit the matching centers by their id, keeping custom channels, staffing and IDs. The shipped channel lists are:

-- Existing center id = "central_dispatch": replace only its channels field.
channels = {
    { id = "POLICE_MAIN", label = "", shortLabel = "POL" },
    { id = "SHERIFF_MAIN", label = "", shortLabel = "SHF" },
    { id = "EMS_MAIN", label = "", shortLabel = "EMS" },
    { id = "FIRE_MAIN", label = "", shortLabel = "FIR" },
    { id = "DISPATCH_MAIN", label = "", shortLabel = "CMD" }
},

-- Existing center id = "ems_dispatch": replace only its channels field.
channels = {
    { id = "EMS_MAIN", label = "", shortLabel = "EMS" },
    { id = "FIRE_MAIN", label = "", shortLabel = "FIR" },
    { id = "DISPATCH_MAIN", label = "", shortLabel = "CMD" }
},

Printers and stationery: in the existing sky_jobs_base/config/printers.lua, add sky_mechanicjob = true to Config.Printers.resources (previously absent) and the complete new Config.Printers.documentAppearance table below. Place these assignments after the existing Config.Printers table when copying them directly:

Config.Printers.resources.sky_mechanicjob = true
Config.Printers.documentAppearance = {
    leftImage = "",
    rightImage = "",
    watermark = ""
}

These global printer values remain file-based. For an individual job, /jobconfig → that job → Document images (documentAppearance) overrides leftImage, rightImage and watermark; each value is an HTTP(S) image URL of at most 2,048 characters. Existing explicit job overrides are retained. Blank global values leave the reserved image areas empty. The document layout is fixed. Do not replace the whole printer configuration with this small addition.

Record sharing changes: Config.Sharing.enabled, Config.Sharing.maxTargetsPerRule and each job's sharing section now govern training courses and qualifications only. The old sharing.records and sharing.links blocks are ignored for records; they may be removed from customized job definitions after backing them up. Set recipients on each saved record using Share. Existing explicit record grants are preserved, but old job-wide record rules no longer authorize or block a recipient. App access, duty, classification and rank clearance still apply. No automatic grant is created just because a job is registered, and receiving a document never grants edit access to the source record.

Explorer and printing: the matching Police, Ambulance, Mechanic and Fire releases use the common Explorer and document services without DOJ. Install those matching job packages; each job owns its Explorer switch and record permissions. Records already exist in their original stores, so no re-creation or bulk import is needed. Authorized recipients browse shared records by issuing job and can search them. Printed copies capture the saved record when the printer produces them; subsequent edits or revoked digital access do not change a collected paper copy. Owners of the physical item can read that copy. Printing needs a configured accessible station printer, the inventory update and SQL below. Existing printer locations do not need to be recreated. For a job without a printer, add one in /jobconfig → job → Locations and review its printerSettings for paper/ink requirements.

Salary and ranks: a stored salary of 0 now means no salary, rather than falling back to the framework amount. Review ranks that deliberately used zero; time worked while their salary was zero will not become a later catch-up payment. Correctly owed payments from insufficient society funds remain owed. There is no salary or grade schema migration. If an earlier failed rank remap already left negative temporary grades, preserve that data and restore the original mapping with support; this update cannot infer that mapping and is not a data reset.

Optional performance diagnostics: extra profiler information stays disabled by default. To make a support recording, place 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 until profiler status reports completion, then run profiler saveJSON sky-release-profile.json. Share the file only when requested by support. To turn the extra information off, set setr sky_profiler 0 and restart again. This is not a /jobconfig setting; enabling it neither starts a recording nor uploads data automatically.

  1. Apply data and inventory updates

Database: with the effective Jobs Base AutoExecuteQuery setting enabled, startup installs the three new InnoDB tables below. With automatic migrations disabled, run this complete SQL against the backed-up existing database before starting Jobs Base. It is the new schema from sky_jobs_base/import.sql; no existing table is reset. sky_jobs_record_shares stores recipients, sky_jobs_record_share_state protects concurrent sharing changes, and sky_jobs_printed_documents retains physical copies. Preserve all three tables and existing record data. /jobconfig does not install SQL.

-- Immutable paper copies of job records; no dependency on DOJ tables.
CREATE TABLE IF NOT EXISTS `sky_jobs_record_shares` (
    `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
    `provider` VARCHAR(64) NOT NULL,
    `owner_job` VARCHAR(64) NOT NULL,
    `record_id` VARCHAR(128) NOT NULL,
    `source_key` VARCHAR(191) NOT NULL,
    `recipient_job` VARCHAR(64) NOT NULL,
    `title` VARCHAR(255) NOT NULL,
    `reference` VARCHAR(128) NOT NULL,
    `citizen_ids` LONGTEXT NOT NULL,
    `vehicle_plates` LONGTEXT NOT NULL,
    `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (`id`),
    UNIQUE KEY `uniq_record_share` (`provider`, `owner_job`, `record_id`, `recipient_job`),
    KEY `idx_record_share_recipient` (`recipient_job`, `provider`, `owner_job`)
) ENGINE=InnoDB;

CREATE TABLE IF NOT EXISTS `sky_jobs_record_share_state` (
    `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
    `provider` VARCHAR(64) NOT NULL,
    `owner_job` VARCHAR(64) NOT NULL,
    `record_id` VARCHAR(128) NOT NULL,
    `source_key` VARCHAR(191) NOT NULL,
    `revision` BIGINT UNSIGNED NOT NULL DEFAULT 0,
    `mutation_id` CHAR(36) NULL,
    PRIMARY KEY (`id`),
    UNIQUE KEY `uniq_record_share_state` (`provider`, `owner_job`, `record_id`, `source_key`)
) ENGINE=InnoDB;

CREATE TABLE IF NOT EXISTS `sky_jobs_printed_documents` (
    `id` CHAR(36) NOT NULL,
    `printer_id` VARCHAR(191) NOT NULL,
    `issued_by_identifier` VARCHAR(128) NOT NULL,
    `snapshot_json` LONGTEXT NOT NULL,
    `metadata_json` LONGTEXT NOT NULL,
    `pickup_state` VARCHAR(16) NOT NULL DEFAULT 'printing',
    `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (`id`),
    KEY `idx_job_document_output` (`printer_id`, `issued_by_identifier`, `pickup_state`, `created_at`, `id`)
) ENGINE=InnoDB;

Inventory item: printing needs an inventory provider that supports per-item metadata and the non-stackable item job_document. Install the definition from sky_jobs_base/config/inventory/items_ox.lua and the image sky_jobs_base/config/inventory/job_document.png in the active inventory. The same package directory contains printer_paper.png and an installation README. For ox_inventory, merge this entry into ox_inventory/data/items.lua and copy the image 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" },
},

For other supported inventories, register the equivalent unique, usable, non-stackable item and install its image in that inventory's image folder; retain item metadata when transferring it. The runtime registers the usable action and preserves an existing item definition. A metadata-less inventory cannot print these copies; adding an icon alone does not enable metadata support. Existing printer_paper and printer_ink items remain required only where paper or ink consumption is enabled.

Duty-card images: install all nine listed sky_jobs_base/config/images/duty/card_*.webp images. Their old source location was bundled into the UI, so there is no customer-side old path to rename. To customize a card, replace its file or add card_<technical_job_name>.webp or .png; use lowercase names with spaces replaced by underscores. Lookup tries the on-duty job name, its group, then optional employee_card, with WebP before PNG. Without an image the card still works. Restart Jobs Base after image changes. No new stream models are required.

Providers and secrets: retain your server-only config/webhooks.lua credentials and existing inventory/media-provider configuration. There is no new credential or external-provider file to merge in this release. Printing and document imagery are separate from /jobconfig data imports. External ESX paycheck customizations are not automatically replaced by this resource update; if your server customizes framework payroll, keep its existing ownership integration and test one Sky-paid and one framework-paid job.

  1. Restart and verify

Restart the database, framework and edited inventory first, then Base 1.42.0, Jobs Base 1.45.0 and the matching job resources. Use a full server restart for the Police permission-ID correction; reselect Police Manage offences (2401) on the intended ranks and units without changing Ambulance's 2101 grants. Confirm the versions and resolve SQL/locale errors before admitting players.

Open /jobconfig, save a radio label, reopen it and confirm the effective setting. Verify a duty card, radio reset and a placement save/cancel. Test Explorer with an authorized and restricted rank; share a record, read it from the recipient job, revoke the grant and confirm digital access disappears. Print a saved record, collect and transfer its job_document item, and verify the original paper content remains readable after the source changes. Test two simultaneous sharing editors for a conflict without draft loss. Check a zero-salary rank and a normal paid rank at an actual payday. Do not treat a package build as proof of these live checks.

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.

Version 1.44.0

Update Base to 1.41.0 before Jobs Base 1.44.0. Use the matching installed job releases: Ambulance 2.40.0, Police 1.33.0, Mechanic 1.30.0, Fire 1.12.0 and Crime 0.4.0.

Highlights

  • Added a Jobs Base section in the in-game Job Configurator for shared settings such as duty, Dispatch, tablet access, garages and player interactions.
  • Added configurable roleplay registers with custom fields and additional record-clearance levels for individual job ranks.
  • Added station printer placement for Police, Ambulance, Fire and DOJ, including interaction points for printers already built into an interior.
  • Added a separate archive for completed public forms, keeping archived submissions readable while preventing further status and note changes.

Notable Changes

  • Improved configuration saves and imports so changes take effect after they are saved successfully and update the affected active interfaces and interactions.
  • Added an explicit import command for transferring existing Jobs Base file settings into the in-game configurator.
  • Improved the configurator with a system overview, focused settings pages, expandable entries and clearer inventory-image choices.
  • Improved support exports and configuration history by hiding recognized credentials, including webhook URLs, while retaining private values when redacted settings are imported.
  • Added printer queues, optional paper and ink consumption, and interactive maintenance for refilling supplies and clearing paper jams.
  • Added an output-tray interaction for collecting printed documents even when the printer is offline or out of paper.
  • Added independent switches for helicopter night vision and thermal vision, with normal vision always available.
  • Added an action for clearing ended calls from the current Dispatch queue while keeping their history and linked incidents.
  • Improved public-form lists with pages of 50 entries and searching across the full archive.
  • Fixed an issue where job vehicles could give a player duplicate vehicle keys.
  • Fixed an issue where vehicle occupants could be pulled out through closed intact doors or while a supported seatbelt or harness was fastened.
  • Fixed an issue where a secondary criminal organization could retain access to its tablet tools while the player was on duty for another job.
  • Fixed an issue where garage cleanup could fail after AdvancedParking had already removed the corresponding parking record.

Other Changes

  • Improved shop baskets so changing quantities keeps products in the order they were added.
  • Fixed an issue where advanced drug-test records could show an effect description instead of the substance name.
  • Fixed an issue where the configurator could continue displaying outdated resource-version results.
  • Fixed an issue where reloading a packaged tablet page could lose its route.
  • Optimized shared job settings and interaction checks to reduce unnecessary server work during normal play.
  • Optimized workshop stock checks to reduce server work when viewing required materials.
  • Optimized colleague-map updates to reduce unnecessary server work while tracking colleagues.
  • Improved translation coverage for shared settings, Fire controls, Crime configuration and the Slovenian vehicle register.
  • Removed the misleading location interaction switch that could not retain a saved value.
  • Improved workshop deletion checks so unpaid tuning orders must be resolved before their workshop can be removed.

Changed Files

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

Simplified update

Update sky_jobs_base safely

Read the complete update instructions in one continuous guide.

  1. Prepare the update

Update Base to 1.41.0 before Jobs Base 1.44.0. Use the matching installed job releases: Ambulance 2.40.0, Police 1.33.0, Mechanic 1.30.0, Fire 1.12.0 and Crime 0.4.0. These instructions cover 1.43.1 → 1.44.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.44.0 download. Update every path in Changed Files, delete and reinsert sky_jobs_base/source/*, and replace sky_jobs_base/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

Choose how Jobs Base settings are managed before the first start. Previously the shared values came from sky_jobs_base/config/config.lua. The new Config.UseIngameConfigurator = true uses shipped defaults plus saved overrides. Your customized managed file values are not automatically imported.

  • To continue using your files, add Config.UseIngameConfigurator = false at the top of config/config.lua, merge the new values below and restart. Saved configurator overrides remain stored for later use.
  • To move to the in-game editor, keep your customized values in config/config.lua, set Config.UseIngameConfigurator = true, and start the updated resources during maintenance. Run /jobconfigimport sky_jobs_base with the same permission used for /jobconfig, then open /jobconfig → Jobs Base and verify the imported values before admitting players. Later file edits require another resource restart before the import reads them. Do not import a stock file over settings you want to keep.

This release brings shared civilian actions, carrying, restraints, searches and inventory-image sources into the Jobs Base configurator. With the switch enabled, edit those managed values there. The switch itself, Config.CommandPermissions, bootstrap job-group selection, Lua callbacks, editor metadata and config/webhooks.lua remain file-based. Keep API keys and webhook URLs in their existing server-only file. Changing command permissions or the bootstrap switch requires a restart. Recognized secrets are hidden in support exports, but review an export before sharing it.

In sky_jobs_base/config/config.lua, add these new values without replacing your existing surrounding tables:

PathPrevious stateNew shipped value / setting
Config.UseIngameConfiguratorAbsenttrue; choose the migration mode above.
Config.MenuColorAbsent"#1DD1CE"; Jobs Base setting MenuColor.
Config.Tablet.apps.forms_archiveAbsenttrue; Jobs Base Tablet → apps → forms_archive.
Config.Dispatch.radioKeybindFixed default in the radio setup"F10"; Jobs Base Dispatch → radioKeybind. Player key rebindings remain personal.
Config.HeliCam.visionModesBoth modes availableThe complete block below; Jobs Base HeliCam → visionModes.
Config.RecordAccessAbsentThe complete block below; Jobs Base → Organization → Record access.
Config.RegistriesAbsentThe complete block below; Jobs Base → Organization → Registries.

Config.PlayerSearch.durationMs = 8000 and scenario = "CODE_HUMAN_POLICE_INVESTIGATE" have comment clarifications only. A complete configured animation still takes priority over the scenario. Existing job settings and stored overrides are retained; an untouched setting can follow a new shipped default.

Config.MenuColor = "#1DD1CE"
Config.Tablet.apps.forms_archive = true
Config.Dispatch.radioKeybind = "F10"

Config.HeliCam.visionModes = {
        nightVision = true, -- Allow night vision when cycling camera modes.
        thermal = true -- Allow thermal vision; normal vision always remains available.
    }

Config.RecordAccess = {
    defaultLevel = 1,
    levels = {
        { level = 1, label = "Level 1" },
        { level = 2, label = "Level 2" },
        { level = 3, label = "Level 3" },
        { level = 4, label = "Level 4" },
        { level = 5, label = "Level 5" },
    },
    gradeRules = {},
}

Config.Registries = {
    definitions = {},
}

Place these assignments after their existing parent tables if merging by copy/paste. Record clearance adds a requirement to existing job/sharing access; it does not grant access on its own. Rank rules use an exact framework job and numeric grade, for example { job = "police", grade = 4, level = 3 } inside Config.RecordAccess.gradeRules. Keep register keys stable: disabling or removing a definition retains its records, and restoring the same key restores access. Native DOJ registers remain owned by DOJ; legacy shared definitions are migrated once, not deleted.

Printers: add the complete new sky_jobs_base/config/printers.lua from the download. All of these global values were absent before:

Config.Printers = {
    enabled = true,
    resources = {
        sky_ambulancejob = true,
        sky_policejob = true,
        sky_dojjob = true,
        sky_firejob = true,
    },
    secondsPerDocument = 6.0,
    -- Defaults for jobs without an explicit printerSettings override.
    queueEnabled = true,
    inkEnabled = false,
    inkCapacity = 100,
    inkPerDocument = 1,
    inkRefillItem = "printer_ink",
    inkRefillAmount = 100,
    -- Extra time for a blocked head job (empty supplies / paper jam).
    queueTimeoutSeconds = 60,
    -- Only applies with paperEnabled. Set jamChance to 0 to disable random jams.
    jamChance = 0.08,
    maintenanceTimeoutSeconds = 45,
    models = {
        { model = "prop_printer_01", class = "office" },
        { model = "prop_printer_02", class = "office" },
        { model = "v_res_printer", class = "standard" },
        { model = "v_ret_gc_print", class = "standard" },
        { model = "prop_copier_01", class = "professional" },
        { model = "v_med_cor_photocopy", class = "professional" },
    },
}

The resource allowlist, model list, print duration, jam chance and maintenance timeout remain global file settings. Per-job choices belong to /jobconfig → the installed Police, Ambulance, Fire or DOJ resource → job → Printers (printerSettings). Add a physical or Interior printer under that job's Locations → station → + Add. Interior printers add an interaction point without spawning another prop. Existing legacy printer positions remain available; their paper settings are moved into the job's printerSettings.

New per-job defaults are queueEnabled = true, inkEnabled = false, inkCapacity = 100, inkPerDocument = 1, inkRefillItem = "printer_ink" and inkRefillAmount = 100. Paper defaults are paperEnabled = false, paperCapacity = 100, refillItem = "printer_paper" and refillAmount = 25. Existing explicit values take precedence. With queues disabled, busy printers reject new jobs. Paper-enabled printers start empty; random jams only apply when paper is enabled. Paper, ink, jams and waiting jobs are runtime state, while locations are saved.

Printer infrastructure does not add printing to every job's forms or records. A compatible document-producing resource is required; the implemented document flow is provided by the matching DOJ resource. Crime is not enabled in the default printer allowlist.

After migration, shared configuration saves apply to the affected running systems. Login rules affect the next login, payment settings affect the next payment, and personal keybindings are not overwritten. Vehicles already outside a garage retain the provider they were spawned with; keep that provider running until they are returned. Phone-app replacement is supported on LB, LB Unique and Sky Phone; do not assume other phone launchers can update their icons while running.

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

With the effective AutoExecuteQuery setting enabled, startup applies the new schema. If you keep automatic migrations disabled, run the following upgrade once against your backed-up existing database before starting this version. The registry_catalog_migrated column is also required on an existing configurator table; a CREATE TABLE IF NOT EXISTS statement alone does not add it.

The upgrade adds sky_jobs_configurator_settings.registry_catalog_migrated as TINYINT(1) NOT NULL DEFAULT 0, sky_jobs_dispatch_calls.cleared_at as nullable DATETIME, the idx_job_form_page index, and the new registry-record and audit tables. It retains existing forms, calls and configurator settings.

SET @sky_update_sql = IF(
    EXISTS(SELECT 1 FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'sky_jobs_configurator_settings' AND COLUMN_NAME = 'registry_catalog_migrated'),
    'SELECT 1', 'ALTER TABLE `sky_jobs_configurator_settings` ADD COLUMN `registry_catalog_migrated` TINYINT(1) NOT NULL DEFAULT 0'
);
PREPARE sky_update_statement FROM @sky_update_sql;
EXECUTE sky_update_statement;
DEALLOCATE PREPARE sky_update_statement;

SET @sky_update_sql = IF(
    EXISTS(SELECT 1 FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'sky_jobs_dispatch_calls' AND COLUMN_NAME = 'cleared_at'),
    'SELECT 1', 'ALTER TABLE `sky_jobs_dispatch_calls` ADD COLUMN `cleared_at` DATETIME NULL'
);
PREPARE sky_update_statement FROM @sky_update_sql;
EXECUTE sky_update_statement;
DEALLOCATE PREPARE sky_update_statement;

SET @sky_update_sql = IF(
    EXISTS(SELECT 1 FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'sky_jobs_public_forms' AND INDEX_NAME = 'idx_job_form_page'),
    'SELECT 1', 'CREATE INDEX `idx_job_form_page` ON `sky_jobs_public_forms` (`job`, `status`, `created_at`, `id`)'
);
PREPARE sky_update_statement FROM @sky_update_sql;
EXECUTE sky_update_statement;
DEALLOCATE PREPARE sky_update_statement;

CREATE TABLE IF NOT EXISTS `sky_jobs_registry_records` (
    `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
    `job` VARCHAR(64) NOT NULL,
    `registry_key` VARCHAR(48) NOT NULL,
    `title` VARCHAR(160) NOT NULL,
    `clearance_level` SMALLINT UNSIGNED NOT NULL DEFAULT 1,
    `fields_json` LONGTEXT NOT NULL,
    `revision` INT UNSIGNED NOT NULL DEFAULT 1,
    `archived` TINYINT NOT NULL DEFAULT 0,
    `created_by_identifier` VARCHAR(128) NOT NULL,
    `created_by_name` VARCHAR(120) NOT NULL,
    `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (`id`),
    INDEX `idx_registry_scope` (`job`, `registry_key`, `archived`, `clearance_level`)
) ENGINE=InnoDB;

CREATE TABLE IF NOT EXISTS `sky_jobs_registry_audit` (
    `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
    `record_id` BIGINT UNSIGNED NOT NULL,
    `job` VARCHAR(64) NOT NULL,
    `registry_key` VARCHAR(48) NOT NULL,
    `action` VARCHAR(24) NOT NULL,
    `actor_identifier` VARCHAR(128) NOT NULL,
    `actor_name` VARCHAR(120) NOT NULL,
    `details_json` LONGTEXT NOT NULL,
    `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (`id`),
    INDEX `idx_registry_audit_record` (`record_id`, `id`)
) ENGINE=InnoDB;

If enabling printer paper or ink, define the selected items in your inventory before use. These optional Ox Inventory entries belong inside the existing returned table in ox_inventory/data/items.lua; they are not usable medication or equipment items. Keep consume = 0, because Jobs Base removes the supply item after successful maintenance. Use your own inventory icons if desired. Other inventories need equivalent normal stackable item definitions.

["printer_paper"] = {
    label = "Printer paper", weight = 100, stack = true, close = true, consume = 0,
},
["printer_ink"] = {
    label = "Printer ink", weight = 100, stack = true, close = true, consume = 0,
},

Printer items are unnecessary while their consumption options are disabled. Existing training-role assignments are preserved when permission identifiers are changed through the configurator; do not reset the role tables. Keep existing document-item definitions supplied by your document resource.

  1. Restart and verify

Restart the database, framework and any edited inventory first, then Base, Jobs Base and the installed job resources. Confirm 1.44.0 and resolve startup errors before admitting players. Open /jobconfig, select Jobs Base and confirm your actual duty, Dispatch, interaction and tablet settings. Save one reversible setting and verify it on a connected client, then restart and confirm it remains saved. Test rank clearance, a public form moving into the archive, and clearing an ended Dispatch call. If using printers, check placement, authorized access, supplies and collection through a compatible document resource. Check one garage spawn for a single key and your supported seatbelt integration before relying on occupant-removal restrictions.

Hotfix

Version 1.43.1

The combined hotfix contains Base 1.40.1, Jobs Base 1.43.1, Mechanic 1.29.1 and Ambulance 2.39.1. Install Base and Jobs Base before the job resources you use.

Highlights

  • Fixed an issue where saving unchanged job settings could repeatedly resend location data to connected players and create unnecessary server traffic.
  • Fixed an issue where job garages overwrote a parked vehicle's saved extras with its catalog equipment defaults.

Notable Changes

  • Fixed an issue where holding a confirmation or cancellation key could immediately finish a newly started object placement in the Job Configurator.
  • Improved saved garage equipment compatibility with the active framework, including Qbox and Ox, while retaining catalog defaults for vehicles without a saved extras selection.

Other Changes

No additional changes.

Changed Files

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

Simplified update

Update sky_jobs_base safely

Read the complete update instructions in one continuous guide.

  1. Prepare the update

These instructions cover 1.43.0 to 1.43.1. Complete earlier updates first when upgrading from an older version. Stop the server and back up the resource, database, customized files and saved configurator data. Install Base 1.40.1 first. Include Mechanic 1.29.1 for the workshop fix and Ambulance 2.39.1 for the medical fixes when using those resources.

  1. Replace the runtime files

Delete the old sky_jobs_base/source folder and insert the complete replacement from the 1.43.1 package. Replace sky_jobs_base/fxmanifest.lua from the same package. Preserve configuration, locales, custom assets and persistent data outside source.

  1. Keep saved jobs and vehicles

No manual configuration values or saved /jobconfig settings change. Keep jobs, locations, permissions, catalog entries and saved vehicles. No SQL, item or locale migration is required; do not reset or reimport the database. Restore the desired extras once if a vehicle was already saved with an incorrect equipment selection.

  1. Restart and verify

Start Base before Jobs Base and job resources, then confirm Jobs Base 1.43.1. Place or move a location in /jobconfig, save and reopen it. Release the confirmation/cancellation keys before confirming a new placement. Park and retrieve a helicopter with mixed enabled and disabled extras; its saved equipment must take precedence over different catalog defaults. Check server and client logs for recurring timeout errors.

Version 1.43.0

Install Base 1.40.0 before Jobs Base 1.43.0. Use the matching job releases: Ambulance 2.39.0, Police 1.32.0, Mechanic 1.29.0, Fire 1.11.0 and Crime 0.3.0 for their shared integrations.

Highlights

  • Added shared vehicle inspection and registration records with owner signatures, document history and access for compatible Mechanic and Police tablets.
  • Added automatic recovery of destroyed job vehicles, with a configurable repair fee before they can be taken out again.
  • Added department records of successfully confiscated items and weapons for the Police tablet.
  • Added confirmed invoice and treatment income to the organization finance history for compatible job integrations.

Notable Changes

  • Fixed an issue where a staffed dispatch center could reject an authorized incident as rate limited.
  • Improved dispatch acceptance from the radio, tablet and self-dispatch list by setting a GPS waypoint after a successful assignment.
  • Changed dispatch alerts to reach the responsible on-duty responders and authorized dispatchers working an active shift.
  • Added a separate permission for paying employee bonuses without also granting general account management.
  • Fixed an issue where opening the role editor after reconnecting could incorrectly report that the player rank was too low.
  • Fixed an issue where organization members could lose access to interactions that used the wrong group identity.
  • Fixed an issue where selecting a filtered CCTV camera could open the wrong feed.
  • Improved vehicle access so authorized police can remove the selected occupant even when that person is not restrained.
  • Added the ability for a carried player to end the carry with /carry.
  • Fixed an issue where a returned or deleted fleet vehicle could leave stale key ownership and prevent keys being granted on its next spawn.

Other Changes

  • Added current-position and world-object selection tools to supported location fields while retaining teleport controls for derived positions.
  • Improved the Job Configurator by keeping unavailable sections visible with disabled controls and grouping default-data tools in General.
  • Improved employee tables with scrolling and readable fixed headers, and kept finance views current when accounts or balances change.
  • Improved configurator translations and shared locale loading so loading one resource does not replace another resource's labels.
  • Optimized organization startup migrations, repeated location lookups and idle interface checks to reduce unnecessary background work.
  • Updated bundled interface images with smaller files.

Changed Files

  • sky_jobs_base/config/config.lua
  • sky_jobs_base/config/init.lua
  • sky_jobs_base/config/inventory/advanced_drug_test_kit.png
  • sky_jobs_base/config/inventory/drug_test_kit.png
  • sky_jobs_base/config/inventory/fake_drug_sample_clean.png
  • sky_jobs_base/config/inventory/handcuffs.png
  • sky_jobs_base/config/inventory/handcuffs_keys.png
  • sky_jobs_base/config/inventory/headbag.png
  • sky_jobs_base/config/inventory/legcuffs.png
  • sky_jobs_base/config/inventory/wire_cutter.png
  • sky_jobs_base/config/inventory/zipties.png
  • sky_jobs_base/config/locales/*
  • sky_jobs_base/fxmanifest.lua
  • sky_jobs_base/import.sql
  • sky_jobs_base/source/* — delete and reinsert
  • sky_jobs_base/vehicle_registry.sql

Removed Files

  • sky_jobs_base/config/locales/_shared/dispatch_fallback.lua
Update InstructionsWhat to copy, what to keep and what to check1.42.01.43.0

Simplified update

Update sky_jobs_base safely

Read the complete update instructions in one continuous guide.

  1. Prepare the update

Install Base 1.40.0 before Jobs Base 1.43.0. Use the matching job releases: Ambulance 2.39.0, Police 1.32.0, Mechanic 1.29.0, Fire 1.11.0 and Crime 0.3.0 for their shared integrations. These instructions cover 1.42.0 → 1.43.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.43.0 package. Update every path in Changed Files, delete and reinsert sky_jobs_base/source/*, and replace sky_jobs_base/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

In sky_jobs_base/config/config.lua, add this complete assignment after the existing Config.JobGarage table declaration. Previously destroyed-vehicle recovery and its repair price had no settings; the new defaults enable recovery and charge 5000:

config/config.lua
Config.JobGarage.destroyedVehicleRecovery = {
    enabled = true,
    repairPrice = 5000,
}

Config.JobGarage.destroyedVehicleRecovery.enabled: absent → true. Config.JobGarage.destroyedVehicleRecovery.repairPrice: absent → 5000; use 0 for free repairs. These are shared file defaults. For a particular job, open /jobconfig > [resource] > [job] > General and review Recover destroyed vehicles and Vehicle repair fee (garageVehicleRecovery.enabled, garageVehicleRecovery.repairPrice). An explicit saved job value takes precedence over the shared default. Recovery applies to the shared job fleet; the vehicle's original job/personal payment source pays the repair charge. Keep the existing personal payment account.

Config.PrimaryJobGroups has expanded comments only; its default remains {}. Existing combined departments need no new value. Keep their chosen primary group and creator assignments.

Replace the changed config/init.lua, the complete locales and the manifest together. Configurator locale packs now load through the shared locale loader; reapply custom translations to the new declarative packs without restoring the old initialization code. Job Configurator labels remain in the matching Jobs Base resource pack.

Review Pay bonuses in the organization's role editor. Permission 33 now controls bonuses separately from account management. Roles without an explicit bonus setting retain their previous account-management behavior until configured; save the intended bonus permission for each affected role. This is role data, not a new Config.* option.

Preserve existing /jobconfig overrides, jobs, locations and dispatch plans. Position tools and derived-position teleport controls do not add stored configuration values. The shared registry has no separate activation switch here: enable it in Mechanic after completing its permissions, service-point and database setup.

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 database. With sky_jobs_base/config/config.lua > Config.AutoExecuteQuery = true, allow the normal startup migrations to finish before starting job resources. This release adds:

  • sky_job_confiscations, with the job, officer/citizen identities, item or weapon, amount, metadata and timestamp.
  • sky_jobs_vehicles.repair_required TINYINT(1) NOT NULL DEFAULT 0.
  • sky_jobs_logs.payment_reference VARBINARY(128) NULL and unique index uniq_job_payment on (job, payment_reference).
  • sky_jobs_vehicle_registry, sky_jobs_vehicle_inspections, sky_jobs_vehicle_registrations and sky_jobs_vehicle_registry_history for vehicle status, signed documents and operations.

With automatic migrations disabled, import sky_jobs_base/vehicle_registry.sql for all four new registry tables, then execute the following additions in the active game database. They mirror the new schema in sky_jobs_base/import.sql and preserve existing records:

CREATE TABLE IF NOT EXISTS `sky_job_confiscations` (
    `id` INT NOT NULL AUTO_INCREMENT,
    `job_name` VARCHAR(64) NOT NULL,
    `officer_identifier` VARCHAR(80) NOT NULL,
    `officer_name` VARCHAR(120) NOT NULL,
    `citizen_identifier` VARCHAR(80) NOT NULL,
    `citizen_name` VARCHAR(120) NOT NULL,
    `item_name` VARCHAR(100) NOT NULL,
    `item_label` VARCHAR(120) NOT NULL,
    `amount` INT NOT NULL,
    `is_weapon` TINYINT(1) NOT NULL DEFAULT 0,
    `metadata` LONGTEXT NULL,
    `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (`id`),
    INDEX `idx_confiscations_job` (`job_name`, `id`)
);

SET @sky_release_sql = IF(
    EXISTS(SELECT 1 FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'sky_jobs_vehicles' AND COLUMN_NAME = 'repair_required'),
    'SELECT 1', 'ALTER TABLE `sky_jobs_vehicles` ADD COLUMN `repair_required` TINYINT(1) NOT NULL DEFAULT 0'
);
PREPARE sky_release_migration FROM @sky_release_sql;
EXECUTE sky_release_migration;
DEALLOCATE PREPARE sky_release_migration;

SET @sky_release_sql = IF(
    EXISTS(SELECT 1 FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'sky_jobs_logs' AND COLUMN_NAME = 'payment_reference'),
    'SELECT 1', 'ALTER TABLE `sky_jobs_logs` ADD COLUMN `payment_reference` VARBINARY(128) NULL'
);
PREPARE sky_release_migration FROM @sky_release_sql;
EXECUTE sky_release_migration;
DEALLOCATE PREPARE sky_release_migration;
SET @sky_release_sql = IF(
    EXISTS(SELECT 1 FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'sky_jobs_logs' AND INDEX_NAME = 'uniq_job_payment'),
    'SELECT 1', 'CREATE UNIQUE INDEX `uniq_job_payment` ON `sky_jobs_logs` (`job`, `payment_reference`)'
);
PREPARE sky_release_migration FROM @sky_release_sql;
EXECUTE sky_release_migration;
DEALLOCATE PREPARE sky_release_migration;

For physical vehicle inspections/registrations, also complete the Base owned-vehicle ID migration and Mechanic invoice migration in their matching update guides before enabling the service. No data-reset SQL is needed. Existing fleet vehicles start with repair_required = 0; this update does not assign old repair debts. Confiscations and payment history start recording new successful operations; old events are not reconstructed.

The financial history needs a confirmed society credit. External billing providers must report successful net society payments through the supported integration; merely creating an invoice does not record income. Keep payment references stable to prevent duplicate entries. No new inventory items are required by Jobs Base.

  1. Restart and verify

Confirm version 1.43.0 and successful migrations. Reopen saved jobs/roles, verify translated fields, and test gang interaction access. Accept one dispatch from the radio and tablet, check its GPS route and recipient duties/shifts. On a test fleet vehicle, check destroyed recovery, the configured payment source, repair fee and keys after respawning. Confirm a successful confiscation and paid invoice appear once in the correct department history. Test filtered CCTV selection and ending a carry from the carried player.

Version 1.42.0

Update sky_base to 1.39.0 before installing Jobs Base 1.42.0.

Highlights

  • Improved the Job Configurator so location and map editors open inside the current page, keeping the sidebar and your previous section available.
  • Added clear explanations and repair steps when an emergency call or mission dispatch cannot be created.
  • Improved exclusion zones so traffic restrictions follow the drawn area more closely and restore normal roads when the zone is removed.

Notable Changes

  • Added a shared patient-position preview with separate stretcher positions, configurable animations, and a fine-adjustment mode.
  • Added support for drawing Crime mainbase boundaries with a visible height preview while keeping ordinary garages, storage, and other job locations in their own tabs.
  • Fixed an issue where saving a mainbase could stop responding or a later job edit could restore outdated boundary settings.
  • Improved job-garage storage so confirmed Mechanic tuning remains available when a vehicle is retrieved again.
  • Changed exclusion zones to preserve vehicles and their occupants instead of deleting them when they enter the area.
  • Added on-screen notifications when entering or leaving an exclusion zone, including when the tablet is closed.
  • Fixed an issue where complicated exclusion zones could cause a client crash.

Other Changes

  • Improved creator forms and selection menus with clearer sizing, keyboard navigation, and protection for unsaved edits when returning to the previous page.
  • Removed empty location panels from editors that only manage zones.
  • Improved the Raid app layout and clarified that only eligible storage inside the mainbase belongs to a raid.
  • Updated Crime, Ambulance, and Mechanic configurator text for mainbase editing, patient animations, dyno placement, and the handling-editor switch.
  • Fixed an issue where vehicles outside a player's view could repeatedly produce trunk-registration warnings.
  • Removed repetitive startup summaries and the blanket warning about example dispatch data while retaining checks for actual configuration problems.
  • Added optional performance diagnostics to help support investigate lag and delays, with diagnostics disabled by default.

Changed Files

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

Simplified update

Update sky_jobs_base safely

Read the complete update instructions in one continuous guide.

  1. Prepare the update.

Update sky_base to 1.39.0 before installing Jobs Base 1.42.0. These steps cover 1.41.2 → 1.42.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.42.0 package. Update every path listed in Changed Files, delete and reinsert sky_jobs_base/source/*, and replace sky_jobs_base/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_jobs_base/source/* tree and sky_jobs_base/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. sky_jobs_base/config/init.lua does not need replacement solely for this profiler update.

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.

There are no changed values in sky_jobs_base/config/config.lua or config/webhooks.lua in this update. Keep your existing shared settings and provider secrets. Shared carry, restraints, search, civilian-use, image-source, and dispatch-center policies remain file settings; they are not moved into /jobconfig.

Replace all sky_jobs_base/config/locales/*, including the Job Configurator subfolders. The new editor and dispatch messages need the matching files.

Review the affected areas in /jobconfig: Crime System → Job → Mainbase, Ambulance → General → Stretcher, and Mechanic → Features → Handling editor. Update the corresponding resource before using its new controls. Saved overrides continue to take precedence over shipped defaults; use each resource's update instructions for the exact keys and values.

Mainbase boundaries are edited in their own job tab. Add or move boundary points, choose the zone height, then apply and save the zone. The lowest point defines the bottom of the area and the height extends upward. Storage, lockers, and garages remain under the normal location controls. Editing a draft does not move the active boundary until it is applied.

When a dispatch fails, follow the displayed cause and numbered steps. Check the receiving department and its response plan in /jobconfig; dispatch-center coverage remains under Config.Dispatch.centers in sky_jobs_base/config/config.lua. Keep a running Fire mission under control before starting it again.

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.

No Jobs Base SQL schema migration, new inventory item, image, or provider secret is introduced. Keep saved jobs, locations, mainbase boundaries, dispatch data, garage records, and configurator history. This update does not require resetting or reimporting all jobs.

  1. Start and verify the update.

Open a creator from /jobconfig, make a draft edit, and use Back or Escape to confirm the unsaved-change prompt. Save a mainbase and reopen it; confirm regular job locations are still available. Test entering and leaving a named exclusion zone with the tablet closed, and remove the zone to restore traffic. Check an emergency dispatch, a Fire mission, and retrieval of a tuned job vehicle with the matching resources.

Version 1.41.2

Use sky_base1.38.0 or a matching newer package. If Ambulance is installed, update sky_ambulancejob to 2.37.2 for the complete hospital startup fix. Crime integrations need the matching Crime package; see the dependency details below.

Highlights

  • Fixed an issue where hospitals could be treated as ready before their saved locations had finished loading, together with Ambulance 2.37.2.
  • Fixed an issue where the Job Configurator rejected placement checks supplied by another job, including the Mechanic mobile Dyno.
  • Added a Raids tablet app for compatible Crime installations, with nearby bases, active raids, participants, stored items and garage vehicles.

Notable Changes

  • Improved Dispatch location labels with street names, intersections and area names in incident views, the radio display and exported reports.
  • Added Money Wash location and interior editors with location capture, interior visits, fixture placement and a movable placement camera.
  • Improved location editing with linked interior choices, coordinate and range validation, and changes that remain in the draft until saved.
  • Added support for delivery integrations to find a job's current storage locations, including locations shared with that job.
  • Added checks that apply boss-menu rank restrictions to every raid action and protect base configuration and vehicle changes during an active raid.
  • Fixed an issue where access to Crime storage and gang tablet apps could use a player's main job instead of their independent Crime membership.

Other Changes

  • Improved held-key handling so death and knockout release blocked job actions immediately.
  • Added a more readable size option for forms shown outside the tablet.
  • Updated Money Wash, heist timing, heist point and base-raid configuration translations, and added raid app translations.

Changed Files

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

Simplified update

Update sky_jobs_base safely

Read the complete update instructions in one continuous guide.

  1. Use sky_base 1.38.0 or a matching newer package, and update sky_ambulancejob to 2.37.2 if it is installed. These steps cover 1.41.1 to 1.41.2; complete earlier upgrade instructions first when starting from an older version. Stop the server and back up the resources, database, saved Job Configurator settings and custom configuration. Preserve generated reports and other writable data.
  2. Install the matching 1.41.2 package. Replace sky_jobs_base/fxmanifest.lua, delete and reinsert sky_jobs_base/source/*, and replace sky_jobs_base/config/locales/* completely. The manifest includes the new raid module and must be updated together with the source and built UI.
  3. No values in sky_jobs_base/config/config.lua change in this patch, and no new global configuration block is required. Preserve existing settings and saved /jobconfig overrides. The new location editors use the settings supplied by the owning resource; captured coordinates and fixture positions must still be saved in the Job Configurator.

If sky_crimesystem is installed, use a matching updated Crime package before using its Job Configurator. Jobs Base now calls Crime's CloseMoneywashInteriorPreview and updated PreviewMoneywashInterior exports when switching configurations, teleporting or editing interiors. Older Crime packages can fail on those actions even when no preview is open.

The optional Raids app requires Crime's matching raid provider. Access follows the organization's existing boss-menu tablet-app restrictions, using the member's Crime rank where applicable. Configure base zones, raid requirements and loot rules in the matching Crime resource. Raid transfers from vehicle trunks and gloveboxes also require the matching sky_base vehicle-inventory transfer adapter; the original 1.38.0 tag does not contain that addition. Install that matching Base package before enabling these raid features. Jobs Base alone does not install or enable the Crime gameplay systems.

External suppliers can optionally use the new GetJobStorageCoords server export. Existing integrations do not need to adopt it to update Jobs Base.

  1. No SQL schema migration, new inventory item or provider secret is added by this Jobs Base patch. Keep the existing database and stored job data. Replace all sky_jobs_base/config/locales/*; the built raid app icon and other UI assets are included in the replacement source/* folder. Any additional Crime item or database requirements belong to its matching package's installation instructions.
  2. Start providers, Base, Jobs Base and the installed jobs in that order. With Ambulance 2.37.2, verify that hospital locations load after startup. Test a valid and a rejected mobile Dyno placement, an incident supplied with coordinates only, and held job keys during death or knockout. If Crime is installed, test switching away from its Job Configurator, a Money Wash interior visit and saving a fixture position. For configured raids, verify allowed and denied ranks, actual storage transfers and garage retrieval, plus normal storage access for a member whose main job differs from their Crime membership.

Version 1.41.1

Use sky_base1.38.0 before updating sky_jobs_base.

Highlights

  • Fixed an issue where combined-service jobs could use the wrong organization settings or station catalogs after another service registered the same job.
  • Added an optional wholesale order mode for external delivery integrations, with saved orders, customer contact details and order status tracking.

Notable Changes

  • Improved access to shared tablet apps, chat, cameras, maps and training for jobs that belong to more than one service group.
  • Added editing of existing job and off-duty identifiers in the Job Configurator while preserving the saved configuration entry.
  • Improved Dispatch configuration feedback with specific validation messages, visible invalid selections and save errors inside the confirmation dialog.
  • Fixed an issue where incidents with coordinates but no named address appeared to have no location in Dispatch views, maps and exported reports.
  • Improved response-plan selection for incoming alerts that specify the responsible job.

Other Changes

  • Added support for external scripts to deliver multiple items into job storage in one request.
  • Improved prop placement by allowing more time for models such as the mobile Dyno to finish loading.
  • Added inventory images for the standard drug test kit, advanced drug test kit and clean fake sample.

Changed Files

  • sky_jobs_base/config/config.lua
  • sky_jobs_base/config/inventory/README.md
  • sky_jobs_base/config/inventory/advanced_drug_test_kit.png
  • sky_jobs_base/config/inventory/drug_test_kit.png
  • sky_jobs_base/config/inventory/fake_drug_sample_clean.png
  • sky_jobs_base/config/locales/*
  • sky_jobs_base/fxmanifest.lua
  • sky_jobs_base/import.sql
  • sky_jobs_base/source/* — delete and reinsert
Update InstructionsWhat to copy, what to keep and what to check1.41.01.41.1

Simplified update

Update sky_jobs_base safely

Read the complete update instructions in one continuous guide.

  1. Use sky_base 1.38.0 before updating sky_jobs_base. These steps cover 1.41.0 → 1.41.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.41.1 as a matching package. Update every path in Changed Files, delete and reinsert sky_jobs_base/source/*, and replace sky_jobs_base/config/locales/* completely. Merge the configuration instructions in this tab into customized files; retain intentional settings and persistent data.
  3. Review the configuration steps.

In sky_jobs_base/config/config.lua, add these two complete blocks. Both were absent in 1.41.0 and are global file settings; individual resource /jobconfig settings do not manage them.

config/config.lua
Config.PrimaryJobGroups = {
    -- ["fire"] = "fire", -- Example only: framework job name = owning service group
}

Config.WholesaleShop = {
    externalOrders = false
}

Config.PrimaryJobGroups defaults to an empty table. For a framework job registered by several services, it can select which service supplies the shared society, management, duty, Dispatch and training settings. Without an entry, the alphabetically first registered group owns those settings. Use your actual framework job name as the key and a registered service group such as fire or ambulance as the value. Each Creator station still uses its own service's garage, wholesale and storage configuration. Review the selected owner's Dispatch vehicles and statuses so they cover the combined fleet. Existing stations and stored vehicles need no conversion.

Config.WholesaleShop.externalOrders defaults to false, retaining immediate purchases paid from the society account and delivered into the player's inventory. Set it to true only after connecting an external order system that handles payment and delivery. In that mode Jobs Base saves the order but does not collect payment or grant items itself. A quoted order price is not proof of payment. Restart Jobs Base after changing these global file settings.

Existing job and off-duty identifiers can now be edited under /jobconfig → the selected resource and job → General. This is optional; no rename is required to update. Saving preserves the configuration entry and its settings, but does not rename framework jobs, move employees, transfer society balances or migrate historical records. Arrange those changes separately if you choose new identifiers. Existing overrides remain effective. Correct any highlighted Dispatch selections and the specific reported channel, status, coverage or radio setting before saving again.

  1. Apply the data, inventory and asset steps.

Back up the database. With Config.AutoExecuteQuery = true, the startup migration creates sky_jobs_wholesale_orders; allow it to finish before starting dependent jobs. With automatic migration disabled, run this new statement from sky_jobs_base/import.sql before starting Jobs Base. The table is added even when external orders remain disabled; existing tables and data are retained.

import.sql
CREATE TABLE
    IF NOT EXISTS `sky_jobs_wholesale_orders` (
        `id` VARCHAR(32) NOT NULL,
        `station_id` VARCHAR(100) NOT NULL,
        `job` VARCHAR(64) NOT NULL,
        `items` LONGTEXT NOT NULL,
        `total_price` DOUBLE NOT NULL DEFAULT 0,
        `status` VARCHAR(16) NOT NULL DEFAULT 'pending',
        `created_by_source` INT NOT NULL,
        `created_by_identifier` VARCHAR(100) NOT NULL,
        `created_by_name` VARCHAR(120) NOT NULL,
        `civilian_name` VARCHAR(120) NOT NULL DEFAULT '',
        `civilian_phone` VARCHAR(40) NOT NULL DEFAULT '',
        `rejection_reason` VARCHAR(255) NOT NULL DEFAULT '',
        `created_at` BIGINT NOT NULL,
        `updated_at` BIGINT NOT NULL,
        PRIMARY KEY (`id`),
        INDEX `idx_wholesale_job_status` (`job`, `status`, `created_at`),
        INDEX `idx_wholesale_status` (`status`, `created_at`)
    );

Copy sky_jobs_base/config/inventory/drug_test_kit.png, advanced_drug_test_kit.png and fake_drug_sample_clean.png from that same directory into your inventory's image directory. These images belong to existing items; no new item definitions are required by this patch. Replace the updated inventory README and all sky_jobs_base/config/locales/*, including Job Configurator translations.

External delivery integrations must verify successful storage delivery before completing an order and prevent duplicate delivery themselves. Changing an order's status does not deliver items. No existing inventory data needs to be cleared, and no provider secret changes are required.

  1. Start providers, Base and Jobs Base before dependent jobs. Check startup migration completion, an immediate wholesale purchase with external orders disabled, the optional external flow if enabled, station catalogs and duty for combined jobs, and the affected Dispatch screens. Confirm edited identifiers only when an intentional rename was configured.

Version 1.41.0

Update sky_base to 1.38.0 before updating sky_jobs_base.

Highlights

  • Added basic and advanced drug tests with saved results, subject names, and controlled sharing between police, medical, and justice departments.
  • Added transferable clean-sample items that can falsify the user's next valid drug test within a configurable activation period.
  • Added separate legitimate and dirty-money balances, transaction histories, and permissions for supported factions.
  • Added support for independent organization memberships alongside a character's regular employment.
  • Improved dispatch alerts so on-duty responders receive queued radio notices, including when they are outside a vehicle, with an optional classic notification banner.

Notable Changes

  • Fixed an issue where unattended medical and fire incidents could be routed to the wrong dispatch center.
  • Fixed an issue where hybrid dispatch could omit the configured no-unit notice when automatic alarm delay was disabled.
  • Improved the emergency phone app so it shows actual service staffing, refreshes availability on reopening, and preserves unsent reports and callback numbers.
  • Fixed an issue where gameplay shortcuts could activate while typing in RoadPhone emergency forms.
  • Improved radio readability with wrapping titles, larger scrollable messages, clearer status labels, and accessible controls.
  • Improved radio and tablet focus changes and enabled moving the handset through its saved layout settings.
  • Added shared support for player-configurable job key bindings while preserving each player's existing assignments.
  • Fixed an issue where delayed updates could restore removed objects or overwrite newer job settings, creator locations, cameras, and map information.
  • Fixed an issue where CCTV updates could reset the current view or replace newer camera status and motion settings.
  • Fixed an issue where repeated garage updates could grant duplicate vehicle keys or retain temporary vehicle access after it should end.
  • Improved tablet maps so permitted jobs can use their map app independently of pause-map colleague tracking, including supported secondary memberships.
  • Fixed an issue where public radial actions could expose private actions or an open menu could retain actions after a job, duty, or permission change.
  • Changed panic access to require explicitly listed service jobs.

Other Changes

  • Added custom NPC interaction names and an option to show or hide station prefixes while keeping map labels separate.
  • Added deletion of calendar entries by their creator while keeping linked system appointments read-only.
  • Improved personal notes and notification history so they stay separate for each character and job, with a one-time assignment flow for older data.
  • Fixed an issue where repeated tablet opening could retain an outdated app catalog, use the wrong job appearance or map layer, or start duplicate reminder requests.
  • Improved the tablet home screen so returning from an app restores the selected page.
  • Fixed an issue where rapidly reopening the tablet could leave duplicate handheld props or an outdated animation.
  • Fixed an issue where Job Configurator settings appeared saved before the database accepted them, and improved partial updates and decimal-comma input.
  • Improved Job Configurator loading feedback, grouped navigation, and location descriptions, and fixed creator registration and placement validation errors.
  • Fixed an issue where the shared tracking service was unavailable after startup.
  • Added contextual actions for completed camera photos supplied by compatible resources.
  • Improved faction finance cards so large amounts fit consistently and exact values remain available.
  • Fixed an issue where Escape in an open shared dropdown could also close the surrounding editor.
  • Updated Job Configurator translations for medical insurance, Dyno and handling settings, Fire pump damage, justice items, and Crime markets, heists, crafting, drugs, faction takeovers, safe opening, money washing, and NPC police support.
  • Added optional server diagnostics for investigating Job Configurator saves.

Changed Files

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

Simplified update

Update sky_jobs_base safely

Read the complete update instructions in one continuous guide.

  1. Update sky_base to 1.38.0 before updating sky_jobs_base. Stop the server and back up the complete sky_jobs_base 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.41.0 as a consistent package. Replace every file listed in Changed Files, delete and reinsert sky_jobs_base/source/*, and replace sky_jobs_base/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.

The changed Config.DrugTests, Config.ManagementFinance, Config.Dispatch.legacyAlertBanner, Config.Dispatch.centers[*].primaryJobs, and Config.Panic.allowedJobs paths are global file settings in sky_jobs_base/config/config.lua. /jobconfig does not manage these global definitions. Existing per-job Dispatch/radio overrides remain effective and should be checked separately.

Add the complete new drug-test block; every path inside it was absent in 1.40.0:

config/config.lua
Config.DrugTests = {
    enabled = true,
    crimeResource = "sky_crimesystem",
    maxDistance = 3.0,
    cooldownSeconds = 2,
    requireOnDuty = true,
    fakeSample = {
        enabled = true,
        item = "fake_drug_sample_clean",
        durationSeconds = 300,
        consumeOnUse = true,
        weight = 100
    },
    records = {
        enabled = true,
        openAfterTest = true,
        maxRecords = 250,
        maxSubjectNameLength = 120,
        accessGroups = { "police", "ambulance", "doj" },
        shareGroups = { "police", "ambulance", "doj" }
    },
    simple = {
        item = "drug_test_kit",
        group = "police",
        consumeOnUse = true,
        weight = 100
    },
    advanced = {
        item = "advanced_drug_test_kit",
        group = "ambulance",
        consumeOnUse = true,
        weight = 150
    }
}

Tests require the configured Crime resource and its current drug-substance integration. With the shipped values, police use basic tests, ambulance staff use detailed tests, staff must be on duty, and both players must be within 3 metres. The clean sample is transferable as an inventory item; activating it lasts 300 seconds and affects the next valid test once. Its active effect is cleared on disconnect. Disabling or changing these settings requires a resource restart.

Extend the existing finance block. historyDays stays 14; maxTransactionAmount, dirtyMoney.enabledForGangs, and dirtyMoney.currency are new:

config/config.lua
Config.ManagementFinance = {
    historyDays = 14,
    maxTransactionAmount = 2000000000,
    dirtyMoney = {
        enabledForGangs = true,
        currency = "black_money"
    }
}

Gang-ledger defaults can be overridden by the owning resource's registered management settings. Legitimate society funds stay with the configured banking provider; the new dirty-money reserve is separate. Grant the new Manage illicit funds rank permission only to intended users. It is separate from the existing Manage funds permission. Base must include the black_money currency.

Apply these exact Dispatch and panic changes while preserving your center IDs, order, recipients, and unrelated settings:

Path1.40.01.41.0
Config.Dispatch.legacyAlertBannerabsentfalse
Config.Dispatch.centers[2].primaryJobs in the shipped ems_dispatch profileabsent{ "ambulance", "fire", "firefighter" }
Config.Panic.allowedJobsnil, allowing registered jobs{ "police", "ambulance", "fire" }; nil or {} now denies everyone
config/config.lua
Config.Dispatch.legacyAlertBanner = false
Config.Dispatch.centers[2].primaryJobs = { "ambulance", "fire", "firefighter" }
Config.Panic.allowedJobs = { "police", "ambulance", "fire" }

The center index in this block is correct only for the shipped order. For custom centers, add primaryJobs to the profile whose id is "ems_dispatch", using your exact job names. Every primary job must also occur in that profile's coveredJobs and must be primary in only one center. Existing incidents keep their assigned center. Add custom panic jobs such as firefighter or sheriff explicitly if required. Existing Config.Panic.enabled, duty rules, recipients, and Ping settings are unchanged.

Config.Dispatch.enabled = true with legacyAlertBanner = false uses the Dispatch App and radio arrivals; true/true adds the classic banner; enabled = false uses classic map dispatch. Classic incidents are kept in memory and do not inherit the persistent Dispatch App history. Keep Config.Dispatch.radio.enabled = true or the intended saved job override for radio arrivals. Radio BACK or the green handset dismisses an arrival notice without accepting a unit assignment. New radio focus bindings default to F10; existing player bindings stay in FiveM settings. The rest of the Dispatch block was reorganized without changing its values.

Job-specific key defaults belong to each job's /jobconfig General → Keybinds section and its Config.Keybinds, not a new Jobs Base key table. Deploy the matching four job packages for this shared input change. For temporary save diagnostics, use the server convar set sky_jobconfig_trace 1; its default is 0, and set sky_jobconfig_trace 0 disables it again. No new provider-secret setting is required.

Interaction names and station prefixes are now configurable through each owning resource's existing interaction definition. These are interaction fields, not global entries in the Settings section:

Path in the owning resource's config/config.luaPrevious behaviorNew behaviorSaved interaction field
Config.Interactions[interactionId].useStationNameNo supported switch; the station prefix was always includedOmitted means true; set false to hide the prefixinteractions[interactionId].useStationName
Config.Interactions[interactionId].npc.nameExisting optional editor field was ignored by interaction promptsA nonblank name is used when the NPC is enabled; blank or disabled NPCs retain the localized interaction labelinteractions[interactionId].npc.name

No file edit is needed to retain the existing station-prefix default. With the owning resource's Config.UseJobConfigurator = true, set the name in /jobconfig → resource → Interactions → type → NPC → Name, and the prefix in Behavior → Show station name. Saved overrides apply to every location of that interaction type and survive saving, reload and restart. Reset clears the override and restores the default prefix. Import uses the same fields. Blip → Name and Config.Interactions[interactionId].blip.name remain independent map labels.

With that resource's configurator disabled, edit its plaintext interaction definition. For the shipped Ambulance doctor, this optional example hides the station prefix and changes the enabled doctor's interaction label:

sky_ambulancejob/config/config.lua
Config.Interactions.npc_doctor.useStationName = false
Config.Interactions.npc_doctor.npc.name = "Dr. Smith"

Keep the existing NPC enabled/model settings. For other interaction types, use their actual key in the owning resource. Empty station names do not add a leading separator. No new config root, item or SQL migration is required. After updating Jobs Base, test a saved name with the prefix enabled and disabled, a blank or disabled NPC name, reset, and the independent map label.

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

With Config.AutoExecuteQuery = true, allow startup migration to finish before starting dependent jobs. Otherwise apply the corresponding statements from the new sky_jobs_base/import.sql first. The release adds four tables and extends logs and personal notes; the exact types and defaults are:

migration.sql
CREATE TABLE
    IF NOT EXISTS `sky_jobs_organization_memberships` (
        `id` INT NOT NULL AUTO_INCREMENT,
        `group_key` VARCHAR(64) NOT NULL,
        `identifier` VARCHAR(64) NOT NULL,
        `organization` VARCHAR(64) NOT NULL,
        `grade` INT NOT NULL DEFAULT 0,
        `added_by` VARCHAR(64) 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_group_identifier` (`group_key`, `identifier`),
        INDEX `idx_organization_membership` (`organization`)
    );

CREATE TABLE
    IF NOT EXISTS `sky_jobs_organization_membership_modes` (
        `group_key` VARCHAR(64) NOT NULL,
        `mode` VARCHAR(24) NOT NULL DEFAULT 'framework',
        `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
        PRIMARY KEY (`group_key`)
    );

CREATE TABLE
    IF NOT EXISTS `sky_jobs_finance_balances` (
        `id` INT NOT NULL AUTO_INCREMENT,
        `job` VARCHAR(50) NOT NULL,
        `ledger` VARCHAR(24) NOT NULL,
        `balance` BIGINT NOT NULL DEFAULT 0,
        `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
        PRIMARY KEY (`id`),
        UNIQUE KEY `uniq_job_ledger` (`job`, `ledger`)
    ) ENGINE=InnoDB;

CREATE TABLE
    IF NOT EXISTS `sky_jobs_drug_test_records` (
        `id` BIGINT NOT NULL AUTO_INCREMENT,
        `record_uid` VARCHAR(40) NOT NULL,
        `owner_group` VARCHAR(32) NOT NULL,
        `created_by_identifier` VARCHAR(64) NOT NULL,
        `subject_name` VARCHAR(120) NULL,
        `test_mode` VARCHAR(16) NOT NULL,
        `positive` TINYINT(1) NOT NULL DEFAULT 0,
        `drug_details` LONGTEXT NOT NULL DEFAULT '[]',
        `shared_groups` LONGTEXT NOT NULL DEFAULT '[]',
        `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_drug_test_record_uid` (`record_uid`),
        INDEX `idx_drug_test_owner_created` (`owner_group`, `created_at`, `id`),
        INDEX `idx_drug_test_creator` (`created_by_identifier`, `created_at`)
    );

ALTER TABLE `sky_jobs_logs`
    ADD COLUMN IF NOT EXISTS `ledger` VARCHAR(24) NULL AFTER `content`,
    ADD COLUMN IF NOT EXISTS `currency` VARCHAR(64) NULL AFTER `ledger`,
    ADD COLUMN IF NOT EXISTS `amount` INT NULL AFTER `currency`;

ALTER TABLE `sky_jobs_personal_notes`
    ADD COLUMN IF NOT EXISTS `job_name` VARCHAR(64) NULL AFTER `character_identifier`,
    ADD INDEX IF NOT EXISTS `idx_personal_notes_owner_job_sort` (`character_identifier`, `job_name`, `is_pinned`, `updated_at`, `id`);

Back up existing personal notes and browser-stored tablet data. Old notes keep job_name = NULL until their owner uses the tablet's one-time assignment dialog to choose the original job. Do not assign every customer's note to the same job or delete the old rows. Organization membership mode is configured by the owning resource; changing it can migrate memberships and multijob entries, so back up those records before switching modes.

Verify the active inventory has drug_test_kit (weight 100), advanced_drug_test_kit (150), and fake_drug_sample_clean (100). Jobs Base registers these through the inventory bridge; file-based inventories may still require their shared definitions. The items are stackable and the script handles consumption. Supply your own matching PNGs: this release includes no images for the three new items. Keep existing printer_paper, other shared items, media provider configuration, and writable dispatch_reports data. No additional stream asset or secret is introduced.

  1. Start Base, Jobs Base, and the matching jobs in order. Verify all migration tables/columns, a basic and advanced drug test, one fake-sample test and a subsequent real test, saved record naming/sharing, and rejection of unauthorized access. Test both finance ledgers and rejected withdrawals, personal notes after switching character/job, owned versus linked calendar deletion, map access, stale radial actions, panic allowlists, garage key revocation, and reopening the tablet. Send a phone/medical incident with zero staffed units and with a staffed center; confirm routing, radio dismissal, tone behavior, and optional banner.

Version 1.40.0

Update sky_base to 1.37.0 before updating sky_jobs_base.

Highlights

  • Added a complete persistent dispatch system with separate unit and dispatcher workspaces, calls, incidents, virtual multi-crew units, assignments, response plans, shifts, roles, permissions, and cross-center transfers.
  • Added an enhanced tactical dispatch map with clustering, selected markers, unit trails, persistent map features, configurable panels, and roster navigation.
  • Added public warnings, SDS unit messages, center chat, callback handoff, phone emergency integration, audio announcements, and PDF incident reports.
  • Added contextual tablet access through configured computers and optional vehicles plus a personal notes application.
  • Added shared job-printer infrastructure with live paper levels, runtime print queues, remote-printer discovery, temporary printers, and resource-owned document workflows.

Notable Changes

  • Improved dispatch reliability with server-owned access and schema rules, request limits, unattended-center fallback, alarm retries, permissions, radio controls, and resource exports for calls and incidents.
  • Improved handheld radio behavior with personal preferences and clearer synchronization while removing the former night mode and default key binding.
  • Added gang-backed management, combined group membership, configurable management sections, and deterministic precedence when a job and gang share an identifier.
  • Improved Job Configurator with restorable defaults, one-time dispatch-default migration, clearer labels, duplicate and location handling, and expanded localized configuration for supported job resources.
  • Added a shared qualification-code whitelist and extended calendar events with hearing end time, location, source, and public-visibility data.
  • Improved garages, tuning orders, training-time validation, CCTV failure reporting, attachment previews, and navmesh blocking.

Other Changes

  • Enabled the shared dispatch system by default and added sky_only as the shipped emergency-dispatch forwarding mode.
  • Added diagnostics for shared Jobs Base services and improved tablet application lifecycle handling.
  • Added personal-note persistence and printer paper handling; the printer_paper inventory item remains administrator-owned and is not created automatically.
  • Updated bundled locales for dispatch, management, Job Configurator, radio, printing, personal notes, calendar, qualifications, and supported job extensions.

Changed Files

  • sky_jobs_base/config/config.lua
  • sky_jobs_base/config/init.lua
  • sky_jobs_base/config/locales/*
  • sky_jobs_base/dispatch_reports/.gitkeep
  • sky_jobs_base/fxmanifest.lua
  • sky_jobs_base/import.sql
  • sky_jobs_base/source/* — delete and reinsert
Update InstructionsWhat to copy, what to keep and what to check1.39.01.40.0

Simplified update

Update sky_jobs_base safely

Read the complete update instructions in one continuous guide.

  1. Install sky_base 1.37.0, stop the server, and back up the complete Jobs Base resource, every sky_jobs_* table, Job Configurator settings, and existing dispatch/report output.
  2. Delete the old folder and install the complete 1.40.0 package. Keep dispatch_reports writable and do not mix 1.39.0 source, locales, UI, manifest, or database schema with this release.
  3. Start from the new config/config.lua. Review the new Config.Tablet.computerAccess, Config.Tablet.vehicleAccess, Config.Tablet.apps.personal_notes, expanded Config.Dispatch, and Config.EmergencyDispatch.server.dispatch.mode. Existing /jobconfig values may override resource-owned defaults.
  4. With Config.AutoExecuteQuery = true, restart Jobs Base once and allow every migration to finish. Otherwise run the complete new import.sql before starting the resource. This release extends calendar, configurator, dispatch incident, unit, audit, and assignment data and creates the personal-notes, dispatch-unit, alarm, map-feature, broadcast, SDS, call, and center-chat tables.
  5. Add the printer_paper item to the active inventory only when a consuming printer configuration requires it. Keep the media-provider API key in config/webhooks.lua private and server-specific; the package contains an empty placeholder.
  6. Restart Base and Jobs Base in order. Verify migration completion, both dispatch workspaces, configured center permissions, radio, public warnings, SDS, chat, phone callback handoff, report output, tablet computers, optional tablet vehicles, personal notes, printers, management, calendar, and Job Configurator restore behavior.

Version 1.39.0

Update sky_base to 1.36.0 before updating sky_jobs_base.

Highlights

  • Added persistent job-fleet impounds with reasons, fees, impounding authority details, and a dedicated impounded state shared by supported job resources.
  • Added optional persistence for placed job props so authorized world objects can survive resource or server restarts until they are removed.
  • Added stable fleet key holders so reconnects and restarts return active vehicle keys to the current driver instead of an earlier occupant.
  • Added an optional login policy that places duty-capable players off duty whenever their framework character loads.

Notable Changes

  • Improved job-garage parking, retrieval, reconnect, and active-vehicle handling so fleet state remains consistent across longer sessions.
  • Added shared training content so one course can be made available to multiple configured jobs without duplicating its material.
  • Improved recruitment so candidate lists use only framework-loaded players from the live job cache.
  • Improved configured duty switching so invalid mappings are rejected and missing off-duty jobs produce a useful Job Configurator warning.
  • Improved external tablet synchronization so LB Tablet and other supported app registrations are reinstalled after a job configuration changes.
  • Added server-authorized one-time prop placement for trusted job resources and made placed trunk or world props return their items atomically when removed.
  • Improved variable barriers and tape lines so their posts follow mapped ground height more accurately.
  • Improved exclusion-zone cleanup so ambient NPCs are removed by the server-selected owner even when the nearest client does not control those entities.

Other Changes

  • Improved startup ordering so database migrations finish before jobs, sharing, and server classes consume their tables.
  • Fixed an issue where empty Job Configurator settings could be stored as a JSON array instead of the expected object.
  • Improved the tuning-pricing editor with functional categories, complete controls, synchronized defaults, and matching locale coverage.
  • Improved shared tablet forms and theme behavior while removing browser filter effects that could render inconsistently in FiveM CEF.
  • Updated bundled translations for training, prop placement, impounds, ankle-monitor persistence, Ambulance fatal-wound settings, Mechanic delivery settings, and Polish wording.

Changed Files

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

Simplified update

Update sky_jobs_base safely

Read the complete update instructions in one continuous guide.

  1. Install sky_base 1.36.0, stop the server, and back up the complete Jobs Base resource, Job Configurator tables, sky_jobs_vehicles, and placed-prop data.
  2. Delete the old folder and install the complete 1.39.0 package. Do not mix the old manifest, database migration, built UI, locales, or source files with this release.
  3. Add these plaintext/global settings to config/config.lua; both paths were absent in 1.38.1 and both ship disabled:
    config/config.lua
    Config.ForceOffDutyOnLogin = false
    Config.PropPlacement.persistPlacedProps = false
    

    In the shipped file, persistPlacedProps = false sits inside Config.PropPlacement immediately after the unchanged returnItemOnRemove = true field and before the unchanged items table. Set Config.ForceOffDutyOnLogin = true only when every duty-capable character should start off duty after each login. Set Config.PropPlacement.persistPlacedProps = true only when newly placed configured props should be restored after restarts. /jobconfig does not manage either value.
  4. With Config.AutoExecuteQuery = true, restart Jobs Base once and let the built-in migration extend sky_jobs_vehicles, create sky_jobs_placed_props, and normalize empty Job Configurator settings. With automatic migration disabled, run the complete new import.sql after Base is updated. The required SQL is:
    migration.sql
    ALTER TABLE `sky_jobs_vehicles`
        ADD COLUMN IF NOT EXISTS `key_holder_identifier` VARCHAR(64) NULL,
        ADD COLUMN IF NOT EXISTS `impound_reason` VARCHAR(255) NULL,
        ADD COLUMN IF NOT EXISTS `impound_fee` INT NOT NULL DEFAULT 0,
        ADD COLUMN IF NOT EXISTS `impounded_at` DATETIME NULL,
        ADD COLUMN IF NOT EXISTS `impounded_by` VARCHAR(120) NULL,
        ADD COLUMN IF NOT EXISTS `impounded_by_identifier` VARCHAR(64) NULL,
        ADD COLUMN IF NOT EXISTS `impound_authority_job` VARCHAR(64) NULL,
        MODIFY COLUMN `state` ENUM('stored', 'parked', 'impounded') NOT NULL DEFAULT 'stored',
        ADD INDEX IF NOT EXISTS `idx_job_state` (`job`, `state`);
    
    CREATE TABLE IF NOT EXISTS `sky_jobs_placed_props` (
        `persistence_key` VARCHAR(96) NOT NULL,
        `owner_resource` VARCHAR(64) NULL,
        `payload` 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 (`persistence_key`),
        INDEX `idx_placed_props_owner_resource` (`owner_resource`)
    );
    
    UPDATE `sky_jobs_configurator_settings`
    SET `settings` = '{}'
    WHERE TRIM(`settings`) = '[]';
    
  5. Keep all existing /jobconfig job and feature choices. This release adds editor capabilities and locale coverage but no new required saved setting in sky_jobs_configurator_settings. The two new config.lua values above remain manual global policy.
  6. No new Jobs Base inventory item, image, or external provider secret is required. Replace config/locales completely and keep the newly built UI together with the runtime files.
  7. Restart in order: sky_base, sky_jobs_base, then job resources. Verify fleet purchase/parking/keys, an authorized job impound and release, optional login duty reset, training sharing, recruitment, external tablet apps, and prop placement/removal with persistence both disabled and enabled.

Version 1.38.1

Update sky_base to 1.35.1 before updating sky_jobs_base.

Highlights

  • Added a payroll policy that can pay salaries without checking or deducting society funds.
  • Changed the Dispatch app to ship disabled so existing servers retain legacy top-center notifications until the full app is deliberately enabled.

Notable Changes

  • Improved the built-in English fallback catalogue so missing translated tablet keys remain readable.
  • Fixed an issue where garage vehicles could show missing state labels while saved data was still loading.

Other Changes

  • Updated the package manifest for the 1.38.1 compatibility set.

Changed Files

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

Simplified update

Update sky_jobs_base safely

Read the complete update instructions in one continuous guide.

  1. Update Base to 1.35.1, stop the server, and back up Jobs Base plus intentional config edits.
  2. Delete the old resource and install the complete 1.38.1 package, including its config, manifest, built UI, locales, and full source directory.
  3. Change Config.Dispatch.enabled from true to false. This is plaintext/global policy; /jobconfig does not replace the master switch.
  4. Add Config.Salary.deductFromSocietyFunds = true after enabled = true. The path was absent in 1.38.0; true preserves society-funded payroll, while false pays owed intervals without checking or charging society funds. This is also plaintext/global.
  5. No SQL, inventory item, image, stream asset, or provider secret changed. Restart Base, Jobs Base, then job resources and verify dispatch presentation, salary funding, garage labels, and fallback text.

Version 1.38.0

Update sky_base to 1.35.0 before updating sky_jobs_base.

Highlights

  • Cross-job sharing - selected cases, reports, warrants, BOLOs, training content, and vehicle records can be shared read-only with explicitly chosen jobs from a new Job Configurator Share tab.
  • Staffed response plans - dispatch response plans can require a minimum total crew in addition to unit types and counts.
  • Employee learning catalogue - training administration and employee-visible learning content are separated, with catalogue visibility and richer course material.
  • More durable job fleets - vehicle parking, reconnects, AdvancedParking integration, keys, colors, and disconnect behavior are more consistent.
  • Complete external tablet icons - every registered Jobs Base, Police, Ambulance, and Mechanic tablet app now ships with a matching bundled icon for LB Tablet and RoadPad.

Notable Changes

  • Dispatch uses exact job precedence, restores legacy notifications, and exposes response-plan evaluation to dependent job resources.
  • Colleague map blips ship restricted to Police and Ambulance, with explicit mutual visibility groups.
  • Recruitment updates live and permits a ten-meter recruiter-to-candidate distance.
  • Per-camera CCTV motion controls, variable-length prop lines, configurable job blip colors, tuning item quantities, and duplicate tuning items are supported.
  • The Job Configurator adds search, clearer subsections, sharing controls, and synchronized visibility for external tablet apps after job changes.
  • LB Tablet uses native iframe sizing by default to keep embedded Sky apps sharp. A per-app fixBlur override remains available for legacy layouts, and the new layout-repair version reapplies the synchronized descriptors and icons once.
  • Framework-confirmed duty changes prevent stale duty state across Jobs Base and Jobs Creator.

Other Changes

  • Camera uploads enforce bounds and reuse WebGL contexts; media deletion treats a provider 404 as already removed.
  • Job garages avoid duplicate vehicle keys and retain OneSync vehicles by default after the original driver disconnects.
  • Fire hydrant supply configuration now uses the exact saved key hoseVehiclePumpHydraulicsHydrantSupplyLitersPerSecond; the matching Fire update converts the former hoseVehiclePumpHydraulicsHydrantSupplyGpm override.
  • Manual and automatic schema definitions now inherit the active database character set and collation.
  • Newly synchronized tablet icons cover Dispatch, Training, Tracking, speed-camera reviews, appointments, medical evaluations, shared medical evaluations, health insurance, Mechanic subscriptions, and Mechanic parts deliveries; existing registered app icons remain aligned with the same catalogue.
  • Mechanic Parts Shop visibility follows its tablet-app restrictions, while the purchase permission remains enforced only by the ordering/payment action.
  • Shared UI, management, CCTV, training, map, storage, dispatch, and Job Configurator wording was completed across bundled locales.

Changed Files

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

Simplified update

Update sky_jobs_base safely

Read the complete update instructions in one continuous guide.

  1. Update sky_base to 1.35.0. Stop the server and back up the complete Jobs Base resource, all Job Configurator data, and the database.
  2. Delete the old folder and install the complete 1.38.0 package. Do not mix the new UI/runtime with 1.37.0 source, locales, or manifest files.
  3. Start from the new config/config.lua. Add the new plaintext global policy exactly as shipped:
    config/config.lua
    Config.Sharing = {
        enabled = true,
        maxTargetsPerRule = 64
    }
    

    Per-job sharing rules are job-owned data edited in /jobconfig on the Share tab; they are not fields inside this global table.
  4. Apply every remaining config change:
    Exact path1.37.01.38.0
    Config.ColleagueMapBlips.allowedJobsnil / unrestricted{ "police", "ambulance" }
    Config.ColleagueMapBlips.groupsnil / same-job onlyPolice and Ambulance can see both groups
    Config.Dispatch.jobConfiguratorExtensions[dispatchKeywords].fields[minimumCrew]MissingInteger editor field, minimum/default 0
    Config.Invites.maxDistance5.010.0 meters
    Config.JobGarage.deleteVehicleOnPlayerDroppedtruefalse
    Config.Tablet.external.lb.fixBlurMissingtrue; use LB's native iframe size
    Config.Tablet.external.lb.layoutRepairVersion"2026-08-01-app-icons-3""2026-08-17-app-icons-native-scale-1"
    Config.Tablet.external.appOverrides.<app>.fixBlurMissingOptional per-app boolean; omit to inherit the LB default

    Use this complete shipped map policy:
    config/config.lua
    Config.ColleagueMapBlips.allowedJobs = { "police", "ambulance" }
    Config.ColleagueMapBlips.groups = {
        police = { "police", "ambulance" },
        ambulance = { "police", "ambulance" },
    }
    Config.Invites.maxDistance = 10.0
    Config.JobGarage.deleteVehicleOnPlayerDropped = false
    Config.Tablet.external.lb.fixBlur = true
    Config.Tablet.external.lb.layoutRepairVersion = "2026-08-17-app-icons-native-scale-1"
    

    Keep fixBlur = true for the shipped native LB iframe scale. Only set an individual Config.Tablet.external.appOverrides.<app>.fixBlur = false when that legacy app explicitly depends on LB's older oversized iframe and transform scaling. Do not keep the old layout-repair value: the new key forces one descriptor repair so every synchronized app icon is applied without duplicate LB entries.
    In /jobconfig, review every dispatch keyword and set Minimum crew (minimumCrew) as needed; 0 preserves the old no-minimum behavior. Review the new Share tab for every job. Saved sharing and keyword values override local job data. For Fire jobs, the hydrant-capacity field now stores hoseVehiclePumpHydraulicsHydrantSupplyLitersPerSecond; Fire 1.6.0 converts the removed hoseVehiclePumpHydraulicsHydrantSupplyGpm override from GPM to litres per second.
  5. With automatic migrations disabled, run this complete manual SQL after installing the new import.sql changes:
    migration.sql
    ALTER TABLE `sky_jobs_training_courses`
        ADD COLUMN IF NOT EXISTS `learning_content` LONGTEXT NULL AFTER `description`,
        ADD COLUMN IF NOT EXISTS `catalog_visible` TINYINT(1) NOT NULL DEFAULT 0 AFTER `learning_content`;
    

    With Config.AutoExecuteQuery = true, restart performs the same schema update automatically. All shipped schema definitions now inherit the active database character set and collation. No new inventory item or streamed gameplay asset is required; the complete resource package already contains the new tablet SVG icons, so do not copy individual icon files into an old source directory.
  6. Restart sky_base, then sky_jobs_base, then the job resources. Verify sharing access, minimum-crew evaluation, employee course visibility, colleague blips, recruitment at ten meters, fleet persistence after disconnect, sharp LB app rendering, and the synchronized external-tablet icon catalogue.

Version 1.37.0

Update sky_base to 1.34.0 before updating sky_jobs_base.

Highlights

  • Complete dispatch center - authorized staff can manage incident queues, assignments, status history, response planning, destinations, reporters, points of interest, announcements, and virtual units with callsigns, types, icons, channels, and status codes.
  • Dedicated radio workspace - a configurable hardware-style radio remains available outside the tablet with position, size, buttons, tones, alarms, channel join/leave, transmit state, and responsive volume controls.
  • Advanced training management - courses, sessions, enrollment approvals, results, qualifications, expiry, reminders, and audit history are managed through a permission-aware tablet app.
  • Organization Units - jobs can create departments or units, assign members, define unit permissions, and restrict configured job vehicles to selected units.
  • External tablet delivery - apps can run as individual entries or an all-in-one workspace on LB Tablet and RoadPad, including authorization, inherited sessions, retries, and lifecycle handling.
  • Persistent and controllable job fleets - AdvancedParking, CD Garage, or native persistence can preserve active job vehicles, while explicit remove/sell modes define who may retire shared fleet entries and whether a refund is paid.

Notable Changes

  • Numeric frequencies remain readable, compact incident chat and logs use the available space better, and current coordinates can be captured as incident locations.
  • Dispatch starts reliably after resource initialization; the radio represents an unassigned state correctly, supports Alt interaction, removes obsolete keypad overlays and flicker, and stabilizes navigation, scrolling, selection, and unavailable controls.
  • Dispatch alerts and panic alerts reach the intended job members, support optional silent metadata, and can play separate radius-based xSound cues without blocking the alert when xSound is unavailable.
  • The dispatch permission uses ID 21; Organization Unit management uses ID 22.
  • Handcuff keys are no longer required by default, and stuck cuff interaction state is cleared during player and resource lifecycle changes.
  • Shared carry is enabled by default, permits conscious targets and carriers inside vehicles, and skips acceptance only for incapacitated targets.
  • Player search can hide the searched player's name while retaining combined item and weapon results.
  • Recruitment now validates a maximum 5.0 meter distance between recruiter and candidate.
  • Duty and multi-job state are normalized against the active framework, and stale off-duty salary payouts are prevented.
  • Tablet access validates the current job, duty state, and configured requirements on the server before opening protected apps.
  • Item images resolve automatically from the ordered inventory sources used by storage and shop interfaces.
  • Vehicle-attachment interaction spheres match their configured size, and creator synchronization no longer leaves connecting players waiting indefinitely.
  • Removed storage props disappear for every nearby client instead of remaining visible for other players.
  • Job Configurator editors now handle numeric medical values, mechanic class pricing and previews, localized cloakroom skins, speed-camera settings, protective equipment, mission rewards, pump fields, and cleanup access consistently.

Other Changes

  • The boss menu was rebuilt around shared page headers, fields, selectors, switches, ranges, date ranges, responsive tables, and accessible action controls across light, dark, and blue-dark themes.
  • Management now has a full-height standalone layout, clearer selected navigation, compact deposit/withdraw controls, and consistent transaction, role, member, finance, log, and billing-spec surfaces.
  • The duty terminal keeps its clock, live status, and completed shift duration aligned and avoids overflowing long shift messages.
  • Storage surfaces received clearer controls and now follow the active job theme consistently.
  • A reusable multi-select displays readable labels while the server still validates vehicle selections against the effective job configuration.
  • Delivery-timer editor labels were removed after the corresponding workflow moved to a dedicated tablet view.
  • Italian was added; shared interface, Dispatch, Fire, Mechanic, Police, Ambulance, cloakroom, reward, and configurator wording was completed or corrected across bundled locales.
  • Tablet app icons are generated before the frontend build, LB layout repair refreshes stale app icons, radio image assets keep stable package names, and the test runner now includes both JavaScript test formats.
  • Six public integration exports expose the active tablet session, safe external-session matching and closing, generated RoadPad app descriptors, and server-authoritative extension of job-vehicle access.
  • Public API, setup, external-tablet, Dispatch, and shared-form documentation was expanded together with regression coverage for the new management, duty, garage, radio, training, access, synchronization, and UI behavior.

Changed Files

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

Simplified update

Update sky_jobs_base safely

Read the complete update instructions in one continuous guide.

  1. Update sky_base to 1.34.0. Stop the server, then back up the complete sky_jobs_base resource, config/config.lua, all sky_jobs_* database tables, saved Job Configurator values, and role permissions.
  2. Delete the old Jobs Base folder and install the complete 1.37.0 package. Keep the new manifest, locales, generated UI, icons, radio assets, SQL, and all of source together. Start from the new config/config.lua; do not transplant the new sections into an otherwise old file.
  3. These are shared plaintext settings, not ordinary per-job /jobconfig values. The following complete block documents the new Units settings and is directly copyable after the packaged config tables:
    config/config.lua
    Config.ToggleFeatures = Config.ToggleFeatures or {}
    Config.ToggleFeatures.units = true
    
    Config.OrganizationUnits = {
        requireOnDuty = true,
        maxUnitsPerJob = 100,
        maxPermissionsPerUnit = 32,
        maxVehiclesPerUnit = 100,
    }
    
    Config.Tablet.apps.training = { enabled = true, isNew = true }
    Config.Tablet.apps.dispatch = { enabled = true, isNew = true }
    
  4. Keep this complete new external-tablet block. The fields did not exist in 1.36.0:
    config/config.lua
    Config.Tablet.external = {
        enabled = true,
        mode = "apps",
        identifierPrefix = "sky_jobs_",
        developer = "Sky-Systems",
        defaultApp = true,
        removable = false,
        size = 5120,
        icon = "https://cfx-nui-sky_jobs_base/source/html/logo.svg",
        allInOne = {
            identifier = "sky_jobs",
            name = "Sky Jobs",
            description = "All Sky Jobs tablet apps in one place.",
            icon = "https://cfx-nui-sky_jobs_base/source/html/logo.svg",
            defaultApp = true,
            removable = false,
            size = 10240,
            allowJobs = {},
            disallowJobs = {},
        },
        appOverrides = {
            camera = false,
            calculator = false,
        },
        lb = {
            layoutRepairVersion = "2026-08-01-app-icons-3",
            hideNativeDuplicates = false,
            nativeDuplicates = {
                camera = "Camera",
                gallery = "Photos",
                map = "Maps",
                calculator = "Calculator",
                settings = "Settings",
            },
            managedAppKeys = {},
        },
        roadpad = {
            outputFile = "roadpad-apps.generated.json",
            category = "apps",
            darkmode = true,
        },
    }
    

    Config.Tablet.external.enabled = true only prepares the integration; it does not change Base's active tablet provider. The shipped Base default remains Config.tablet = "default", which keeps the built-in Jobs Base tablet active. Set Config.tablet = "lb" or Config.tablet = "roadpad" in sky_base only as a deliberate opt-in. Use mode = "apps" for individual entries or mode = "all-in-one" for the shared workspace. When opting in, start the chosen external tablet provider before sky_base. LB registers dynamically; after an LB mode or descriptor change, restart lb-tablet, sky_base, and sky_jobs_base. RoadPad is static: replace every existing sky_jobs* object in roadpad/public/static/config/config.json -> AppStore with every object from the generated roadpad-apps.generated.json apps array. Do not append the generated objects to old Sky entries.
  5. Keep the packaged Training section and use these copyable assignments for every allowed runtime default and permission introduced in 1.37.0:
    config/config.lua
    Config.Training = Config.Training or {}
    Config.Training.enabled = true
    Config.Training.requireOnDuty = true
    Config.Training.upcomingDays = 90
    Config.Training.historyDays = 365
    Config.Training.reminderMinutes = 60
    Config.Training.readCooldownMs = 350
    Config.Training.mutationCooldownMs = 350
    Config.Training.allowSelfEnrollment = true
    Config.Training.approvalRequired = true
    Config.Training.defaultCapacity = 12
    Config.Training.permissions = {
        schedule = 1001,
        catalog = 1002,
        viewRecords = 1003,
        delete = 1004,
        manageSessions = 1005,
        reviewEnrollments = 1006,
        recordResults = 1007,
        issueQualifications = 1008,
        revokeQualifications = 1009,
        viewAudit = 1010,
    }
    

    The saved /jobconfig key is trainingSettings, with defaults enabled = true, requireOnDuty = true, allowSelfEnrollment = true, approvalRequired = true, defaultCapacity = 12, and upcomingDays = 90. Saved values override the Lua defaults; review and save every affected job.
  6. Keep the packaged Dispatch section and use these copyable assignments for every allowed shared runtime default introduced in 1.37.0:
    config/config.lua
    Config.Dispatch = Config.Dispatch or {}
    Config.Dispatch.enabled = true
    Config.Dispatch.appJobs = { "police", "ambulance", "fire", "firefighter", "mechanic" }
    Config.Dispatch.averageResponseSpeedKmh = 70
    Config.Dispatch.noUnitFallback = true
    Config.Dispatch.cleanupIntervalMs = 5000
    Config.Dispatch.announcement = {
        enabled = true,
        resource = "xsound",
        defaultRadius = 65.0,
        ttsUrlTemplate = "",
    }
    Config.Dispatch.spatialSounds = {
        enabled = true,
        resource = "xsound",
        dispatch = {
            enabled = true,
            url = "https://cfx-nui-sky_jobs_base/source/html/assets/sky-dispatch_radio_end.ogg",
            volume = 0.35,
            radius = 12.0,
        },
        panic = {
            enabled = true,
            url = "https://cfx-nui-sky_jobs_base/source/html/assets/sky-dispatch_radio_start.ogg",
            volume = 0.65,
            radius = 25.0,
        },
    }
    Config.Dispatch.groupDefaults = {
        police = { defaultChannel = "POLICE_MAIN" },
        ambulance = { defaultChannel = "EMS_MAIN" },
        fire = { defaultChannel = "FIRE_MAIN" },
        firefighter = { defaultChannel = "FIRE_MAIN" },
        mechanic = { defaultChannel = "MECHANIC_MAIN" },
    }
    Config.Dispatch.defaultStatusCodes = {
        { code = 1, label = "Available by radio", available = true },
        { code = 2, label = "Available at station", available = true },
        { code = 3, label = "Responding", available = false },
        { code = 4, label = "On scene", available = false },
        { code = 5, label = "Request to speak", available = false },
        { code = 6, label = "Unavailable", available = false },
    }
    

    The saved /jobconfig keys are dispatchSettings, dispatchChannels, dispatchStatusCodes, dispatchVehicleTypes, dispatchVehicles, dispatchKeywords, and dispatchPois. Allowed dispatchSettings defaults covered by this release are enabled = true, centerEnabled = true, incidentAssessmentEnabled = true, defaultChannel = "", noUnitFallback = true, and averageResponseSpeedKmh = 70; status-code defaults are the six entries above. Saved values override the Lua defaults, so review and save every affected job. With announcements or spatial sounds enabled, start xsound before sky_jobs_base; if it is unavailable, alerts continue without 3D audio.
  7. Apply every other changed shared value exactly:
    config/config.lua
    Config.Invites.maxDistance = 5.0
    Config.PoliceCuffs.key.enabled = false
    Config.PlayerCarry.enabled = true
    Config.PlayerCarry.allowConsciousTargets = true
    Config.PlayerCarry.allowCarrierInVehicle = true
    Config.PlayerSearch.showTargetName = false
    Config.JobGarage.persistenceProvider = "auto"
    Config.JobGarage.deleteVehicleOnPlayerDropped = true
    Config.JobGarage.vehicleRemovalMode = "sell"
    Config.JobGarage.allowAllEmployeesToRemove = false
    Config.JobGarage.sellPercentage = 50
    Config.Panic.allowedJobs = nil
    

    All were missing in 1.36.0 except Config.PoliceCuffs.key.enabled (true -> false), the three listed carry values (false -> true), Config.JobGarage.sellPercentage (still 50, now valid from 1 to 100 in sell mode), and Config.Panic.allowedJobs (fixed list -> nil). Carry acceptance remains enabled for conscious targets and is skipped for incapacitated targets. Garage "auto" uses native mode when neither supported persistence provider is started, selects the one started provider, and fails visibly if both are started; start the selected provider before sky_jobs_base or choose it explicitly.
  8. Before startup, inspect and back up the existing configurator-settings table:
    SELECT TABLE_NAME, ENGINE
    FROM information_schema.TABLES
    WHERE TABLE_SCHEMA = DATABASE()
      AND TABLE_NAME = 'sky_jobs_configurator_settings';
    

    If it exists and is not InnoDB, run this after the backup; neither CREATE TABLE IF NOT EXISTS nor automatic migration converts an existing table:
    ALTER TABLE sky_jobs_configurator_settings ENGINE=InnoDB;
    

    When Config.AutoExecuteQuery = false, run the complete new import.sql. It creates the two Organization Unit tables, five Dispatch tables, and five Training tables. It also includes this required upgrade for an existing incident table:
    ALTER TABLE `sky_jobs_dispatch_incidents`
        ADD COLUMN IF NOT EXISTS `details` LONGTEXT NULL AFTER `message`;
    
  9. Update integrations for the six new public exports. Client code can call GetTabletState() to receive { open, appKey, route, surface, resource, session }, IsExternalTabletOpen() to test whether an LB, RoadPad, or embedded provider owns the active surface, MatchesExternalTabletSession(payload) to require the matching surface, resource, and session plus an optional appKey, and CloseExternalTabletSession(payload) to receive accepted, closedState while stale sessions are rejected. Server code can call GetRoadPadTabletApps() for the generated AppStore descriptors only while external integration is enabled and Base selects RoadPad. RegisterVehicleAccessProvider(provider) returns a Boolean; its callback (source, jobName, model) may only add catalogue, purchase, spawn, or trunk access, and the registration is removed when its owner resource stops.
  10. After startup, grant Dispatch permission 21 and Manage Units permission 22 only to intended roles, then save those roles. No new Jobs Base inventory item is required. Start the selected external providers first, then sky_base, sky_jobs_base, and every installed job resource. Verify saved Configurator values, permissions, incidents, radio controls, Training records, Units, external tablet entries, shared interaction defaults, integration exports, and garage persistence after a full restart.

Version 1.36.0

Update sky_base to 1.33.0 before updating sky_jobs_base.

Highlights

  • Central civilian interaction policy - servers can opt in to cuffs, zipties, leg restraints, escorting, vehicle placement, head bags, and searches for civilians through one safe-off shared configuration.
  • Shared player carry engine - one server-authoritative carry flow now serves civilians and installed job resources, including acceptance, distance, conscious-target, sprint, vehicle, animation, and attachment rules.
  • Multi-provider media uploads - FiveManage and Qbox CDN are built in, custom providers can register centrally, and management/tablet media flows share the selected provider.
  • More reliable job garages - persistent vehicles retain a stable catalogue identity, duplicate models remain distinguishable, grade-restricted owned vehicles can still be returned, and location-specific vehicle-class rules are supported.

Notable Changes

  • Metal handcuffs can require the new non-consumable handcuffs_keys item for removal.
  • Player searches can combine items and weapons into one view.
  • Ordered item, weapon, prop, ped, and vehicle image sources replace the old single-URL fields while preserving legacy aliases for integrations.
  • Civilian target actions are automatically registered through the selected Sky target adapter when enabled.
  • Calendar creators can edit entries; garage state, billing prices, radial target payloads, trunk targets, creator markers, and boss-menu currency/map presentation are synchronized more reliably.
  • Successful manual dashcam recordings are now stored in the job gallery and report a visible save error if gallery persistence fails.
  • Illenium Appearance wardrobe points now open job outfits, and configurator selectors hide unavailable resource integrations.
  • Serbian shared and Job Configurator translations were added, alongside wider locale coverage.

Other Changes

  • Added custom management permission registration and documented central carry, civilian access, media-provider, image-source, and garage APIs.
  • Deterministic config/server loading prevents duplicate registrations.
  • Blip values are normalized before reaching FiveM natives.

Changed Files

  • sky_jobs_base/config/config.lua
  • sky_jobs_base/config/init.lua
  • sky_jobs_base/config/inventory/handcuffs_keys.png
  • sky_jobs_base/config/inventory/README.md
  • sky_jobs_base/config/locales/*
  • sky_jobs_base/config/webhooks.lua
  • sky_jobs_base/fxmanifest.lua
  • sky_jobs_base/import.sql
  • sky_jobs_base/source/* — delete and reinsert
Update InstructionsWhat to copy, what to keep and what to check1.35.11.36.0

Simplified update

Update sky_jobs_base safely

Read the complete update instructions in one continuous guide.

  1. Update sky_base to 1.33.0.
  2. Back up sky_jobs_base, delete the old folder, and install the complete 1.36.0 package including source/html, locales, inventory images, tests, and manifest.
  3. These are shared plaintext settings, not job-resource /jobconfig values. Replace the five singular Config.Nui.*ImageBase strings with itemImageBases = { "https://cdn.sky-systems.net/items" }, weaponImageBases = { "https://cdn.sky-systems.net/weapons" }, propImageBases = { "https://cdn.sky-systems.net/props" }, pedImageBases = { "https://cdn.sky-systems.net/peds" }, and vehicleImageBases = { "https://cdn.sky-systems.net/vehicles" }.
  4. Change Config.Cctv.allowedJobs from { "police", "ambulance", "firefighter" } to { "police", "ambulance", "fire" }; add Config.PoliceCuffs.key = { enabled = true, item = "handcuffs_keys" }; and add Config.PlayerSearch.combineWeapons = true.
  5. Add Config.CivilianUse = { enabled = false, target = true, cuffs = true, zipties = true, legRestraints = true, escort = true, vehicle = true, headBag = true, search = true }.
  6. Add Config.PlayerCarry with enabled = false, command = "carry", requireAcceptance = true, requestTimeoutSeconds = 15, maxDistance = 2.5, allowConsciousTargets = false, allowSprint = false, allowCarrierInVehicle = false, acceptKey = "E", declineKey = "X", carrier animation missfinale_c2mcs_1 / fin_c2_mcs_1_camman / 49, passenger animation nm / firemans_carry / 33, attachBone = 0, and offsets x = 0.27, y = 0.0, z = 0.63, pitch = 0.5, roll = 0.5, yaw = 180.0.
  7. In config/webhooks.lua, add Webhooks.media = { provider = "fivemanage", providers = {} }, retain Webhooks.fivemanage with its existing V3 URL and timeoutMs = 10000, and add Webhooks.qbox = { apiKey = "", baseUrl = "https://api.qbox.re/v1/file", timeoutMs = 10000 }. Keep all API keys server-side.
  8. Run the updated import.sql when automatic migration is disabled; it adds nullable sky_jobs_vehicles.catalog_id VARCHAR(100).
  9. Register the non-consumable handcuffs_keys item and copy config/inventory/handcuffs_keys.png when your inventory requires manual setup.
  10. Restart Base, Jobs Base, and then every installed job resource.

Version 1.35.1

Update sky_base to 1.32.1 before updating sky_jobs_base.

Highlights

  • Restrained-state protection across job tools - handcuffing now closes active job interfaces and blocks tablet, multi-job, panic, incident, radial, and protected interaction actions until the player is released.
  • Gang-aware shared tablet access - QBCore and Qbox gangs can receive explicitly registered tablet apps independently from a player's regular job.
  • Expanded Fire Job Configurator - configurable pump vehicles render as clear cards with compact intake/outlet editors, conditional controls, localized labels, and simple/enhanced panel support.
  • Context-aware direct action keybinds - cuffs and zipties now use apply/remove toggles based on the nearest player's current restraint, with shared default mappings enabled.

Notable Changes

  • Handcuff interaction distance increased from 2.0 to 4.0, and players cannot fire or interrupt the handcuffing sequence with conflicting controls.
  • Tgiann integrations receive synchronized restraint state.
  • Job-grade synchronization is scoped correctly per framework and no longer clears stored off-duty salary values.
  • Jobs without a framework-native duty value now resolve their initial duty state correctly.
  • Off-duty job aliases can still resolve their registered tablet app group.
  • Item and weapon images support lowercase file names and both common weapon-image naming formats.
  • Added the Ambulance maximum-health compatibility label and completed English/German Fire pump configurator copy.

Other Changes

  • Improved unavailable-action wording and updated the public Jobs Base API documentation.
  • Removed an unused disconnect listener and expanded configurator and salary regression coverage.
Update InstructionsWhat to copy, what to keep and what to check1.35.01.35.1

Simplified update

Update sky_jobs_base safely

Read the complete update instructions in one continuous guide.

  1. Update sky_base to 1.32.1.
  2. Download sky_jobs_base 1.35.1, then back up the resource and customized config files.
  3. Delete the old resource folder and install the complete new folder, including source/html and all locales.
  4. Transfer your server-specific values into the new config/config.lua.
  5. Review the changed cuff distance and every changed direct radial keybind listed below.
  6. No SQL migration or new inventory item is required.
  7. Restart sky_base, then sky_jobs_base, followed by all dependent jobs.

Version 1.35.0

Update sky_base to 1.32.0 before updating sky_jobs_base.

Highlights

  • Shared player-interaction system - handcuffs, zipties, leg restraints, escorting, vehicle placement, head bags, searches, restraint escape, and administrator restraint commands now use one server-authoritative Jobs Base system shared by supported job resources.
  • Personal job-garage ownership - fleets can remain shared, belong to individual employees, or support transfers between employees, with configurable job or personal payment and clearer ownership information in the garage UI.
  • More capable shared tablet and creator tools - trusted job apps can open inside the shared tablet, attachment placement is easier to control, and Fire personnel can use the shared camera network.
  • Persistent mounted equipment - registered prop items can support controlled wall placement, job/duty-based removal, saved custom mounts, and reliable cleanup without changing ordinary ground props.

Notable Changes

  • Cuff escape is validated by the server and can be tuned for chance, timing, difficulty, cooldown, and supported restraint types.
  • Shared radial actions support grouped submenus and optional direct keybinds.
  • Restraint item documentation and ready-to-copy images now live with sky_jobs_base.
  • Switching jobs resets duty correctly, off-duty players no longer receive salary synchronization, and management changes refresh more reliably.
  • Job garages preserve canonical plates through storage, modification, ownership, and transfer flows.
  • Config.MultiJob.showDefaultJob now defaults to true, making the configured fallback job selectable.
  • Unrelated map blips are preserved when shared job blips refresh.

Other Changes

  • Improved garage lists, vehicle details, statistics, ownership layout, and transfer verification.
  • Expanded shared and Job Configurator translations.
  • Fixed missing item and weapon images in shared shop and storage screens when image files use lowercase names but configured item names use uppercase or mixed case.
  • Updated the resource version to 1.35.0.
Update InstructionsWhat to copy, what to keep and what to check1.34.01.35.0

Simplified update

Update sky_jobs_base safely

Read the complete update instructions in one continuous guide.

  1. Update sky_base to 1.32.0.
  2. Download sky_jobs_base 1.35.0, then back up the resource, database, and customized config/webhook files.
  3. Delete the old resource folder and install the complete new folder, including source/html, locales, and inventory images.
  4. Transfer your server-specific values into the new config/config.lua. Keep the new shared player-interaction, restraint, radial-keybind, garage ownership, mounted-prop, CCTV, and command-permission blocks.
  5. Review Config.MultiJob.showDefaultJob, Config.Cctv.allowedJobs, and every group under Config.JobPlayerInteractions.
  6. Copy the five restraint images from config/inventory into your inventory image folder when required.
  7. Run the updated /import.sql only when automatic query execution is disabled.
  8. Restart sky_base, then sky_jobs_base, followed by every dependent job resource.

Version 1.34.0

Update sky_base to 1.31.0 before updating sky_jobs_base.

Highlights

  • Expanded tablet personalization - the new Full Dark theme, switchable tablet cases, and job-specific default themes give each service a clearer visual identity.
  • Refreshed shared tablet experience - Gallery, Calculator, Settings, Boss Menu, selects, image handling, and the main map received a coordinated usability and visual update, including a detailed GTA map and Cayo Perico coverage.
  • Optional EmergencyDispatch integration - dispatches can route through EmergencyDispatch when explicitly enabled, while the built-in Sky provider remains the safe default.
  • More reliable Job Configurator workflows - callback timeouts and mutation deadlocks were corrected, numeric values keep the intended precision, runtime table values survive refreshes, and string-list table fields can be edited directly.

Notable Changes

  • Added Config.MultiJob.showDefaultJob so the fallback job can remain active internally without appearing in the player job menu.
  • Salary payouts are now limited to jobs registered with Sky Jobs.
  • Station blips are replaced and cleaned up correctly instead of duplicating after refreshes or resource restarts.
  • Role-structure editing is only offered on the framework that supports it.
  • Job images now accept PNG and WebP sources throughout shared menus and vehicle views.
  • Added localized creator section labels for Fire Stations and Mechanic Workshops.
  • Expanded Fire Job, Police Job, and Ambulance Job configurator translations, including dedicated Duplicate action labels in every bundled language.
  • Added cleanup support for resource-owned trunk props and improved general creator stability.

Other Changes

  • Improved map zooming and dragging and removed obsolete map alignment offsets.
  • Removed retired Ambulance fall-injury configurator labels.
  • Updated the resource version to 1.34.0.

Version 1.33.0

Update sky_base to 1.30.0 before updating sky_jobs_base.

Highlights

  • Complete Job Configurator support toolkit - configurations can now be exported for support, imported again, checked with a safe repair preview, reviewed through revision history, and reset with an exact preview. History compares normalized values so unchanged JSON data no longer appears as a change, and a global reset also clears its revisions.
  • Radial action submenus - categorized actions open in nested radial levels, the center now shows a close icon at the root and an undo-2 back action inside submenus, and target context remains attached to the selected action.
  • Shared vehicle attachment editor - supported job resources can position equipment with a gizmo, local/world transform modes, free camera controls, and reusable attachment settings.
  • Safer job lifecycle management - job deletion and related creator cleanup are serialized, default jobs can be removed deliberately, and connected resources can block deletion while active service work remains.
  • Controlled cross-job chat - optional per-job rules define which job members, groups, conversations, and unread counts are visible without exposing unrelated job data.

Notable Changes

  • Added per-job station blip configuration and support for creator locations shared by multiple jobs.
  • Added secure fleet vehicle resale with persisted purchase prices and a configurable refund percentage.
  • Added live oil-spill management and the shared in-world prop-offset measurement tool.
  • Added movable streamed props, authoritative transform updates, ownership cleanup on resource stop, and safer item returns when placed props cannot be picked up.
  • Added Job Configurator coverage for the Crime System, Fire Job, Police speed-camera exclusions, and additional Ambulance locales.
  • Added installed resource versions to the Job Configurator job selector without repeated console output.
  • Improved single-job creator entry management, offline rank updates, AI medic availability refreshes, and FiveManage setup guidance.
  • Job duty is now read fresh from the active framework session instead of being restored from stale local persistence.
  • Improved tablet reopening, radial input, framework job lookup caching, wardrobe metadata, job markers, responsive layouts, and image fallback handling.

Other Changes

  • Added configuration for the prop-offset tool, job chat visibility, fleet sales, and radial submenu timing.
  • Expanded shared and Job Configurator locale coverage across all supported languages.
  • Updated the resource version to 1.33.0.

Version 1.32.0

Update sky_base first - install version 1.29.0 or newer before updating sky_jobs_base.

Highlights

  • Locations can be shared between jobs - selected jobs can reuse a physical location while keeping their own storage, garage, wardrobe, and job configuration separate.
  • Reliable radial toggle and providers - the radial now opens with registered job actions ready, closes consistently with the configured key, and no longer blocks other job interaction keybinds.
  • New shared select controls - management, tablet, and configurator screens now use a consistent searchable select with keyboard navigation and reliable dropdown positioning.
  • Broader Job Configurator support - integer settings, hospital bed fields, wheel-damage groups, and connected job locale coverage have been expanded.
  • More reliable creator and map workflows - creator interactions, trunk actions, hydrant markers, tablet markers, and cleanup behavior now stay aligned more consistently.

Notable Changes

  • Improved management themes - light-theme management views and select dropdowns now remain readable across their supported screens.
  • Better configurator guidance - warnings now appear with the settings they describe, and duplicate creator sections are removed.
  • Hospital and vehicle configuration expanded - hospital creator fields and localized vehicle wheel-damage settings are now available to connected job resources.
  • Database-dependent job registration stabilized - job registration now waits for database migrations to finish.
  • Trunk navigation and availability fixed - trunk prop navigation includes a back action and unavailable trunk options no longer remain usable after a restart.
  • Tablet map behavior improved - map zoom, markers, hydrants, and blip cleanup are more reliable.

Other Changes

  • Added and synchronized configurator locales for ambulance, mechanic, and fire job settings.
  • Standardized internal debug output and refined creator interaction handling.
  • Updated the resource version to 1.32.0.

Version 1.31.0

Update sky_base first - install the matching release before updating sky_jobs_base.

Highlights

  • Expanded shared Job Configurator workflows - the shared configurator now supports broader editing flows, clearer save behavior, and a more consistent setup experience across connected job resources.
  • Improved radial and map interactions - shared radial actions and tablet-map interactions are now more capable and reliable, enabling smoother job-side action flows.
  • Refined shared preview and media handling - item and vehicle previews now resolve more consistently, improving how shared job interfaces present visual content.

Notable Changes

  • Config imports into the Job Configurator - existing local job settings can now be adopted more cleanly into the shared configurator workflow.
  • More flexible save behavior in the configurator - different configuration areas can now be handled more appropriately during editing and saving.
  • Ped previews in configurator flows - supported setup screens now provide better live preview behavior while editing.
  • Remote job map actions expanded - shared tablet-map flows now support broader remote interaction use cases for connected job resources.
  • Improved boss transaction feedback - management and billing-related actions now surface clearer feedback when a transaction cannot be completed.
  • Arabic locale added - sky_jobs_base now includes Arabic language support.
  • Creator and interaction reliability improvements - creator-backed settings and interaction states now stay aligned more consistently during editing and reloads.

Other Changes

  • Locale loading and shared frontend handling were streamlined for better consistency.
  • Documentation and shared configuration guidance were updated for the newer configurator behavior.

Version 1.30.0

Update sky_base first, then update sky_jobs_base before starting the connected job resources.

Highlights

  • Mechanic order parts can now come from job storage - mechanic jobs can choose whether tuning-order parts are taken from the player's inventory or from the shared faction storage.
  • Billing price management was improved - bosses can manage Job Configurator billing prices more reliably, including default prices, saved labels, and custom billing positions.
  • Billing editors are easier to use - structured billing controls and billing price lists now appear directly inside the right Job Configurator pages instead of requiring raw JSON or separate confusing tabs.

Notable Changes

  • Added shared storage helpers so connected job resources can count and remove items from station storage safely.
  • Added the mechanic-only Order item source dropdown to the Job Configurator General page.
  • Bossmenu Billing & Prices now loads default billing prices from the Job Configurator, keeps default rows protected, and supports custom price keys generated from labels.
  • Billing price labels are now saved in the billing specs table and synchronized back into the Job Configurator payload.
  • Resource-owned billing settings now render as normal controls with readonly fields, toggles, selects, and cleaner item-list behavior.
  • Instant Tuning received a dedicated Tuning editor so public tuning locations can be limited to selected categories, stages, and options.
  • Shared debug messages now respect the sky_base debug setting more consistently.

::

Version 1.29.0

Update sky_base first - install the matching release before updating sky_jobs_base.

Highlights

  • Expanded Job Configurator coverage - the shared configurator now supports more advanced setup flows for connected job resources, including richer placement controls, better jail-related editing support, and broader configurable job requirements.
  • Improved billing management workflows - billing-related job settings and price management are now handled more cleanly through the shared admin and configurator flows.
  • Shared prop and storage flows were consolidated - prop placement, trunk access, and shared job storage behavior are now more consistent across supported job systems.

Notable Changes

  • Boss-side billing price management - job billing prices can now be managed more directly through the shared management flow.
  • More reliable configurator editing - placement handling, hospital-related creator flows, decimal inputs, and linked configurator sections now behave more consistently during setup.
  • Config validation improvements - dependent item-use settings now surface clearer warnings when they are configured inconsistently.
  • Wholesale shop grade enforcement - configured grade restrictions are now respected more consistently in wholesale purchase flows.
  • Arabic locale added - sky_jobs_base now includes Arabic language support.
  • Broader localized configurator support for connected jobs - the shared configurator now ships the language support needed for newer ambulance and police configurator flows.
  • Improved item image resolution - item and weapon images are resolved more reliably across different naming styles.
  • Safer boss deposits - boss-menu deposits now handle insufficient-player-balance situations more cleanly.

Other Changes

  • Internal helper cleanup reduced duplicate shared logic across the jobs-base layer.
  • Small frontend utility cleanup improved consistency across shared interface elements.

Version 1.28.0

Update sky_base first - this release depends on the matching sky_base update for job and duty synchronization, tablet item handling, and prop/item flows.

Highlights

  • Job Configurator expansion. The in-game configurator now covers more advanced job setup directly in the UI, including mechanic vehicle-class access, society account and storage settings, advanced color editors, instant tuning profiles, damage-handling editors, dynamic settings, and entry duplication.
  • Better creator-based configurator workflows. The shared Job Configurator now handles creator-backed entry editors more reliably for job-specific location setups such as hospital management.
  • More reliable Multi-Job and duty handling. Multi-job switching, off-duty job handling, duty synchronization, and duty failure feedback are now more consistent, preventing stale or mismatched player state.
  • Shared prop item flow. Job props can now be placed and removed more consistently, with keypress removal support and item returns when a consumed prop is removed.

Notable Changes

  • Shop grade requirements - job shop items can now require a minimum grade, so higher-tier equipment can be restricted without custom scripting.
  • Tablet item handling - tablet usable-item registration now follows the tablet item config more predictably.
  • Shared clothing support - added a shared native clothing engine for resources that need outfit snapshot and restore behavior.
  • Fire job map support - fire hydrants can now appear on the tablet map for fire job workflows.
  • Configurator UX improvements - dropdowns, popups, select controls, interaction defaults, creator context handling, and long editor sections were refined for cleaner admin editing.
  • Live dependent setting updates - configurator dropdowns that depend on creator entries now refresh more reliably after entry changes, so linked settings can reflect newly added, renamed, or removed entries without stale results.
  • Creator entry actions - shared creator-backed configurator sections now support create, save, and delete flows more reliably across resources.
  • Cross-resource option sources - resources can now provide select options to the configurator more cleanly for linked settings that depend on external creator data.
  • Job/location editing flow - supported creator-driven location editors can stay inside the expected job editing workflow instead of forcing a separate disconnected setup path.
  • Radial menu reliability - short taps and quick close/open interactions are now handled more consistently.

Other Changes

  • Added and updated localized configurator labels for the new admin-facing options.
  • Debug output now respects the shared sky_base debug setting for cleaner production consoles.
  • Creator actions now keep their selected entry context more reliably.
  • Numeric configurator fields now preserve decimal-style values more consistently while editing and resetting settings.
  • Refined how creator-related configurator updates propagate after entry edits.

Version 1.27.0

Update sky_base first — this release aligns the inventory calls with the matching sky_base release. Running it against an older sky_base can break item add/remove in storage, lockers, and vehicle trunks.

Highlights

  • Multi-Job admin tooling — a new /multijobadmin command lets admins inspect and edit a player's multi-job list (list / add / set / remove), and a new Config.MultiJob.selfRemoveBlacklist prevents players from removing protected jobs (e.g. police, ambulance) from their own menu. Each stored job now keeps its job and grade labels, so the menu shows consistent names even when framework job definitions change later.
  • Full per-vehicle job-garage attributes — job vehicles can now define livery, vehicle extras, fuel type, primary / secondary / pearlescent / wheel colours, a minimum grade requirement, and a raw vehicle-properties passthrough. These apply to freshly bought vehicles; once a player repaints and parks a vehicle, its stored customization wins. The in-game Job Configurator gained an editable vehicle-attribute table to manage all of this without editing config files.
  • Configurable interaction marker draw distance — interaction points can now set an optional drawDistance to extend marker visibility beyond the default range, with safeguards so it never shrinks below the standard interaction buffer.

Notable Changes

  • Multi-Job switching is cleaner — switching jobs no longer carries the previous job's grade into the target job, and a player's duty state is preserved across a switch. Removing a member from a job now also clears the matching multi-job entry.
  • Per-vehicle trunk control — job vehicles can disable the trunk entirely (trunkEnabled) or just the placeable trunk props (trunkPropsEnabled), and the ambulance stretcher action can be hidden per vehicle (hasStretcher). Trunk interactions now register reliably for vehicles that load late or are spawned dynamically (e.g. externally registered vehicles), with job-gated access.
  • Garage vehicle list stays fresh — the list of allowed job vehicles now refreshes when a job is registered or unregistered and every time the garage menu opens, preventing stale entries. A per-vehicle minimum grade is enforced across the catalog, owned list, purchase, and spawn paths.
  • Job Configurator improvements — long setting lists are now grouped into logical subsections for easier navigation, props gained an item-name field, the active section stays open after saving an entry, and the interaction table scrolls correctly for long lists instead of overflowing.
  • Storage fixes — the transfer popup now opens with an amount of 1 selected (instead of the full stack) while still allowing the maximum, and items that were missing a display name now resolve their label through the active inventory, falling back to the technical name and truncating long labels so cards no longer overflow.
  • Database reliability — identifier columns were converted to a fixed-length type so their unique keys and indexes build correctly on InnoDB servers without innodb_large_prefix (existing tables are migrated automatically). Framework-owned table indexing is now gated by the active framework, so indexes are only attempted on tables that actually belong to your framework.
  • Radial menu — improved selection in hold mode and preserved the target context so radial actions stay reliable.

Other Changes

  • Added Czech (cz) localization and expanded translation coverage for the wardrobe, configurator, and related features across the bundled languages.
  • Migrated internal item add/remove calls to the new sky_base inventory signature (slot + metadata).
  • Rebuilt and verified the jobs-base NUI production bundle.

Version 1.26.0

Highlights

  • New Multi-Job system — a configurable in-game menu (/jobs) lets players hold several jobs and switch between them, including on- and off-duty switching, per-player persistence, admin commands to grant or remove jobs, and full localization.
  • Job Configurator additions — a settings search, per-location on-/off-duty access control, and expanded tuning controls (per-stage enable plus paint/color presets).
  • Lighter, faster in-game interface — the bodycam and tablet camera were rebuilt on native WebGL for a much smaller interface bundle, no-op visual effects were removed, and job-member lists load faster for snappier menus.

Notable Changes

  • Multi-Job menu — configurable through the new Config.MultiJob block (enabled, the /jobs command, an optional keybind, defaultJob, maxJobs, and off-duty switching). Each player's job list is stored persistently, and admins can manage it with the new /givejob and /removejob commands.
  • Off-duty job pairs — Config.MultiJob.autoDetectOffDutyJobs with Config.MultiJob.offDutyPrefix automatically links framework pairs such as ballas and off_ballas. The menu itself gained dynamic colors (policeColor / medicalColor), active-job indicators, a scrollable list, and a protected default job.
  • Per-location duty access — Job Configurator locations can now allow or restrict access for off-duty players.
  • Tuning controls — tuning values can be enabled or disabled per stage, with color/paint presets, decimal steps for number inputs, and the feature navigation staying visible after a job is saved.
  • Tablet improvements — page swipes now work across the whole app grid, the tile layout and tap-to-open were restored, and notifications are routed through their registered app actions.
  • Camera & bodycam — the tablet camera and the bodycam recorder now capture directly through WebGL. The bodycam gained a configurable bitrate cap (recordBitrateKbps) to keep uploads within the storage provider's limits.
  • Configurable ped images — the ped image source can now be set directly from the in-game interface, and the shop supports per-item image overrides.
  • Performance & stability — faster job-member lookups backed by new database indexes for job logs and member queries, removal of no-op backdrop-filter / will-change styling for better interface performance, distance-based streaming of placed job props (propStreamDistance / propStreamDespawnBuffer), and colleague minimap blips that respect access control (showOnMinimap).
  • Reliability — creators clean up correctly when their owning resource stops, creator markers and draw distance are consistent, duty-toggle traffic was reduced, and startup waits for the shared library to be ready to avoid early errors.

Other Changes

  • Added a confiscated-items label and a creator-cleanup notification across all supported locales.
  • Rebuilt and verified the jobs-base NUI production bundle.

Version 1.25.0

Highlights

  • Per-job Nitro access for mechanic jobs — the Mechanic Job Configurator now lets each job inherit the global Nitro setting or explicitly enable or disable Nitro installation and use.
  • Improved Job Configurator controls — marker setting dropdowns remain inside the configurator design without being clipped, and Parts Delivery global controls no longer open the HUD position picker accidentally.

Notable Changes

  • Added a Nitro access selector to the General section of every mechanic job with Use global Nitro setting, Enable Nitro for this job, and Disable Nitro for this job choices.
  • The Nitro selector is only displayed in the sky_mechanicjob configurator and stores its selection directly in the job's nitroAccess value.
  • Existing tuningCostProfile.nitroAccess values remain supported as a compatibility fallback; jobs without either value inherit the global Nitro setting.
  • Added English and German labels explaining that the per-job setting affects Nitro only.
  • The Marker tab's Add marker setting dropdown is now rendered outside its clipped scroll container while retaining the dark Job Configurator design.
  • The marker setting option list now uses a compact scrollable height so it stays within the configurator panel.
  • Parts Delivery Shop switches, number inputs, text inputs, and selectors under Global settings no longer trigger the timer HUD position popup.
  • The Parts Delivery timer position popup now opens exclusively through its dedicated Set position button.

Other Changes

  • Reused the shared custom SelectInput component for the new Nitro access selector.
  • Added dedicated styling for portalled Job Configurator dropdowns, including matching colors, borders, shadows, and highlighted options.
  • Rebuilt and verified the jobs-base NUI production bundle.

Version 1.24.0

Highlights

  • Fully localized mechanic Job Configurator settings — mechanic configuration titles, feature definitions, setting labels, descriptions, option labels, extension labels, and read-only table values now use locale keys throughout the in-game configurator. All bundled locales share the same active workshopConfig structure, with translated coverage for tuning, parts delivery, vehicle care, wheel damage, mileage HUD, instant tuning, carry items, and related settings.

Notable Changes

  • Clearer fixed settings tables — tables that do not allow adding rows now still display their configured title and description. This gives settings such as the mechanic repair-kit restored-parts table the context needed to understand what its values control, while keeping the Add button hidden.
  • Reliable always-on-duty state when the duty system is disabled — when Config.DutySystem is disabled, every player associated with a job now consistently counts as on duty. Player entries created before their job was registered or re-registered are corrected to isOnDuty = true during job registration and immediately synchronized to clients.

Other Changes

  • Removed remaining hardcoded or English-fallback mechanic configurator text from the shared settings UI.
  • Read-only values such as wear parts and vehicle classes can now be translated through locale keys.
  • Rebuilt the jobs-base NUI production bundle so the localization and fixed-table improvements are available in game.

Version 1.23.0

Security update — this release revalidates job & duty synchronization server-side and must be paired with the matching sky_base update. Update sky_base first; running this release against an older sky_base can leave job and duty state out of sync. See Update Instructions.

Highlights

  • Security — job & duty cache revalidated server-side. The events that synchronize a player's job, grade, and duty no longer trust data sent by the client — the cache is re-read from your framework instead. This closes a hole where a manipulated client could spoof its own job, rank, or duty state, which is exactly what every job script relies on for authorization. Requires the matching sky_base update.
  • Performance — the boss menu no longer stalls the server. Opening the management menu used to fire dozens of database queries per open and load the entire job-log table to filter it in memory. Member lookups and log filtering, sorting, and paging now run as single indexed queries, removing the server hitches on busy societies.
  • Expanded in-game Job Configurator. New creator sections, accurate on-screen HUD positioning for extensions (draggable, with a true-to-size preview), and reliable multi-location placement — multiple workshop lifts, delivery bays, dealers, tuning points, and garage points can now be added without overwriting the ones placed before them.

Notable Changes

  • Lockable management editing — a new Config.ManagementEditing block lets you lock the role name, salary, payout interval, and role create/delete/reorder in the boss menu. Locked fields appear read-only and are enforced server-side (changeable only via the database), with an optional per-job override.
  • Write-once job-grade salaries — editing a grade's name or label no longer changes its salary; the salary is set only when the grade is first created.
  • Self-clearing dispatches & auto-closing map — dispatches a player created are now cleaned up (including when they disconnect), and the tablet map can optionally close on its own after a dispatch is accepted (Config.Tablet.map.closeOnDispatchAccept).
  • Vehicle trunk weapons — weapons now display and transfer correctly in vehicle-trunk storage, consistent with shared storage and personal lockers.
  • Reliable duty state on reconnect — a player who toggled duty off through the framework and then disconnected is no longer wrongly restored to on-duty when they rejoin.
  • Faster resource start on busy servers — the player-cache warm-up no longer waits on each offline player one after another, so the cache becomes ready in seconds instead of minutes after a restart.
  • Bodycam recorder is now opt-in — a new Config.Cctv.bodycamRecorderEnabled toggle (default off) controls the client-side bodycam recorder, which can noticeably increase client CPU usage when enabled.
  • New server exports for job & player management — additional integration points so other resources can read and manage job and player state.

Other Changes

  • Lighter, smoother interface — charts load on demand, progress and panic animations now use CSS transitions, and the bodycam preview is frame-rate capped, reducing UI bundle size and client load.
  • Consistent thin scrollbars across long Job Configurator lists, editors, and settings tables.
  • Added the missing weapons tablet-app title in every bundled language.

Version 1.22.0

Highlights

  • Employee GPS jammer — a new item-based jammer (Config.EmployeeGpsJammer) that temporarily hides employees from colleague map tracking in an area. Fully configurable: required item, whether it is consumed, range, duration, cooldown, the play animation, and which jobs may use it.
  • Per-job visibility groups & item gating for map blips / panic / ping — colleague map blips, the panic alert, and pings now support optional per-job groups (control exactly which jobs see or receive them, e.g. police / sheriff / fib sharing) and an optional carried-item requirement (requireItem + item). Defaults keep the previous behaviour.
  • Per-job storage capacities — shared storage and personal locker sizes can now be set per job; the Config.Storage values act as the default for jobs that don't define their own.

Notable Changes

  • A player's on-duty job rank is now preserved and correctly re-applied when toggling off-duty and back on-duty, keeping the primary grade consistent.
  • Management UI — the Roles view now fully refreshes after job/grade changes, ESX job-grade salaries stay in sync, and online members' grades update immediately.
  • Mechanic / workshop storage — physical carry parts can now be withdrawn from workshop storage even when their stored metadata differs from the selected item; normal storage transfers stay strict.
  • Registered creators can now be disabled while keeping their data registered — command, job-based, and permission-bypass opens are blocked with a configurable notification (e.g. when a newer in-game configurator replaces a legacy creator flow).
  • Trunk prop placement improved with per-prop vertical (z) offset support, preserved through the vehicle's trunk state.
  • Added a pedImageBase option to Config.Nui for ped image assets (e.g. fire scenario creator assets).
  • Fixed a redundant garage vehicle deletion that could act on an already-removed entity.

Other Changes

  • The in-game Job Configurator editor, interaction, instant-tuning, and asset-picker text is now fully localized across all bundled languages (English & German translated; other locales fall back to English).
  • Added server-side diagnostics that log when a job configurator has no enabled/active jobs, so misconfigured setups are visible in the server log instead of failing silently.
  • Improved player-cache cleanup with a dedicated unload path (via sky_base:playerUnloaded) that clears a player's entry without preserving duty state.
  • Hardened global config-table initialization so core tables are set up consistently before other config files load.
  • Fixed a German locale typo.

Version 1.21.0

Highlights

  • rcore_clothing wardrobe / job-changing-room backend — the configurable wardrobe (introduced in 1.20.0) now supports rcore_clothing. It is picked up automatically by Config.Cloakroom.backend = "auto", or you can pin it with "rcore". A clear notification is shown if rcore_clothing is selected but not running.
  • Job Configurator enhancements — added an Instant Tuning settings page (Behavior, Marker, Blip, and Locations tabs) with current-position capture and teleport support, clearer Tuning Prices inputs (values rounded to two decimals with a % / $ unit suffix so it is obvious whether a cost is percentage- or money-based), and a transport-mode selector (e.g. Engine Hoist) for Carry Items.

Notable Changes

  • Player names in duty / identity displays now prefer the framework RP / character name, falling back to the Steam/FiveM name only when no character name is available.
  • Improved job & duty state synchronization — client job/duty state is re-evaluated more reliably on load and when jobs are registered, ESX on-duty / off-duty job aliases stay consistent across related job entries, and jobs now fully refresh after creator location changes (no more stale job states).
  • CCTV camera app access is now strictly per-job — jobs sharing a job group (e.g. FIB / LAPD) no longer automatically inherit another job's camera network.
  • Added configurable per-job bodycam visibility via the new optional bodycamViewJobs setting.
  • Added a client-side event that fires when the helicopter camera is entered or exited, so other scripts can react (e.g. toggle HUD elements).
  • Fixed job identification for jobs created through the creator.

Other Changes

  • Fixed bodycam saves occasionally getting stuck on "Saving", and item-gated bodycams appearing active without a recording buffer.
  • Fixed creator interaction labels falling back to raw point IDs; station-blip-only points no longer spawn interactions.
  • Fixed the "salary paid" entry showing a raw key instead of translated text in job logs.
  • The UI now waits for localization to finish loading before rendering, avoiding missing-text flashes on first load.
  • Added server-side duty diagnostics to help trace duty / multi-job conflicts in support cases.
  • Added Portuguese (pt) locale, and extended panic-button and Job Configurator localization across languages (cn, de, en, es, fi, fr, nl, pl, rs, ru, se).

Version 1.20.0

Highlights

  • In-game Job Configurator — a new /jobconfig admin command opens a unified in-game interface to create and manage jobs live: general settings, locations, interactions (markers, blips, peds), vehicles, shops, props, features, and per-job settings. Changes are stored in the database and applied without editing config files by hand. Access is controlled via the new jobconfig entry in Config.CommandPermissions.
  • Configurable wardrobe / cloakroom backend — the cloakroom now works with a wide range of clothing systems through Config.Cloakroom.backend. "auto" detects supported systems (qb-clothing, 17movement, qs-appearance, ak47-clothing, tgiann-clothing, nf-skin, bl-appearance, izzy-appearance, codem-appearance, hex-clothing, illenium-appearance, ESX skinchanger/esx_skin, and more), or you can pin a specific one. A custom hook lets you wire up any other clothing resource. (Supersedes the ESX-only wardrobe from 1.18.0.)
  • Dynamic currency formatting — job payroll and finance amounts now use sky_base's configurable currency formatting, and payouts can target a chosen account via Config.Salary.accountType ("money" / "bank") or a custom sky_base currency via Config.Salary.currency. Requires the matching sky_base release.

Notable Changes

  • Added a global duty toggle Config.DutySystem — set to false to make all job members always count as on duty.
  • Added Jobs Creator support for player duty and job changes — jobs managed through an external Jobs Creator are now recognized for duty state and job switching.
  • The panic feature can now be restricted to specific jobs via Config.Panic.allowedJobs (e.g. police, ambulance); set it to nil to fall back to all registered job-related jobs.
  • Limited vehicle trunk props — job vehicles can carry a configured, limited set of placeable props (e.g. cones, barriers) via per-vehicle props / propCounts in Config.JobGarage.
  • Tablet apps are now configurable per app — hide an app by setting it to false, or use a table (e.g. cctv = { enabled = true, isNew = true }) to show a "new" badge. Tablet apps can also be opened directly from notifications.
  • Added comprehensive validation and logging to job finance operations.
  • Interaction points now support a configurable marker size (per-point markerSize) and an optional per-point interaction distance (e.g. on the duty terminal).
  • Tablet gallery images can now be zoomed with dedicated zoom controls.
  • ox_target actions now support entity-type filtering for more precise targeting.

Other Changes

  • Fixed bodycam saving occasionally getting stuck.
  • Fixed free (0-cost) garage vehicle purchases.
  • Smoother card-sliding UX on the duty terminal.
  • Expanded and updated job localization strings across multiple languages (cn, de, en, es, fi, fr, nl, pl, rs, ru, se).

Version 1.19.0

Highlights

  • Configurable garage behavior - server owners can now disable garage license plate changes globally via Config.JobGarage.allowPlateChange, and optionally warp players directly into spawned garage vehicles with Config.JobGarage.warpIntoVehicle.
  • Panic button in the job radial menu - the panic alert can now be exposed as a radial action with Config.Panic.useRadial, while Config.Panic.useKeybind lets you disable the default panic keybind registration if you want players to trigger panic only through your preferred flow.

Notable Changes

  • Fixed tablet Map zone interactions so zone points and alert markers can be clicked reliably without the map drag handling intercepting the input.
  • Improved tablet Map layout sizing so the map and sidebar stay aligned on more tablet aspect ratios.
  • Fixed map exclusion-zone cleanup so player-owned or occupied vehicles are not removed just because they are inside a zone.
  • Corrected German locale text for the garage and plate-change flow.

Other Changes

  • No additional changes.

Version 1.18.0

Highlights

  • ARGB color hex support — theme color values now accept FiveM-style 8-char hex (FFRRGGBB); the alpha channel is stripped before parsing, so existing 6-char hex colors keep working unchanged. Applies to the tablet Boss Menu theme as well as the matching server-side color handling.

Notable Changes

  • Config.Nui.itemImageBase default reverted to the Sky-Systems CDN — "https://cdn.sky-systems.net/items" is the default again (was nui://ox_inventory/web/images in 1.17.0). Set it explicitly if you prefer the ox_inventory path.
  • Wardrobe is now ESX-only — wardrobe creator interaction points are blocked on non-ESX frameworks with the new localized notification WardrobeUnsupportedFramework. Prevents partial wardrobe flows on unsupported setups.
  • /setboss argument hints — the /setboss command now declares optional job and grade parameters, so framework command-help displays the expected arguments.
  • Added graceful fallback handling for job-registry queries — integrations that look up registered jobs or per-job info before the registry is fully populated no longer error out.
  • Hardened duty-state lookups and made webhook key resolution nil-safe, preventing runtime errors with a partial Config.Webhooks setup.

Other Changes

  • Expanded job localization strings across 9 languages (cn, de, es, fi, fr, nl, pl, rs, ru) — new keys cover faction management (invites, role creation), vehicle garage (purchase, plate changes), cloakroom, interaction labels, and tablet features (CCTV, compass waypoints, station blips).
  • Refined Swedish (se) translations for improved clarity and consistency.

Version 1.17.0

Highlights

  • Management UI revamp — Dashboard, Finance, Members, Roles, Transactions, and Logs views have been redesigned with a more responsive layout, and the Tablet Boss Menu picks up the matching light theme. Role management is now fully flexible: create, reorder, and delete job grades from the UI, and item-based permissions can be assigned per role alongside the existing vehicle, app, and document permissions. ESX servers can now add new grades above the current highest grade — the previous "highest grade is read-only" limitation is gone.
  • Global salary toggle — new Config.Salary.enabled (default true) turns payroll on or off server-wide, and a new server export Sky_Jobs.SetJobSalaryEnabled(jobKey, false) lets you override it per registered job. When salary is disabled the management UI hides the related settings and the server throttles payout-counter writes to reduce database load.
  • Per-job society accounts — registered jobs can now point at a custom shared society account instead of the default society_<jobKey> convention, so multiple jobs can share a single society account (e.g. a city-services group sharing one balance across several sub-jobs).
  • Colleague map blips overhaul — colleague blips are now strictly pause-menu only and use server-snapshot coordinates (including vehicle type and heading) for every blip, instead of switching between live entity blips and stale coordinate blips. Single-instance tracking with explicit cleanup on duty end, pause-menu close, and resource stop. Fixes duplicate blips lingering on the map and the "blip stuck where the colleague used to be" lag for fast-moving colleagues out of streaming range. Configurable via Config.ColleagueMapBlips.pauseMenuSnapshotIntervalMs and pauseMenuRenderIntervalMs.
  • Direct duty status exports — new exports.sky_jobs_base:isPlayerOnDuty(source) (server) and exports.sky_jobs_base:isOnDuty() (client). Integrations can check on-duty state directly instead of reaching into the Sky_Jobs root table.

Notable Changes

  • Fixed setOfflineJob running both the QBCore and ESX update helpers on every non-Qbox framework, which spammed Table doesn't exist warnings in oxmysql logs whenever the wrong helper queried the missing framework table. The function now branches explicitly on Sky.Config.framework.
  • Fixed tablet prop cleanup deleting third-party prop_cs_tablet props (other phone or tablet resources) within ~1s of closing the Sky tablet. Cleanup is now restricted to the tablet prop sky_jobs_base actually spawned.
  • Fixed the tablet keeping NUI focus during its close animation — focus is now released as soon as the close animation starts, so chat and vehicle controls return immediately.
  • Standardized item image lookup — the legacy Config.Nui.useOxInventoryImages toggle was removed. The default Config.Nui.itemImageBase is now nui://ox_inventory/web/images; set it to "https://cdn.sky-systems.net/items" (or any other base path) if you want the Sky-Systems CDN icons or a custom source.
  • Removed the Billing Presets section from the management menu — the section is no longer part of the management flow.
  • Cloakroom outfit list now scrolls internally instead of growing the whole cloakroom view when many outfits are configured.

Other Changes

  • Internal: job grade calculation was consolidated through the shared Job.GetHighestGrade helper across the server and the role editor. Behaviour change is limited to the next-grade default being more reliable when the job currently has no grades.

Version 1.16.0

Highlights

  • Wardrobe outfits can now be restricted by role / job grade - outfit editors can define which grades may use an outfit. The cloakroom UI shows unavailable outfits as disabled, and the server enforces the restriction when an outfit is applied.
  • Mechanic carry props can now integrate with station storage - when sky_mechanicjob is running, supported carried props can be deposited into station storage from the storage interaction and withdrawn back into the carry system.
  • Added server exports AddStorageItem(...) and AddStorageItems(...) so trusted integrations can add one or many items directly to station storage while respecting storage capacity.

Notable Changes

  • CCTV tablet app access now works for every job in the same registered job group instead of only one exact job key.
  • Tablet map labels no longer clip in tight layouts.

Other Changes

  • Added Russian (ru) translation.
  • Enhanced tablet homescreen details

Version 1.15.0

Highlights

  • New admin permission system — /setboss no longer uses Sky.FW.IsAdmin; it now resolves via FiveM ACE (sky_jobs_base.setboss) auto-wired from Config.CommandPermissions at server start. Sky_Jobs.RegisterCreator accepts a new opts.permission parameter (e.g. "sky_policejob.stationcreator") that the creator command and the openCreatorByJob NUI path consume directly; the legacy permissionResource / permissionCommand pair is preserved for backward compatibility. Fixes admin commands silently denying admins on QBox after qbx_core:HasPermission was deprecated in qbx_core v1.8.0.
  • Live colleague map blips for every Sky job — the world-map blip system that shows on-duty colleagues moved from sky_policejob into sky_jobs_base under the neutral name Config.ColleagueMapBlips (was Config.OfficerMapBlips). The implementation was already job-agnostic; it now ships in the right resource so every Sky job (ambulance, mechanic, custom jobs, …) gets the feature without copy-pasting code. Blips now render whenever the player is on-duty — visible on the minimap during normal gameplay, on the pause-menu map, and on the tablet map. Server owners who prefer a clean minimap can opt out via the new Config.ColleagueMapBlips.showOnMinimap = false (blips then stay on the big maps only). The server pushes a fresh per-job snapshot every ~1s instead of each client polling every 3.5s — fixes the customer-reported "blip at the place where the person was but isn't anymore" lag for fast-moving colleagues out of streaming range.
  • Added Sky_Jobs.OpenCreatorByJobWithoutPermission(source, jobKey) server export (and matching exports.sky_jobs_base:openCreatorByJobWithoutPermission) — opens the station creator for a player by job key without running the permission check. Intended for admin tooling and trusted integrations that have already authorized the caller upstream.
  • Interaction points now respect a forceMarkerInteraction flag on the creator entry definition — that single interaction always uses marker + help notification, even if a target backend (ox_target / qb-target) is active on the server. Pairs with the matching sky_base 1.14.0 feature.

Notable Changes

  • Fixed public interactions being unreachable for players whose current job didn't match the creator entry's jobKey. The 1.14.0 job-locking security check was too strict and also blocked entries explicitly marked public = true; those are now exempt while non-public entries stay job-locked as before.
  • /dutytest (debug command) now resolves via Config.CommandPermissions.dutytest instead of a hardcoded group.admin ACE lookup. Server owners can broaden access (e.g. add supporter) or restrict it via the same table as every other admin command.
  • Server-side map broadcast now routes name and grade lookups through Sky_Jobs.PlayerCache instead of Sky.FW.* — silences the per-second debug spam (Sky.FW.GetName(N), Sky.FW.GetJobData(N, grade), …) that flooded the console on servers with Sky.Config.debug = true. No behaviour change.
  • Wholesale shop purchases now accept free items (price 0) — parity with the per-job shop change shipped in 1.12.0.
  • Tablet Boss Menu and Tablet Chat views: fixed content overflow and inconsistent scrolling on long member/message lists.
  • Tablet Map app is now responsive — layout adapts cleanly to different tablet aspect ratios, the marker list pane resizes properly on narrow widths, and the Home view exposes the Map app at the correct size for tablets running in alternate UI scales.
  • Fixed panic / ping alerts being delivered to players of unrelated jobs. When a channel's allowedJobs filter was left empty, the system previously allowed any on-duty player to receive the alert; it now restricts delivery to players whose current job is a registered Sky job (or a linked off-duty variant). Setups that customized Config.Panic.allowedJobs / Config.Ping.allowedJobs are unaffected.
  • New Sky_Jobs.IsJobRelated(jobKey) server helper + sky_jobs_base:isJobRelated callback for integrators that need to check whether a job is registered with Sky_Jobs (covers both on-duty and linked off-duty job keys).
  • Server console now prints a clearer info message when the FiveManage API key is missing, instead of a silent fallback.

Other Changes

  • Added Swedish (se) translation.

Version 1.14.0

Highlights

  • Security fix: the server now enforces job ownership on every creator-interaction request (boss menu, wardrobe, storage, garage, …). Players whose current job doesn't match the station's assigned job can no longer reach those interactions.

Notable Changes

  • Garage: simplified the vehicle reclamation logic — reclamation now follows only the offline-and-unresolvable check introduced in 1.13.0, so vehicles no longer flip back to "stored" in additional edge cases.
  • A misconfigured pedHash in Config.Interactions now skips just that one NPC with a warning instead of aborting the rest of the interaction rebuild.
  • Boss menu / job-data lookups now handle unknown jobs or malformed grade tables gracefully instead of failing with a runtime error.

Other Changes

  • Tablet map dispatch details: action button labels now wrap inside their boxes so longer translations no longer overflow.

Version 1.13.0

Highlights

  • Added a new sky_jobs_base:creator:pedSpawned client event — consuming resources can react to creator NPC spawns through a single event handler instead of registering hooks per interaction.
  • Custom storage UI now accepts .webp background images alongside PNG/JPG.
  • CCTV tablet app is now only shown for police and ambulance jobs.

Notable Changes

  • Fixed garage vehicles flipping back to "stored" status when a player parked out and the vehicle briefly lost server scope. Reclaim now requires the owner to be offline AND the vehicle unresolvable for ~90 seconds before being marked stored, instead of triggering after a single 30 s tick.
  • Fixed Config.Interactions[*].scenario and onSpawn not re-applying when an existing NPC was reused on creator rebuild (job / duty change). Hooks now also run on reuse, not only on fresh spawns.
  • Fixed helicopter cam target lock not releasing in some cases.

Other Changes

  • No additional changes.

Version 1.12.0

Highlights

  • Job radial menu and target integration now work under both ox_target and qb-target — follows the new Config.target selector introduced in sky_base 1.11.0.
  • Added a tablet push-notifications API — external resources can push notifications onto the tablet home screen.
  • Free items (price 0) are now allowed in per-job shops and the wholesale shop. Negative prices are still rejected.
  • Trunk prop placement is now exposed as a reusable export with optional confirmation callback, so external resources can consume an item only after placement is confirmed.

Notable Changes

  • Fixed Config.Interactions[*].onSpawn callbacks not firing for interaction NPCs. The scenario option was unaffected. External resources that need spawn-time customization (outfits, props, weapons) should register hooks via the documented client-side API.
  • Fixed garage vehicle purchase confirmation modal showing English fallback text — added the missing confirmPurchaseTitle, Confirm, Cancel, Message, purchaseSuccessTitle, and Message keys to all 9 locales.
  • Locale drift cleanup across CN, ES, FI, FR, NL, PL, RS — restored missing keys for the garage plate editor, CCTV / Map waypoint actions, station creator job-blip modals, tablet missingItem state, panic / ping mapping descriptions, and CameraUploadFailed.
  • Fixed speedcam image capture failure.
  • Config.JobRadial comments updated to reference the new Config.target from sky_base instead of the removed enableOXTarget flag (no behaviour change for existing values).

Other Changes

  • No additional changes.

Version 1.11.1

Highlights

  • Tablet now reopens the last-used app automatically after closing and reopening the tablet.
  • ox_target interaction labels are now fully localized — added a new InteractionLabels table in all 9 languages (CN, DE, EN, ES, FI, FR, NL, PL, RS). Manual overrides via Config.Interactions[id].label still take precedence.
  • Interaction NPCs now support optional scenario and onSpawn fields in Config.Interactions — NPCs can play a GTA scenario on spawn and run custom setup code (outfits, props, extra tasks).
  • Security fix: helicopter spotlight events are now validated against Config.HeliCam.allowedJobs and duty status, blocking non-authorized players from griefing with spotlights.

Notable Changes

  • Default Config.JobRadial.mode changed from hold to toggle.
  • Grade change notifications now show richer info and update live.
  • Fixed ox_target radial actions becoming unclickable after the first trigger.
  • Station creator blip handling refined.
  • Map exclusion zones now require police-group access.
  • Fixed rare server errors during public forms, gallery, and chat interactions.
  • Dispatch now cleans up correctly when a player disconnects.

Other Changes

  • CCTV bodycam cache is released when a player disconnects.
  • Refreshed mechanic and tuner card artwork.
  • Table header rendered transparent again.
  • General server-side performance improvements.

Version 1.11.0

Highlights

  • Storage, locker, and vehicle trunk now track item metadata as a separate stack — items with different metadata no longer collide under the same unique key (new metadata_key column and refreshed unique indexes).
  • Added ox_target integration for job radial actions (Config.JobRadial.oxTarget.enabled) so non-tablet actions can be triggered through ox_target without opening the radial menu.
  • Added optional tablet item requirement (Config.Tablet.requireItem + Config.Tablet.item) — when enabled, the tablet is registered as a usable item and required to open.
  • Added openCreatorByJob server export (Sky_Jobs.OpenCreatorByJob) to open the station creator by job key with per-job permission checks.

Notable Changes

  • Boss menu salary input rebuilt with an improved SliderInput component (unit labels, direct numeric entry, validation).
  • Weapon metadata is now preserved through garage and storage add/remove operations.
  • CCTV network is now shared across police sub-jobs.
  • Storage metadata-index migration now auto-resolves the correct prefix length from each column's declared type (VARCHAR/CHAR/TEXT/BLOB).

Other Changes

  • Added missing translations across all 9 locales (CN, DE, EN, ES, FI, FR, NL, PL, RS).
  • Fixed spurious error notification on every shop weapon purchase.

Version 1.10.0

Highlights

  • Added prop placement with in-game editor to the station creator.
  • Added license plate change feature in the garage menu with permission checks and DB sync.
  • Added per-job blip configuration directly from the creator UI (sprite, color, scale, display, short range).
  • Added garage vehicle grade restrictions — vehicles can now be locked behind job grades.

Notable Changes

  • Map App now has a button to set waypoints to station markers.
  • Added tablet:openHome event for external scripts to open the tablet to the home screen.
  • Creator placement settings for fine-tuning marker/interaction point positions.
  • Improved InputModal component with better validation and layout.

Other Changes

  • Comprehensive translation update across all 8 languages (CN, ES, FI, FR, NL, PL, RS, DE).
  • Fixed missing garage plateEditor and status locale keys in EN and DE.
  • Fixed merge conflicts in ES and FI locale files.
  • Fixed missing translation keys in garage interface.

Version 1.9.0

Highlights

  • Added auto database migration (Config.AutoExecuteQuery) — missing tables and columns are created automatically on resource start.
  • Added dedicated fuel and fuel_type columns for job vehicles, persisted via the sky_base fuel bridge.
  • Added salary pause/resume exports (pausePlayerSalary, resumePlayerSalary, isPlayerSalaryPaused) to prevent paycheck farming via AFK.
  • Added unsaved changes confirmation popup in the Roles view.

Notable Changes

  • Roles can now only manage roles with a lower rank.
  • Management interfaces now rebuild client-side when a player's job or grade permissions are updated via boss command.
  • Vehicle mods and liveries are now safely persisted in the garage system.
  • Migration logic now uses centralized Sky.DB.Migrate() from sky_base.
  • Preserved NPCs are now repositioned when creator points are moved.
  • Added retry logic for Sky_Jobs export loading.

Other Changes

  • Added radial menu open sound.
  • Fixed "not on duty" notify not appearing.
  • Disabled default station blips for hospital creator points.
  • Added missing translation keys for wardrobe, billing, finance, garage, and management views.

Version 1.8.0

Highlights

  • Added external garage integration exports for trunk/prop functionality with third-party garage systems.
  • Radial menu default changed from toggle to hold mode.

Notable Changes

  • Station map blips are now visible for all players; interaction points remain job-filtered.
  • Optimized CCTV bodycam validation with native framework functions and preserved cache on duty transitions.
  • Panic button now notifies off-duty players within notification scope.
  • NUI focus is disabled in creator menu to prevent input conflicts.

Other Changes

  • Garage location is now automatically set when clicking Add in creator menu.
  • Creator menu now plays navigation sounds for UX feedback.
  • Station blips set to short range to reduce map clutter.
  • Fixed station creation failing in creator menu.
  • Added missing CCTV config section (Config.Cctv).

Version 1.7.0

Highlights

  • Fixed SIGSEGV crash caused by screenshot-basic server export; uploads now go directly from client via presigned URL.
  • FiveManage API migrated from V2 (fmapi.net) to V3 (api.fivemanage.com) with unified baseUrl.
  • Removed hard screenshot-basic dependency from fxmanifest.

Notable Changes

  • FiveManage API key is no longer sent to the client during video uploads.
  • Fixed trunk transfer failures caused by incorrect return-value comparison.
  • Item metadata is now preserved through trunk transfers.
  • Garage now retries alternative spawn points when primary is blocked.
  • Server now tracks occupied spawn points to prevent concurrent spawn collisions.
  • Duty state is persisted by identifier and restored on rejoin.

Other Changes

  • NPC entities are preserved during job interaction rebuilds instead of being respawned.
  • Managers are now notified of member list changes on disconnect.
  • Reduced CPU overhead by increasing sleep intervals in non-time-sensitive loops.
  • Added TTL caching for CCTV plate lookups.
  • Added early exits in idle threads (CCTV, panic alerts, salary processing).
  • Replaced many direct framework calls with PlayerCache-first helpers.
  • Added Finnish translation.

Version 1.6.0

Highlights

  • Shop items now support quantity input for bulk purchases.
  • Locker and station storage now support item metadata for ox_inventory.

Notable Changes

  • Added CCTV/speedcam waypoint button to set GPS markers from tablet.
  • Added configurable station map blips.

Other Changes

  • Updated German translations and added new English locale keys.

Version 1.5.0

Highlights

  • Radial menu now supports hold and toggle modes with improved input blocking.
  • Added infinite scrolling and backend pagination for transaction logs.
  • Added localization and UI for vehicle selling feature.

Notable Changes

  • Table component now includes sticky headers, row limits, and text truncation tooltips.
  • Duty status changes now include retry logic with immediate UI feedback on failure.
  • Improved identifier resolution and job-data synchronization across resource starts.
  • Job creator now supports boat dock markers and interaction points.
  • Finance UI now refreshes in real-time through server triggers.
  • Refined duty-time tracking and salary payout calculations.

Other Changes

  • Player cache operations now gate on framework load state.
  • Calendar reminder polling now handles app availability more robustly.
  • Table timestamps now render in fixed German locale.
  • Hardened player cache refresh during initialization with protected calls.
  • Optimized server performance by caching job data and bodycam item status.
  • Removed calendar debug logging.
  • Added Chinese translation.
  • Added payroll localization strings across all languages.

Version 1.4.0

Highlights

  • Added image gallery and screenshot capture system with secure uploads.
  • Added boat garage support.
  • Added job invitation system with interactive popup.

Notable Changes

  • Added My submissions section in public forms.
  • Staff can now add internal or citizen-visible notes to public forms.
  • Added custom background image support for custom storage UI.
  • Added option to disable Go Back button in custom storage.
  • Panic ping and dispatch now use registered key mappings.
  • Ping and panic markers now auto-remove after configurable duration.
  • Radial menu now only shows for registered jobs.

Other Changes

  • CCTV now respects player visibility settings.
  • Improved unregistered-job duty handling.
  • Improved health percentage calculation to avoid negative values.
  • Improved member online/offline accuracy and multichar identifier resolution.

Version 1.1.1

Highlights

  • Hotfix: fixed storage bug.

Notable Changes

  • No additional notable changes documented.

Other Changes

  • No additional changes documented.

Version 1.1.0

Highlights

  • Added /setboss [job] [grade] command for boss/wholesale fallback access assignment.
  • Added option to disable tablet apps or entire tablet.
  • Added back off-duty job support.

Notable Changes

  • Fixed locale issues and missing locale entries for tablet apps.
  • Fixed duplicate NPC spawn on player join.
  • Fixed go-on-duty radial notify behavior when player lacks job.

Other Changes

  • Fixed NPC heading application.
  • Added image path config support.
  • Fixed dashcams and vehicles on map.

Screenshot & Webhook Update

Highlights

  • screenshot-basic is no longer a hard dependency.
  • Screenshot uploads now run client-to-FiveManage via presigned URLs (no server temp files).
  • FiveManage API updated from V2 to V3 endpoints.

Notable Changes

  • Video uploads now use presigned URLs for improved security.
  • Webhook config simplified to single baseUrl.

Other Changes

  • FiveManage SDK resource is no longer required for sky_jobs_base.