Before updating, make sure sky_base is up to date.
Current
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 InstructionsA guided update for server owners1.48.01.48.1
Guided update
Update sky_jobs_base safely
Complete the five phases in order. Your progress is kept while this page remains open.
0 / 5phases complete
Phase 1 of 5
Prepare
These instructions cover sky_jobs_base1.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.
Phase 2 of 5
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.
Phase 3 of 5
Merge config
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.
Phase 4 of 5
SQL & items
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.
Phase 5 of 5
Restart & test
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 InstructionsA guided update for server owners1.47.11.48.0
Guided update
Update sky_jobs_base safely
Complete the five phases in order. Your progress is kept while this page remains open.
0 / 5phases complete
Phase 1 of 5
Prepare
These instructions cover sky_jobs_base1.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.
Phase 2 of 5
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
Phase 3 of 5
Merge config
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:
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.
Phase 4 of 5
SQL & items
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.
Phase 5 of 5
Restart & test
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.
Update InstructionsA guided update for server owners1.47.01.47.1
Guided update
Update sky_jobs_base safely
Complete the five phases in order. Your progress is kept while this page remains open.
0 / 5phases complete
Phase 1 of 5
Prepare
These instructions cover sky_jobs_base1.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.
Phase 2 of 5
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.
Phase 3 of 5
Merge config
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.
Phase 4 of 5
SQL & items
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.
Phase 5 of 5
Restart & test
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.
Update InstructionsA guided update for server owners1.46.01.47.0
Guided update
Update sky_jobs_base safely
Complete the five phases in order. Your progress is kept while this page remains open.
0 / 5phases complete
Phase 1 of 5
Prepare
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.
Phase 2 of 5
Replace 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.
Phase 3 of 5
Merge config
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 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:
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.
Phase 4 of 5
SQL & items
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.
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.
Phase 5 of 5
Restart & test
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.
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 InstructionsA guided update for server owners1.45.01.46.0
Guided update
Update sky_jobs_base safely
Complete the five phases in order. Your progress is kept while this page remains open.
0 / 5phases complete
Phase 1 of 5
Prepare
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_base1.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.
Phase 2 of 5
Replace 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.
Phase 3 of 5
Merge config
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:
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.
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.
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.
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 key
Previous state
New state and operator action
printerSettings.inkCapacity
Shared 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.inkRefillAmount
Shared 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].deleteCopiesAfterRestart
Absent.
New boolean, default false. Set true only for printers whose uncollected ready copies should be cleared when the service starts.
printers[i].remoteEnabled
Boolean, 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].temporaryAllowed
Boolean, 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.
Phase 4 of 5
SQL & items
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.
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 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.
Phase 5 of 5
Restart & test
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.
Update InstructionsA guided update for server owners1.44.01.45.0
Guided update
Update sky_jobs_base safely
Complete the five phases in order. Your progress is kept while this page remains open.
0 / 5phases complete
Phase 1 of 5
Prepare
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.
Phase 2 of 5
Replace 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.
Phase 3 of 5
Merge config
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:
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.
Phase 4 of 5
SQL & items
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:
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.
Phase 5 of 5
Restart & test
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 InstructionsA guided update for server owners1.43.11.44.0
Guided update
Update sky_jobs_base safely
Complete the five phases in order. Your progress is kept while this page remains open.
0 / 5phases complete
Phase 1 of 5
Prepare
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.
Phase 2 of 5
Replace 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.
Phase 3 of 5
Merge config
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:
Path
Previous state
New shipped value / setting
Config.UseIngameConfigurator
Absent
true; choose the migration mode above.
Config.MenuColor
Absent
"#1DD1CE"; Jobs Base setting MenuColor.
Config.Tablet.apps.forms_archive
Absent
true; Jobs Base Tablet → apps → forms_archive.
Config.Dispatch.radioKeybind
Fixed default in the radio setup
"F10"; Jobs Base Dispatch → radioKeybind. Player key rebindings remain personal.
Config.HeliCam.visionModes
Both modes available
The complete block below; Jobs Base HeliCam → visionModes.
Config.RecordAccess
Absent
The complete block below; Jobs Base → Organization → Record access.
Config.Registries
Absent
The 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.
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.
Phase 4 of 5
SQL & items
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 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.
Phase 5 of 5
Restart & test
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 InstructionsA guided update for server owners1.43.01.43.1
Guided update
Update sky_jobs_base safely
Complete the five phases in order. Your progress is kept while this page remains open.
0 / 5phases complete
Phase 1 of 5
Prepare
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.
Phase 2 of 5
Replace 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.
Phase 3 of 5
Merge config
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.
Phase 4 of 5
SQL & items
No SQL, item or locale migration is required. Preserve jobs, locations, permissions, catalog entries and saved vehicles; do not reset or reimport the database.
Phase 5 of 5
Restart & test
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.
Update InstructionsA guided update for server owners1.42.01.43.0
Guided update
Update sky_jobs_base safely
Complete the five phases in order. Your progress is kept while this page remains open.
0 / 5phases complete
Phase 1 of 5
Prepare
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.
Phase 2 of 5
Replace 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.
Phase 3 of 5
Merge config
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.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.
Phase 4 of 5
SQL & items
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.
Phase 5 of 5
Restart & test
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 InstructionsA guided update for server owners1.41.21.42.0
Guided update
Update sky_jobs_base safely
Complete the five phases in order. Your progress is kept while this page remains open.
0 / 5phases complete
Phase 1 of 5
Prepare
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.
Phase 2 of 5
Replace 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.
Phase 3 of 5
Merge config
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.
Phase 4 of 5
SQL & items
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.
Phase 5 of 5
Restart & test
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 InstructionsA guided update for server owners1.41.11.41.2
Guided update
Update sky_jobs_base safely
Complete the five phases in order. Your progress is kept while this page remains open.
0 / 5phases complete
Phase 1 of 5
Prepare
Use sky_base1.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.
Phase 2 of 5
Replace files
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.
Phase 3 of 5
Merge config
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.
Phase 4 of 5
SQL & items
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.
Phase 5 of 5
Restart & test
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.
Update InstructionsA guided update for server owners1.41.01.41.1
Guided update
Update sky_jobs_base safely
Complete the five phases in order. Your progress is kept while this page remains open.
0 / 5phases complete
Phase 1 of 5
Prepare
Use sky_base1.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.
Phase 2 of 5
Replace files
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.
Phase 3 of 5
Merge config
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.
Phase 4 of 5
SQL & items
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.
Phase 5 of 5
Restart & test
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 InstructionsA guided update for server owners1.40.01.41.0
Guided update
Update sky_jobs_base safely
Complete the five phases in order. Your progress is kept while this page remains open.
0 / 5phases complete
Phase 1 of 5
Prepare
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.
Phase 2 of 5
Replace files
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.
Phase 3 of 5
Merge config
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:
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:
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:
Path
1.40.0
1.41.0
Config.Dispatch.legacyAlertBanner
absent
false
Config.Dispatch.centers[2].primaryJobs in the shipped ems_dispatch profile
absent
{ "ambulance", "fire", "firefighter" }
Config.Panic.allowedJobs
nil, allowing registered jobs
{ "police", "ambulance", "fire" }; nil or {} now denies everyone
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 /jobconfigGeneral → 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.lua
Previous behavior
New behavior
Saved interaction field
Config.Interactions[interactionId].useStationName
No supported switch; the station prefix was always included
Omitted means true; set false to hide the prefix
interactions[interactionId].useStationName
Config.Interactions[interactionId].npc.name
Existing optional editor field was ignored by interaction prompts
A nonblank name is used when the NPC is enabled; blank or disabled NPCs retain the localized interaction label
interactions[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:
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.
Phase 4 of 5
SQL & items
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.
Phase 5 of 5
Restart & test
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.
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 InstructionsA guided update for server owners1.39.01.40.0
Guided update
Update sky_jobs_base safely
Complete the five phases in order. Your progress is kept while this page remains open.
0 / 5phases complete
Phase 1 of 5
Prepare
Install Base 1.37.0, stop the server, and back up the complete sky_jobs_base folder, Job Configurator data, all sky_jobs_* tables, existing dispatch information, and generated reports. Record local dispatch centers, permission mappings, radio choices, external phone callbacks, management extensions, tablet access, and intentional webhook/provider edits.
1.40.0 is a coordinated runtime, frontend, locale, and schema release. Install it as one complete package and keep dispatch_reports writable by the server process.
Phase 2 of 5
Replace files
Delete and reinsert the complete resource. At minimum replace fxmanifest.lua, import.sql, config/config.lua, config/init.lua, the complete config/locales and source directories, and the built frontend. Retain the included dispatch_reports/.gitkeep; the runtime writes generated reports below this directory.
Phase 3 of 5
Merge config
Start from the new file and merge local choices into the new structures. The principal shipped changes are:
Config path
1.39.0
1.40.0 shipped value / action
Config.Tablet.computerAccess
Absent
Added and enabled; station radius 100.0, interaction distance 1.0, configured animation, and bundled computer prop list
Config.Tablet.vehicleAccess
Absent
Added and disabled with an empty vehicle list
Config.Tablet.apps.personal_notes
Absent
Added with enabled = true and isNew = true
Config.Dispatch.enabled
false
true
Config.Dispatch.readyStatusCode
Absent
1
Config.Dispatch.respondingStatusCode
Absent
3
Config.Dispatch.announcement.enabled
true
false
Config.Dispatch.announcement.allowedAudioHosts
Absent
Added allowlist; add only trusted media hosts
Config.Dispatch.jobConfiguratorExtensions
Present
Removed; the dispatch schema is now resource-owned on the server
Config.EmergencyDispatch.server.dispatch.mode
Absent
"sky_only"
Replace the full Dispatch block so its rate limits, radio, enhanced workspace, operations, notifications, resilience, boss permissions, public warnings, SDS, centers, callback handoff, announcement allowlist, status codes, and field options remain aligned. Status-code labels are now locale-owned. Review every configured center and permission before production use. Valid emergency forwarding modes are documented beside Config.EmergencyDispatch.server.dispatch.mode; retain "sky_only" unless external forwarding is intentionally configured.
/jobconfig stores Jobs Base and resource extensions separately from low-level plaintext runtime values. On first start, the new migration records dispatch_defaults_migrated and moves applicable saved defaults into the new schema. Review restored defaults before editing them again. Keep config/webhooks.lua private: the distributed apiKey value is empty and must only be populated with a newly issued server credential when media upload is required.
Phase 4 of 5
SQL & items
With automatic migrations enabled, start Jobs Base once and wait for the migration-success log before dependent jobs start. With automatic migrations disabled, run the complete 1.40.0import.sql; do not apply only selected statements. It performs these coordinated changes:
Extends sky_jobs_calendar_events with end timestamp, location key, source type/id, public visibility, and supporting indexes.
Adds dispatch_defaults_migrated to sky_jobs_configurator_settings.
Creates sky_jobs_personal_notes.
Extends dispatch incidents, incident units, and audit data with center, call, forwarding, command, closure, priority, source, token, plate, and object identifiers.
Creates persistent dispatch units, unit members, assignments, alarm attempts, map features, broadcasts, SDS unit messages, calls, and center chat.
Ensures all dispatch tables use InnoDB for the required transactional and foreign-key behavior.
Existing rows are preserved by the migration. Back up first and do not downgrade the schema without a tested restoration. Add printer_paper to the inventory only if your enabled printer workflow consumes that item; there is no bundled item registration, image, or stream asset migration.
Phase 5 of 5
Restart & test
Start sky_base, then sky_jobs_base, and confirm all migrations complete before starting job resources. Test unit and dispatcher access with allowed and denied roles; create, assign, transfer, close, and reopen representative calls/incidents; verify multi-crew units, response plans, center fallback, radio preferences, tactical-map persistence, public warnings, SDS, chat, announcements, phone callback handoff, and PDF output. Test tablet access at a configured computer and with vehicle access both disabled and enabled, personal-note persistence, a configured printer queue, gang/job management precedence, calendar hearing fields, qualification restrictions, Job Configurator default restoration, garage/tuning cancellation paths, CCTV diagnostics, and a reconnect/restart cycle.
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 InstructionsA guided update for server owners1.38.11.39.0
Guided update
Update sky_jobs_base safely
Complete the five phases in order. Your progress is kept while this page remains open.
0 / 5phases complete
Phase 1 of 5
Prepare
Before updating, install sky_base1.36.0, stop the server, and back up the resource, intentional config edits, Job Configurator tables, sky_jobs_vehicles, and any existing world-prop integration data.
Install 1.39.0 as one clean package. Its UI, locales, manifest, migrations, and source runtime must match.
Phase 2 of 5
Replace files
Delete and reinsert the complete resource. At minimum replace fxmanifest.lua, import.sql, config/config.lua, the complete config/locales and source directories, and the built UI supplied in the package.
Phase 3 of 5
Merge config
The new settings are plaintext/global policy and are not /jobconfig values. Both paths were absent in 1.38.1 and ship with false in 1.39.0:
config/config.lua
Config.ForceOffDutyOnLogin = false
Add persistPlacedProps to the existing block without changing its neighboring policy values or item catalogue. These two executable assignments show the exact release defaults:
In the table definition, insert persistPlacedProps = false between unchanged returnItemOnRemove = true and the existing items = { ... } catalogue. Set Config.ForceOffDutyOnLogin = true only to force every duty-capable player off duty after each framework login. Set Config.PropPlacement.persistPlacedProps = true only to save newly placed configured props in sky_jobs_placed_props and restore them after restarts.
/jobconfig continues to manage normal resource/job settings. Existing saved jobs and feature choices remain valid; no new required setting key is introduced by this release. The expanded tuning-pricing controls, warning text, impound wording, and dependent-resource fields arrive through the replaced UI and locale packages.
Phase 4 of 5
SQL & items
With Config.AutoExecuteQuery = true, the built-in migration performs the following changes automatically. With it disabled, execute the complete bundled import.sql after Base is updated:
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`) = '[]';
The complete table definition for new installations also uses state ENUM('stored', 'parked', 'impounded'), stores the seven new fleet columns, and adds idx_job_state (job, state). These definitions inherit the active database charset and collation. No new inventory item, image, or provider credential is required.
Phase 5 of 5
Restart & test
The console reports Base 1.36.0 before Jobs Base 1.39.0 starts.
sky_jobs_vehicles.state accepts impounded, all seven new columns exist, and idx_job_state is present.
sky_jobs_placed_props exists and empty Job Configurator settings are stored as {}.
Fleet parking, retrieval, reconnects, and keys return control to the current driver.
An authorized dependent job can impound and release a fleet vehicle with its reason and fee intact.
Config.ForceOffDutyOnLogin and Config.PropPlacement.persistPlacedProps each honor both false and true deliberately.
Shared training, recruitment, missing off-duty mapping warnings, and external tablet reinstallation work after a job change.
Placed items, trunk props, barriers, and tape can be removed once, return their item once, and restore only when persistence is enabled.
Exclusion-zone NPC cleanup remains effective when the closest client does not own the entity.
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 InstructionsA guided update for server owners1.38.01.38.1
Guided update
Update sky_jobs_base safely
Complete the five phases in order. Your progress is kept while this page remains open.
0 / 5phases complete
Phase 1 of 5
Prepare
Update Base to 1.35.1, stop the server, and back up the Jobs Base resource plus intentional config edits.
Install 1.38.1 as one clean package; its config, UI, locales, manifest, and runtime must match.
Phase 2 of 5
Replace files
Delete and reinsert the resource. Replace config/config.lua, fxmanifest.lua, the built UI, config/locales, and source completely.
Phase 3 of 5
Merge config
Both changes are plaintext/global policy and not normal /jobconfig settings:
config/config.lua
Config.Dispatch.enabled = false -- was true in 1.38.0
Config.Salary = {
enabled = true,
deductFromSocietyFunds = true, -- new in 1.38.1
accountType = "bank",
currency = nil,
payIntervalsWhileOnDuty = true,
defaultIntervalMinutes = 30,
minIntervalMinutes = 10,
maxIntervalMinutes = 180
}
Set deductFromSocietyFunds = false only when salaries should be created without society-fund validation or deduction.
Phase 4 of 5
SQL & items
No SQL, inventory item, image, stream asset, or provider credential changed.
Phase 5 of 5
Restart & test
Base 1.35.1 starts before Jobs Base 1.38.1.
Disabled Dispatch uses legacy notifications; enabling it deliberately restores the full app.
Funded payroll stops at insufficient society funds when true and pays without deduction when false.
Garage states and untranslated frontend keys show readable fallback labels.
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 InstructionsA guided update for server owners1.37.01.38.0
Guided update
Update sky_jobs_base safely
Complete the five phases in order. Your progress is kept while this page remains open.
0 / 5phases complete
Phase 1 of 5
Prepare
Update sky_base to 1.35.0, stop the server, and back up the complete sky_jobs_base folder, the Job Configurator tables, training tables, and custom provider/config edits.
Install 1.38.0 as one clean package. Its frontend bundle, runtime, locale tree, SQL schema, and dependent job-resource contracts must match.
Phase 2 of 5
Replace files
Delete and reinsert the complete resource. Replace fxmanifest.lua, import.sql, config/config.lua, the complete config/locales directory including nested Job Configurator locales, and the complete source directory.
Phase 3 of 5
Merge config
Add the new global plaintext sharing policy; /jobconfig stores the individual rules separately:
The LB fixBlur default uses the provider's native iframe dimensions so embedded Sky apps remain sharp. Keep it true unless a specific legacy app was built around the old oversized iframe and transform scaling; that exception belongs at Config.Tablet.external.appOverrides.<app>.fixBlur = false. The exact new layoutRepairVersion runs the descriptor/layout repair once and installs the synchronized bundled icons without retaining duplicate entries from the former catalogue.
Config.Sharing is the server-wide limit and kill switch. In /jobconfig, open each job's Share tab and explicitly select permitted target jobs and content types. Dispatch minimumCrew belongs to each job's dispatchKeywords extension row; saved rows without the field resolve to 0. Keep allowedJobs = nil only when every job should use colleague blips, and keep groups = nil only when viewers should see their own job exclusively.
Fire's hydrant-capacity field now uses the exact saved key hoseVehiclePumpHydraulicsHydrantSupplyLitersPerSecond. The removed key was hoseVehiclePumpHydraulicsHydrantSupplyGpm; Fire 1.6.0 migrates an existing saved value to litres per second.
Phase 4 of 5
SQL & items
Automatic migration adds the following columns to sky_jobs_training_courses: learning_content LONGTEXT NULL and catalog_visible TINYINT(1) NOT NULL DEFAULT 0. When automatic migration is disabled, execute:
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`;
No new inventory item, provider secret, or streamed gameplay asset is required. The complete package includes the synchronized tablet SVG catalogue for every registered Jobs Base, Police, Ambulance, and Mechanic app; replace the complete source directory instead of copying individual icons into an older build. Existing courses remain hidden from the employee catalogue until catalog_visible is enabled deliberately. The updated manual and automatic schema definitions inherit the active database character set and collation.
Phase 5 of 5
Restart & test
The console reports sky_base1.35.0 and sky_jobs_base1.38.0 in that order.
The training table contains learning_content and catalog_visible.
A shared record is read-only for an allowed target job and unavailable to a non-target job.
A response plan with minimumCrew does not pass until enough personnel staff the selected units.
Employee-visible courses show only when catalogue visibility is enabled.
Only configured Police/Ambulance viewers receive the shipped colleague blips.
Recruitment succeeds within ten meters and rejects a more distant candidate.
A job vehicle remains after its original driver disconnects and can be reconciled or parked.
External tablet visibility refreshes after job and duty changes.
LB Tablet renders Sky apps at the native sharp scale, runs layout repair version 2026-08-17-app-icons-native-scale-1 once, and shows the bundled icon for every registered Jobs Base, Police, Ambulance, and Mechanic app without duplicate entries.
Mechanic Parts Shop visibility follows the configured tablet-app restriction, while an unauthorized purchase is still rejected by the ordering permission check.
Fire Job Configurator shows hydrant supply in litres per second under hoseVehiclePumpHydraulicsHydrantSupplyLitersPerSecond.
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 InstructionsA guided update for server owners1.36.01.37.0
Guided update
Update sky_jobs_base safely
Complete the five phases in order. Your progress is kept while this page remains open.
0 / 5phases complete
Phase 1 of 5
Prepare
Update Base to 1.34.0, then stop the server. Back up the complete sky_jobs_base folder, config/config.lua, all sky_jobs_* database tables, saved Job Configurator settings, and role permissions. Preserve the active external-tablet provider configuration separately.
Do not overlay 1.37.0 on 1.36.0. The new server modules, generated interface, SVG icons, audio files, manifest order, config, locales, and SQL schema are one release unit.
Phase 2 of 5
Replace files
Delete and reinsert the complete resource. At minimum, replace fxmanifest.lua, source, the complete built UI, config/config.lua, config/init.lua, config/locales, and import.sql. Do not restore an old source/html bundle, generated icon, radio asset, config section, or SQL file after copying the new package.
Phase 3 of 5
Merge config
Use the new config/config.lua as the base. The following values are shared plaintext configuration and are not ordinary per-job /jobconfig values. These complete assignments are executable after the packaged config tables.
Config.Tablet.external.enabled = true prepares the integration but does not select it in Base. The shipped Base default remains Config.tablet = "default", so the built-in Jobs Base tablet remains active. Set Base's Config.tablet = "lb" or Config.tablet = "roadpad" only as a deliberate opt-in. mode = "apps" creates individual entries; mode = "all-in-one" uses allInOne. appOverrides controls individual entries, lb.nativeDuplicates defines the optional native mapping, and lb.managedAppKeys accepts separately installed Sky app keys. When opting in, start the chosen provider before sky_base. After an LB mode or descriptor change, restart lb-tablet, sky_base, and sky_jobs_base. For RoadPad, replace every existing sky_jobs* object in roadpad/public/static/config/config.json -> AppStore with every object from the generated roadpad-apps.generated.jsonapps array; never append the generated objects to stale Sky entries.
Keep the packaged Training section. These copyable assignments cover every allowed runtime default and permission introduced in 1.37.0:
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; dispatchStatusCodes defaults to the six entries above. Saved Training and Dispatch 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.
"auto"; accepts "advancedparking", "cd_garage", or "none"
Config.JobGarage.deleteVehicleOnPlayerDropped
Missing
true; native mode only
Config.JobGarage.vehicleRemovalMode
Missing
"sell"; accepts "disabled", "remove", or "sell"
Config.JobGarage.allowAllEmployeesToRemove
Missing
false; otherwise the existing sell-vehicle permission is required
Config.JobGarage.sellPercentage
50
Still 50; valid refund range is 1 through 100 in sell mode
Config.Panic.allowedJobs
Fixed list
nil; falls back to all registered job resources
Carry acceptance remains enabled for conscious targets and is skipped for incapacitated targets. Garage "auto" selects the one started persistence provider, uses native mode when neither is started, and fails visibly if both are started. Start the selected provider before sky_jobs_base or select it explicitly. Grant Dispatch permission 21 and Manage Units permission 22 only to intended roles after startup; new privileges are not granted automatically.
New client exports are GetTabletState() -> { open, appKey, route, surface, resource, session }, IsExternalTabletOpen() -> Boolean for an LB, RoadPad, or embedded provider-owned surface, MatchesExternalTabletSession(payload) -> Boolean after matching surface, resource, and session plus an optional appKey, and CloseExternalTabletSession(payload) -> accepted, closedState, with stale sessions rejected. New server exports are GetRoadPadTabletApps(), which returns the generated AppStore descriptors only when external integration is enabled and Base selects RoadPad, and RegisterVehicleAccessProvider(provider) -> Boolean. A registered vehicle-access callback receives (source, jobName, model), may only add catalogue, purchase, spawn, or trunk access, and is removed when its owner resource stops.
Phase 4 of 5
SQL & items
Before startup, inspect the storage engine of the existing configurator-settings table. CREATE TABLE IF NOT EXISTS and the automatic migration apply InnoDB only when creating a missing table; they do not convert an existing one.
SELECT TABLE_NAME, ENGINE
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'sky_jobs_configurator_settings';
If the table exists and its engine is not InnoDB, convert it only after the database backup:
ALTER TABLE sky_jobs_configurator_settings ENGINE=InnoDB;
When Config.AutoExecuteQuery = true, the packaged migration creates missing tables and columns during startup. When it is false, run the complete new import.sql before startup. The release adds:
sky_jobs_organization_units and sky_jobs_organization_unit_members, with member rows removed automatically when their unit is deleted.
sky_jobs_dispatch_incidents, sky_jobs_dispatch_incident_log, sky_jobs_dispatch_incident_units, sky_jobs_dispatch_unit_state, and sky_jobs_dispatch_audit.
sky_jobs_training_courses, sky_jobs_training_sessions, sky_jobs_training_enrollments, sky_jobs_training_qualifications, and sky_jobs_training_audit.
The incident schema also gains a nullable long-text details field. The complete import.sql includes this separate upgrade statement for an already existing table:
ALTER TABLE `sky_jobs_dispatch_incidents`
ADD COLUMN IF NOT EXISTS `details` LONGTEXT NULL AFTER `message`;
A newly created sky_jobs_configurator_settings table uses InnoDB. An existing table reaches that required engine only through the explicit check and ALTER TABLE step above.
No new inventory item or image registration is required. Roles do not receive new privileges automatically; grant Dispatch permission 21 and Manage Units permission 22 deliberately, then save the roles.
Phase 5 of 5
Restart & test
Restart in dependency order: the deliberately selected external providers first, then sky_base, sky_jobs_base, and every installed job resource. With the built-in tablet default, begin at sky_base. After an LB mode or descriptor change, restart lb-tablet before Base and Jobs Base.
Base reports 1.34.0 and Jobs Base reports 1.37.0 in that order.
Existing saved Job Configurator values still load, and edited Training/Dispatch settings persist after restart.
Dispatch incidents, assignments, status changes, radio channel/volume controls, announcements, and silent alerts work for authorized staff.
Courses, sessions, approvals, results, qualifications, expiry, and audit entries persist.
Organization Units can assign members, permissions, and only valid vehicles from the effective job configuration.
With Base Config.tablet = "default", the built-in Jobs Base tablet remains active; an external provider is used only after deliberately selecting "lb" or "roadpad".
After an external opt-in, the provider starts before Base; LB entries authorize after a provider/Base/Jobs Base restart, or RoadPad's AppStore contains only the current generated sky_jobs* objects.
External tablet entries authorize, navigate, close, return, and recover from a stale session without duplicate focus.
Client tablet-state/session exports reject stale ownership, RoadPad descriptors appear only in the selected mode, and a registered vehicle-access provider can grant but never revoke normal access.
Cuffs, carry, search privacy, recruitment distance, panic recipients, and protected tablet access follow the new defaults.
Persistent or native job vehicles survive/release exactly according to the selected provider and removal mode.
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.
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 InstructionsA guided update for server owners1.35.11.36.0
Guided update
Update sky_jobs_base safely
Complete the five phases in order. Your progress is kept while this page remains open.
0 / 5phases complete
Phase 1 of 5
Prepare
Back up the complete resource plus config/config.lua and config/webhooks.lua. Do not restore an old source, source/html, manifest, locale, or generated UI file over the new package.
Phase 2 of 5
Replace files
Install the full package. In particular, keep the new civilian-interaction and player-carry runtime, media-provider runtime, handcuffs_keys.png, DOJ Job Configurator files, current frontend bundle, and updated API documentation.
Phase 3 of 5
Merge config
Start from the new config/config.lua. /jobconfig manages each job resource's registered values, but it does not manage the shared settings below.
Config path
1.36.0 shipped value / action
Config.Nui.itemImageBases
New ordered list; default https://cdn.sky-systems.net/items
Config.Nui.weaponImageBases
New ordered list; default https://cdn.sky-systems.net/weapons
Config.Nui.propImageBases
New ordered list; default https://cdn.sky-systems.net/props
Config.Nui.pedImageBases
New ordered list; default https://cdn.sky-systems.net/peds
Config.Nui.vehicleImageBases
New ordered list; default https://cdn.sky-systems.net/vehicles
Config.Cctv.allowedJobs
Changed from { "police", "ambulance", "firefighter" } to { "police", "ambulance", "fire" }
Config.PoliceCuffs.key.enabled
New: true
Config.PoliceCuffs.key.item
New: "handcuffs_keys"
Config.PlayerSearch.combineWeapons
New: true; set false for separate item and weapon tabs
Replace the old singular itemImageBase, weaponImageBase, propImageBase, pedImageBase, and vehicleImageBase fields with the matching ordered arrays. Uncomment and reorder the supplied inventory presets as needed.
The Jobs Base SQL adds nullable sky_jobs_vehicles.catalog_id VARCHAR(100) so saved vehicles remain tied to the correct catalogue entry. Run the current import.sql if Config.AutoExecuteQuery is disabled.
Add the handcuffs_keys item to the active inventory and copy config/inventory/handcuffs_keys.png when the inventory does not consume bundled definitions automatically. The item is not consumed when cuffs are removed.
Phase 5 of 5
Restart & test
Base reports 1.33.0 and Jobs Base reports 1.36.0.
Existing owned garage vehicles still appear and can be returned after the SQL migration.
Duplicate vehicle models retain distinct labels, restrictions, and purchase entries.
Metal cuffs require handcuffs_keys; ziptie removal keeps its configured cutter rules.
Config.CivilianUse.enabled = false exposes no civilian actions; an intentional opt-in exposes only enabled actions.
Civilian and job carry sessions start, accept/decline, stop, and clean up correctly.
The selected media provider can upload and delete a test image.
All configured image-source fallbacks and current job configurators render correctly.
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.
Remove this old block; crime_ziptie now toggles apply/remove
Config.JobRadial.keybinds.escort.key
"L"
"6"
Config.JobRadial.keybinds.escort_vehicle.key
"O"
"7"
Config.JobRadial.keybinds.escort_take_out.key
"U"
"8"
Config.Nui.weaponImageBase keeps the same shipped value. Only its comment now documents both supported weapon-image naming formats.
/jobconfig automatically receives the new Ambulance maximum-health label and Fire pump-panel editor when the matching job resource is updated. Do not add those labels to sky_jobs_base/config/config.lua.
Phase 4 of 5
SQL & items
No SQL migration, new inventory definition, or image copy is required for 1.35.1.
The console reports sky_base1.32.1 and sky_jobs_base1.35.1.
Cuff and ziptie toggle keybinds select the correct apply/remove action.
Handcuffing closes active job interfaces and blocks protected actions until uncuffed.
Off-duty jobs and jobs without native duty state receive the correct tablet and duty behavior.
A gang-only tablet app appears only for its configured QBCore/Qbox gang.
Lowercase item and weapon image files render correctly.
Fire pump vehicles appear as editable cards in /jobconfig.
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 InstructionsA guided update for server owners1.34.01.35.0
Guided update
Update sky_jobs_base safely
Complete the five phases in order. Your progress is kept while this page remains open.
0 / 5phases complete
Phase 1 of 5
Prepare
Update sky_base to 1.32.0 first, then stop the server. Create both backups before touching the live files:
Back up
Safe location
Complete sky_jobs_base folder
Outside the live resources folder
Database
A restorable SQL dump
Your edited config and webhook files
Separate custom-config folder
Do not install 1.35.0 over the existing folder. This release changes the shared runtime and rebuilt tablet interface.
Phase 2 of 5
Replace files
Replace the resource cleanly:
Action
Current server path
New package / destination
Delete
resources/[sky]/sky_jobs_base
Remove only after both backups exist
Copy
—
Copy the new sky_jobs_base folder to resources/[sky]/sky_jobs_base
Keep from new release
fxmanifest.lua, source, and source/html
Never restore these from 1.34.0
Keep from new release
config/locales and config/inventory
Contains the current translations, item guide, and restraint images
Merge only your values
Backed-up config/webhook files
Apply intentional values to the matching new files
Confirm that config/inventory includes handcuffs.png, zipties.png, wire_cutter.png, legcuffs.png, and headbag.png.
This image compatibility change adds no config value, SQL migration, locale, API, or inventory definition. Keep the complete new source/html folder so the updated shared interface is installed.
Phase 3 of 5
Merge config
Start with the newconfig/config.lua. Copy your server-specific values into it; do not replace it with the old file.
The complete public 1.34.0 → 1.35.0 migration is grouped below. /jobconfig does not replace any of these shared Jobs Base values.
Config path
Old behavior
New shipped value / action
Config.CommandPermissions.admincuff
Did not exist
Add your permission groups; shipped { "god", "superadmin", "admin" }
Config.CommandPermissions.adminuncuff
Owned by Police
Add it here with your permission groups
Config.MultiJob.showDefaultJob
false
true; keep false only if the fallback job must stay hidden
Config.Cctv.allowedJobs
Not explicitly set
{ "police", "ambulance", "firefighter" }, or your own job/group allowlist
Keep every additional group supplied by the new package and deliberately review its booleans instead of copying the old Police Config.CivilianUse block.
Keep the complete new Config.PoliceCuffs block. These are all fields that must exist:
Do not paste the old Police cuff block over this one: it is missing the server-authoritative escape chance, delay, cooldown, latency, decoy, and ziptie rules.
Duty and job access no longer belongs inside those blocks. Configure it once through Config.JobPlayerInteractions.groups.
The head-bag self-remove command is now sky_jobs_base_headbag_remove_self; do not restore the old Police command name.
Add these three fields directly below Config.JobGarage.parkKey:
config/config.lua
ownershipMode = "shared", -- "shared", "personal", or "personal_transferable"
paymentSource = "job", -- "job" or "personal"
personalPaymentAccount = "bank"
Choice
Result
ownershipMode = "shared"
Existing shared fleet behavior
ownershipMode = "personal"
Each purchased vehicle belongs to one employee
ownershipMode = "personal_transferable"
Personal ownership plus employee transfers
paymentSource = "job"
Purchase uses job/society funds
paymentSource = "personal"
Purchase uses the buyer's configured personal account
Start with the shipped shared + job combination unless you have deliberately planned personal ownership and payment.
Keep the complete Config.JobRadial.keybinds and Config.JobRadial.providers blocks. Direct keybinds remain globally disabled until keybinds.enabled = true.
Action entry
Shipped command
Default key
Handcuff
sky_jobs_handcuff
J
Remove cuffs
sky_jobs_unhandcuff
K
Apply zipties
sky_jobs_ziptie
H
Cut zipties
sky_jobs_unziptie
N
Escort/release
sky_jobs_escort
L
Place in vehicle
sky_jobs_escort_vehicle
O
Remove from vehicle
sky_jobs_escort_take_out
U
Every action entry also has enabled and description. providers stays an empty table unless a custom radial provider cannot register itself.
After every matching job resource is updated, open /jobconfig and review:
Resource
New or expanded settings
Police
Billing feature plus the Police behavior that now delegates to the shared interaction blocks
Mechanic
Lift-bypass vehicle classes/models and Charge public self-service orders
Ambulance
New shop medications, treatment randomization, and transfusion venous access
Fire
Extinguisher placement/maintenance, wall alignment, custom mounts, door overview, and male/female protective gear
Shared command permissions, interaction access, cuffs/escape, leg restraints, head bags, escort/search, garage ownership, CCTV, and radial keybinds still come from sky_jobs_base/config/config.lua.
Phase 4 of 5
SQL & items
Choose exactly one database path:
Your setting
Required action
Config.AutoExecuteQuery = true
Do not import SQL manually. The resource applies the migration during its first start.
Config.AutoExecuteQuery = false
While the server is stopped, run the new sky_jobs_base/import.sql once in your database manager.
The migration adds sky_jobs_vehicles.ownership_mode, owner_identifier, and payment_source plus idx_job_owner (job, owner_identifier), and applies the remaining required shared schema updates. Keep all existing rows.
If your inventory does not load bundled images, copy the five PNG files from sky_jobs_base/config/inventory into its image folder. Register the matching handcuffs, zipties, wire_cutter, legcuffs, and headbag items only when they do not already exist.
The console reports sky_base1.32.0 and sky_jobs_base1.35.0 without SQL errors.
Job switching resets duty correctly and the configured default job visibility is correct.
Cuffs, zipties, escape, leg restraints, head bags, escort, vehicle placement, and search work with two players.
/admincuff and /adminuncuff obey your permission groups.
Shared and personal garage purchase, storage, and transfer behavior matches your chosen ownership mode.
Radial submenus, embedded tablet apps, Fire camera access, and mounted-prop placement/removal work.
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.
Download sky_jobs_base from the CFX Portal and create a resource backup.
Replace the /source folder, including the rebuilt interface under /source/html.
Replace /fxmanifest.lua so version 1.34.0 is loaded.
Replace /config/locales to install the updated shared and Job Configurator translations.
The following shared /config/config.lua values are not replaced by saved /jobconfig settings and must be merged manually when keeping an existing config:
Add showDefaultJob = false to Config.MultiJob. Set it to true only when the configured fallback job should remain selectable in the player menu.
Copy the complete new Config.EmergencyDispatch block. It includes the top-level enabled and resource fields plus the nested client/server fallback, refresh, vehicle, and dispatch settings. Keep enabled = false unless the emergencydispatch resource is installed and intentionally configured.
No SQL migration is required.
Restart sky_jobs_base, then restart every dependent job resource.
If you use /jobconfig, verify creator labels, numeric fields, table string lists, and the connected Fire/Police/Ambulance settings before saving.
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.
Update sky_base to version 1.30.0.
Download sky_jobs_base from the CFX Portal and create a database and resource backup.
Replace the /source folder, including the rebuilt interface under /source/html.
Replace /fxmanifest.lua so version 1.33.0 is loaded.
Replace /config/locales.
The shared /config/config.lua settings below are not replaced by saved /jobconfig values. Merge them manually when you keep your existing config:
Add the propoffset entry to Config.CommandPermissions and copy the complete Config.PropOffsetTool block (enabled, maxDistance, and outputKey).
Add Config.Chat.jobViewJobs. Leave it nil for own-job/job-group visibility, use a job list for selected cross-job access, or true for access to every registered job.
Keep or add Config.JobGarage.sellPercentage = 50; set it to 0 when fleet vehicle sales should be disabled.
Add Config.JobRadial.submenuOpenDelayMs = 350 for hold-mode submenu navigation.
Review /config/webhooks.lua and keep your existing private FiveManage Media token.
Run the updated /import.sql before starting the resource if automatic query execution is disabled. It adds configurator revision/history storage, deleted-job tracking, initialization state, and stored fleet purchase prices.
Restart sky_jobs_base, then restart every dependent job resource.
If you use /jobconfig, verify Share, Import, Repair, History, reset preview, job blips, and radial submenus before making production changes. Servers that do not use /jobconfig must also apply the manual config.lua changes listed in each updated job resource below.
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.
Update sky_base to version 1.29.0 or newer.
Download sky_jobs_base from the CFX Portal and create a backup.
Replace the /source folder, including the rebuilt in-game interface under /source/html.
Replace the /config/locales folder.
Replace /fxmanifest.lua so version 1.32.0 is loaded.
Restart sky_jobs_base and all dependent job resources.
No SQL migration is required.
Use this only if a Job Configurator is broken and cannot be repaired through /jobconfig. This permanently removes the saved jobs, features, settings, and interactions for the selected resource.
Stop the server and create a database backup.
Replace sky_ambulancejob in both statements with the affected configuration key: sky_ambulancejob, sky_policejob, sky_mechanicjob, or sky_firejob.
Run:
DELETE FROM `sky_jobs_configurator_settings`
WHERE `config_key` = 'sky_ambulancejob';
DELETE FROM `sky_jobs_configurator_jobs`
WHERE `config_key` = 'sky_ambulancejob';
Start the server again. The affected job resource imports its shipped Job Configurator defaults automatically.
Open /jobconfig and verify the restored jobs and settings.
This reset does not delete separate creator data such as hospitals, hospital beds, jails, or other placed creator entries.
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.
Update sky_base first - install the matching release before starting sky_jobs_base.
Download sky_jobs_base from the CFX Portal.
Create a backup.
Replace the /source folder.
Replace the /config/locales folder.
Replace /fxmanifest.lua so version 1.31.0 is loaded.
If you keep your existing config/config.lua, merge the updated Config.JobRadial options from the shipped file so the newer shared targeting behavior is available.
No SQL migration is required.
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.
Update sky_base first.
Download sky_jobs_base from the CFX Portal.
Create a backup.
Replace the /source folder, including the rebuilt /source/html files.
Replace /fxmanifest.lua so the new version is loaded.
Run the updated import.sql, or let the automatic migration add the new billing label column if enabled. If automatic migrations are disabled, run:
ALTER TABLE `sky_jobs_billing_specs`
ADD COLUMN `label` VARCHAR(160) NULL AFTER `reason`;
Restart sky_jobs_base, then restart connected resources such as sky_mechanicjob.
Open /jobconfig and verify the Mechanic General, Billing, and Instant Tuning sections.
::
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.
Update sky_base first - install the matching release before starting sky_jobs_base.
Download sky_jobs_base from the CFX Portal.
Create a backup.
Replace the /source folder.
Replace the /config/locales folder.
Replace /fxmanifest.lua so version 1.29.0 is loaded.
Update /config/config.lua, or merge the changes below:
Job-garage trunk interaction distance - the shared trunk radial now uses a larger rear interaction distance:
Config.JobGarage = {
trunk = {
- promptDistance = 3.0,
- interactDistance = 3.0,
- requireBehind = true,
- openKey = 38,
+ interactDistance = 5.0, -- Max distance from the vehicle rear to open the trunk via the "Open trunk" radial (G) action.
distanceTolerance = 1.5,
}
}
New shared prop placement block - add this new top-level section if you want to use the shared job prop-item flow:
Shared billing labels SQL update - the updated import.sql adds a label column to billing specs. If Config.AutoExecuteQuery = false, run:
ALTER TABLE `sky_jobs_billing_specs`
ADD COLUMN `label` VARCHAR(160) NULL AFTER `reason`;
Restart sky_jobs_base, then verify /jobconfig, boss billing management, shared prop handling, and relevant shop restrictions.
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.
Update sky_base first - install the matching release before starting sky_jobs_base.
Download sky_jobs_base from the CFX Portal.
Create a backup.
Replace the /source folder (this includes the rebuilt in-game interface under source/html).
Replace the /config/locales folder for the new and updated configurator labels.
Replace /fxmanifest.lua so version 1.28.0 is loaded.
Replace /config/config.lua, or apply the additive options below.
a) Update your existing Config.Tablet block. The tablet item now controls usable-item registration. Set item = "" if you do not want a usable tablet item:
Config.Tablet = {
enabled = true,
requireItem = false,
- item = "tablet",
+ item = "tablet", -- Usable inventory item that opens the tablet (set to "" to disable the usable item).
prop = {
-- your existing prop settings stay as they are
}
}
b) Add the new prop removal options inside your existing Config.JobGarage.trunk block. Do not create a second Config.JobGarage table:
Config.JobGarage = {
trunk = {
propStreamDistance = 150.0,
propStreamDespawnBuffer = 25.0,
+ propRemoveEnabled = true, -- Show a keypress prompt next to placed props to remove them.
+ propRemoveKey = 38, -- Control id for the prop removal key.
+ propRemoveKeyLabel = "E", -- Key label shown in the removal prompt.
+ propRemoveDistance = 2.2, -- Max distance for keypress/radial prop removal.
}
}
c) Optional job configuration additions. Existing configs keep working, but the Job Configurator can now manage more fields such as society account, storage options, mechanic vehicle classes, instant tuning profiles, damage handling, and shop minimum grades. Use the shipped config.lua as the reference when adding these fields manually.
8. Restart sky_jobs_base, then open /jobconfig and /jobs to verify the configurator and multi-job menu.
9. No SQL migration is required.
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.
Update sky_base first — install the matching release. This release's inventory calls depend on it; an older sky_base can break storage / locker / trunk item handling.
Download sky_jobs_base from the CFX Portal.
Create a backup.
Replace the /source folder (this includes the rebuilt in-game interface under source/html).
Replace the /config/locales folder (new cz.lua; expanded wardrobe / configurator strings across languages).
Run the updated import.sql. It adds the new multi-job label columns and converts identifier columns to a fixed-length type; with Config.AutoExecuteQuery = true (default) the migration runs automatically on start, otherwise import it manually.
Replace /fxmanifest.lua so version 1.27.0 is loaded.
Add the new options to config/config.lua. The easiest way is to take the new config/config.lua from the download and copy your old custom values into it. If you prefer to edit your existing file by hand, follow the steps below.
a) Add the new admin command to the Config.CommandPermissions table you already have. Do not create a second table — add the line next to the existing givejob / removejob entries:
b) Update your existing Config.MultiJob block. The per-command giveJobGroups / removeJobGroups keys are replaced by a single adminCommand, and a new selfRemoveBlacklist is added:
Config.MultiJob = {
command = "jobs",
giveJobCommand = "givejob",
removeJobCommand = "removejob",
- giveJobGroups = { "god", "superadmin", "admin" },
- removeJobGroups = { "god", "superadmin", "admin" },
+ adminCommand = "multijobadmin", -- command name used for /multijobadmin (permissions live in Config.CommandPermissions)
-- ... your other Config.MultiJob settings stay as they are ...
+ -- Jobs listed here cannot be removed by the player from the self-service menu.
+ -- Admin commands and exports can still remove them.
+ selfRemoveBlacklist = {
+ -- "police",
+ -- "ambulance"
+ },
}
c) (Optional) Per-interaction drawDistance. Any entry in Config.Interactions may now set an optional visual marker draw range. Leave it out to keep the previous behaviour:
duty_terminal = {
duty = false,
+ -- drawDistance = 25.0, -- optional: visual marker draw range; lower values keep the default buffer
-- the rest of this interaction's settings stay as they are
}
d) (Optional) Per-vehicle job-garage attributes. Job vehicles are defined in each job's own Config.Jobs[*].vehicles list (e.g. sky_ambulancejob/config/config.lua), not here. Each entry now additionally supports minGrade, livery, extras, fuelType, primaryColor / secondaryColor / pearlescentColor / wheelColor, trunkEnabled, trunkPropsEnabled, hasStretcher (ambulance only), and a raw properties passthrough. All are optional — existing vehicle entries keep working unchanged. The new documentation block above Config.JobGarage in the shipped config.lua lists every field.
9. Restart sky_jobs_base, then verify the multi-job menu (/jobs) and the Job Configurator (/jobconfig).
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.
Update sky_base first.
Download sky_jobs_base from the CFX Portal.
Create a backup.
Replace the /source folder (this includes the rebuilt in-game interface under source/html).
Replace the /config/locales folder (multi-job menu strings, creator-cleanup notification, confiscated-items label).
Run the updated import.sql to add the multi-job storage table. Database indexes are added automatically on startup — no further SQL is required.
Add the new options to config/config.lua. The easiest way is to take the new config/config.lua from the download and copy your old custom values into it. If you prefer to edit your existing file by hand, follow the steps below.
a) Add the brand-new Config.MultiJob block. This is the multi-job menu (the /jobs window where a player switches between several jobs). It is a completely new section, so you can paste it anywhere in config.lua — a good spot is right after Config.CommandPermissions. Each line is explained in the comments:
+Config.MultiJob = {
+ enabled = true, -- turn the whole multi-job menu on/off
+ command = "jobs", -- chat command that opens the menu (/jobs)
+ giveJobCommand = "givejob", -- admin command name to give a player a job
+ removeJobCommand = "removejob", -- admin command name to take a job away
+ giveJobGroups = { "god", "superadmin", "admin" }, -- who may use /givejob
+ removeJobGroups = { "god", "superadmin", "admin" }, -- who may use /removejob
+ defaultJob = "unemployed", -- job a player falls back to when they have no jobs left
+ defaultGrade = 0, -- the grade/rank of that fallback job
+ fallbackJob = nil, -- leave nil unless you want a different fallback than defaultJob
+ fallbackGrade = nil, -- same, leave nil to use defaultGrade
+ maxJobs = 8, -- how many jobs one player may hold at once
+ includeCurrentJob = true, -- also list the player's current framework job in the menu
+ switchOffDuty = true, -- allow switching while off duty
+ allowUnregisteredFrameworkJobs = true,-- allow jobs that exist in your framework but not in a Sky config
+ autoDetectOffDutyJobs = true, -- automatically pairs jobs like "ballas" with their off-duty "off_ballas"
+ offDutyPrefix = "off_", -- the name prefix used for those off-duty jobs
+ policeColor = "#173B73", -- accent color used for police-type jobs in the menu
+ medicalColor = "#C73535", -- accent color used for medical/EMS jobs in the menu
+ openKey = nil -- optional keybind, e.g. "F6". Leave nil to open with /jobs only
+}
b) Add the two new admin commands to the table you already have. Do not create a second Config.CommandPermissions — open the existing one near the top of config.lua and add these two lines next to jobconfig/setboss. The group names ("god", "superadmin", "admin") decide who is allowed to run each command:
c) Add the remaining new keys inside the tables that already exist. These belong in sections you already have — pasting them on their own will cause an error. Use Ctrl+F to find each section name, then add the line(s) among that section's settings.
Add inside your existing Config.Cctv table:
Config.Cctv = {
+ recordBitrateKbps = 1500, -- caps the bodycam upload size (lower = smaller file)
-- the rest of your Config.Cctv settings stay as they are
}
Add inside the trunk block of your existing Config.JobGarage table:
Config.JobGarage = {
trunk = {
+ propStreamDistance = 150.0, -- how close (in meters) a placed prop spawns
+ propStreamDespawnBuffer = 25.0, -- extra distance before a spawned prop is removed again
-- the rest of your trunk settings stay as they are
}
}
Add inside your existing Config.ColleagueMapBlips table:
Config.ColleagueMapBlips = {
+ showOnMinimap = false, -- also show on-duty colleagues on the minimap (false = off)
-- the rest of your Config.ColleagueMapBlips settings stay as they are
}
Replace /fxmanifest.lua so version 1.26.0 is loaded.
Restart sky_jobs_base, then open /jobs to verify the multi-job menu.
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.
Update sky_base first.
Download sky_jobs_base from the CFX Portal.
Create a backup.
Replace the /source folder, including the rebuilt in-game interface under source/html.
Replace the /config/locales folder for the new English and German Nitro access labels.
Replace /fxmanifest.lua so version 1.25.0 is loaded.
Restart sky_jobs_base and sky_mechanicjob.
Open /jobconfig and review the Nitro access setting under General for each mechanic job.
No SQL migration or manual config change is required.
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.
Update sky_base first.
Download sky_jobs_base from the CFX Portal.
Create a backup.
Replace the /source folder (this includes the rebuilt in-game interface under source/html).
Replace the /config/locales folder.
Replace the /fxmanifest.lua (version 1.24.0).
No config changes or SQL migration required.
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.
Update sky_base first — install the matching release. This release's job & duty security fix depends on it; an older sky_base will leave job/duty sync incomplete.
Download sky_jobs_base from the CFX Portal.
Create a backup.
Replace the /source folder (this also contains the updated in-game interface under source/html).
Replace the /fxmanifest.lua (version 1.23.0).
Replace the /config/locales folder (new weapons tablet-app title in every language, plus Job Configurator string updates).
Replace /config/webhooks.lua.
Replace /config/config.lua, or merge the additive options below (each defaults to the previous behaviour):
Lockable management editing — new block:
+-- Set a flag to false to lock the value in the management menu (read-only; edit via database only).
+-- Override per job via Sky_Jobs.SetJobManagementEditing(jobKey, { salary = false, ... }).
+Config.ManagementEditing = {
+ roleName = true, -- grade/role display name
+ salary = true, -- salary amount per payout
+ salaryInterval = true, -- payout interval minutes
+ roleStructure = true -- create / delete / reorder roles
+}
+bodycamRecorderEnabled = false, -- client-side bodycam recorder; can noticeably increase client CPU usage when enabled
Auto-close the tablet map after accepting a dispatch — inside Config.Tablet.map:
+closeOnDispatchAccept = true, -- close the tablet automatically after accepting a dispatch on the map
No SQL migration.
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.
Update sky_base first.
Download sky_jobs_base from the CFX Portal.
Create a backup.
Replace the /source folder.
Replace the /fxmanifest.lua (now loads the new config/init.lua).
Add the new /config/init.lua file.
Important — the global table initialization moved to config/init.lua. If you keep your own config/config.lua instead of replacing it, remove these two lines from the top of the file (they are now set in init.lua):
New groups / requireItem / item keys on Config.ColleagueMapBlips, Config.Panic, and Config.Ping (same three keys on each; groups = nil keeps the default visibility):
Config.ColleagueMapBlips = {
enabled = true,
showSelf = true,
+ groups = nil, -- optional: viewer job -> jobs whose blips it can see
+ requireItem = false, -- if true, only shown while carrying `item`
+ item = "gps",
...
}
Config.Storage now documents that its values are the default capacity for jobs without a per-job storage override (no value change needed):
Config.Storage = {
- storageCapacity = 1000, -- Shared storage capacity (<= 0 for unlimited)
- lockerCapacity = 10 -- Personal locker capacity (<= 0 for unlimited)
+ storageCapacity = 1000, -- Default shared capacity for jobs without a per-job storage override (<= 0 for unlimited)
+ lockerCapacity = 10 -- Default personal locker capacity for jobs without a per-job storage override (<= 0 for unlimited)
}
New pedImageBase in Config.Nui:
Config.Nui = {
propImageBase = "https://cdn.sky-systems.net/props",
+ pedImageBase = "https://cdn.sky-systems.net/peds", -- base path for ped images (e.g. fire scenario creator assets)
...
}
No SQL migration required.
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).
Update sky_base first.
Download sky_jobs_base from the CFX Portal.
Create a backup.
Replace the /source folder.
Replace the /config/locales folder (new pt.lua; extended panic-button and Job Configurator strings across languages).
In config/config.lua (both optional — defaults keep the previous behaviour):
Config.Cloakroom.backend now also accepts "rcore" to force the rcore_clothing job-changing room. "auto" detects it automatically.
Add the optional bodycamViewJobs key to the bodycam block to configure per-job bodycam visibility:
- bodycamItem = "bodycam"
+ bodycamItem = "bodycam",
+
+ -- Optional per-job bodycam visibility. Key = viewer job, value = jobs whose
+ -- bodycams it can see. Jobs not listed keep the default network (own job +
+ -- jobs in the same job group). Leave nil to keep the previous behaviour.
+ bodycamViewJobs = nil
No SQL migration required.
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).
Update sky_base first (required — the new currency formatting relies on the matching sky_base release).
Download sky_jobs_base from the CFX Portal.
Create a backup.
Replace the /source folder.
Replace the /config/locales folder if you use the bundled locales.
Database — the in-game Job Configurator adds new tables. With Config.AutoExecuteQuery = true (default) they are created automatically on start. If you manage SQL manually, import the updated import.sql.
In config/config.lua, add the new options:
Config.AutoExecuteQuery = true
+Config.DutySystem = true -- Set to false to make job members always count as on duty
Config.CommandPermissions = {
+ jobconfig = { "god", "superadmin", "admin" }, -- /jobconfig - open the in-game job configurator
setboss = { "god", "superadmin", "admin" },
...
}
In config/config.lua, add the new salary account options to Config.Salary:
Config.Salary = {
enabled = true,
+ accountType = "bank", -- "money" or "bank" - account used for payouts
+ currency = nil, -- optional custom sky_base currency key; overrides accountType when set
payIntervalsWhileOnDuty = true,
...
}
In config/config.lua, add the configurable wardrobe backend to Config.Cloakroom (use "auto" to keep auto-detection, or pin / customize a clothing system):
In config/config.lua, restrict the panic feature if desired via Config.Panic.allowedJobs:
Config.Panic = {
enabled = true,
+ allowedJobs = { "police", "ambulance" }, -- set to nil to allow all job-related jobs
useKeybind = true,
...
}
(Optional) Tablet apps now accept a table form for hiding apps / showing a "new" badge, e.g. cctv = { enabled = true, isNew = true } in Config.Tablet.apps. Limited trunk props can be set per job vehicle via props / propCounts in Config.JobGarage. No changes required to keep existing behavior.
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.
Update sky_base first.
Download sky_jobs_base from the CFX Portal.
Create a backup.
Replace the /source folder.
Replace the /config/locales folder.
In config/config.lua, add the new garage options to Config.JobGarage:
Config.JobGarage = {
parkRadius = 4.0,
parkKey = 38,
sellPercentage = 50,
+ allowPlateChange = true, -- Set to false to disable license plate changes in the garage menu.
+ warpIntoVehicle = false, -- Set to true to put the player directly into the spawned garage vehicle.
spawnBlockRadius = 3.0,
...
}
In config/config.lua, add the new panic options to Config.Panic:
Config.Panic = {
enabled = true,
+ useKeybind = true, -- Set to false to stop registering the panic keybind.
+ useRadial = false, -- Set to true to show the panic button in the job radial menu.
requireOnDuty = true,
...
}
No SQL migration. No Config.AutoExecuteQuery action required.
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.
Update sky_base first.
Download sky_jobs_base from the CFX Portal.
Create a backup.
Replace the /source folder.
Replace the /config/locales folder.
In config/config.lua, the default itemImageBase has been reverted to the Sky-Systems CDN. If you want to keep the ox_inventory path from 1.17.0, set it explicitly:
No SQL migration. No Config.AutoExecuteQuery action required.
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.
Update sky_base first.
Download sky_jobs_base from the CFX Portal.
Create a backup.
Replace the /source folder.
Replace the /config/locales folder.
In config/config.lua, the colleague-blip block has two new keys and a new default for showOnMinimap (now a legacy / no-op flag — colleague blips are pause-menu only):
Config.ColleagueMapBlips = {
enabled = true,
showSelf = true,
- showOnMinimap = true,
- updateIntervalMs = 500,
+ showOnMinimap = false, -- legacy; colleague blips are now pause-menu only
+ updateIntervalMs = 500, -- legacy fallback for pauseMenuRenderIntervalMs
+ pauseMenuSnapshotIntervalMs = 500, -- server snapshot interval while the pause-menu map is open
+ pauseMenuRenderIntervalMs = 200, -- local blip refresh interval while the pause-menu map is open
display = 4,
...
}
In config/config.lua, append enabled to the existing Config.Salary block:
In config/config.lua, the default Config.Nui.itemImageBase switched to the ox_inventory image path. If you relied on the previous Sky-Systems CDN default (or had useOxInventoryImages = true), set itemImageBase directly:
The legacy Config.Nui.useOxInventoryImages flag is gone — set itemImageBase directly instead.
9. No SQL migration. No Config.AutoExecuteQuery action required.
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
Download sky_jobs_base from the CFX Portal.
Create a backup.
Replace the /source folder.
Replace the /config/locales folder (new ru.lua and updated de.lua).
Replace fxmanifest.lua if you track the resource version from the manifest.
If Config.AutoExecuteQuery = false, run the wardrobe migration manually:
ALTER TABLE `sky_jobs_wardrobes` ADD COLUMN IF NOT EXISTS `allowed_grades` LONGTEXT NULL;
Optional for creator integrations: marker, interaction and extra interaction definitions may now set interactionDistance = 2.5 (or another number) to tune the use distance for that specific point.
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.
Download sky_jobs_base from the CFX Portal.
Create a backup.
Replace the /source folder.
Replace the /config/locales folder (new se.lua).
Required — update sky_base to 1.14.0 or newer first, and add the three permission bootstrap ACEs to your server.cfg:
Without these, /setboss and every creator command will deny everyone except the server console.
6. The new Config.CommandPermissions block in config/config.lua controls who can use /setboss and /dutytest:
Config.CommandPermissions = {
-- /setboss <job> <grade> - Set the boss grade for a job
setboss = { "god", "superadmin", "admin" },
-- /dutytest [playerId] [on|off] - Debug command to force a duty state on a player
dutytest = { "god", "superadmin", "admin" },
}
Adjust the allowed groups if needed — defaults match the previous behaviour.
7. The new Config.ColleagueMapBlips block in config/config.lua controls the colleague map blip system that previously lived in sky_policejob as Config.OfficerMapBlips:
Config.ColleagueMapBlips = {
enabled = true,
showSelf = true,
showOnMinimap = true, -- false = blips only on the big map (pause / tablet), hidden from minimap
updateIntervalMs = 500,
display = 4,
shortRange = false,
scale = 0.85,
color = 3,
colorLights = 3,
sprites = { foot = 1, car = 225, boat = 427, heli = 64, car_lights = 56, boat_lights = 427, heli_lights = 43 }
}
If you had customized Config.OfficerMapBlips in sky_policejob/config/config.lua, copy those values here and remove the old block from the police config (it is no longer read). refreshIntervalMs is no longer needed — the server now pushes positions automatically every ~1s.
8. Optional — third-party scripts calling Sky_Jobs.RegisterCreator(...) should migrate from the legacy permissionResource / permissionCommand pair to the new unified permission field:
Sky_Jobs.RegisterCreator("mycreator", "myjob", {
title = "My Creator",
- permissionResource = GetCurrentResourceName(),
- permissionCommand = "mycreator",
+ permission = "myresource.mycreator",
})
The legacy pair still works (no immediate breaking change for 3rd-party scripts).
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.
Download sky_jobs_base from the CFX Portal.
Create a backup.
Replace the /source folder.
Make sure sky_base is up to date before starting the resource.
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.
Download sky_jobs_base from the CFX Portal.
Create a backup.
Replace the /source folder.
Replace the /config/locales folder.
Make sure sky_base is at version 1.12.0 or newer (banking adapter rename).
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.
Download sky_jobs_base from the CFX Portal.
Create a backup.
Replace the /source folder.
Replace the /config/locales folder.
Requires sky_base 1.11.0 or newer for target-system support. If you previously used Config.enableOXTarget = true in sky_base, set Config.target = "ox" (or "qb" / "auto").
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.
Download sky_jobs_base from the CFX Portal.
Create a backup.
Replace the /source folder.
Replace the /config/locales folder.
In config/config.lua, update the existing Config.JobRadial.mode default:
(Optional) Each entry in Config.Interactions now accepts scenario and onSpawn:
-- scenario = "WORLD_HUMAN_CLIPBOARD" -- GTA scenario to play on spawn
-- onSpawn = function(ped) -- runs once after ped is created
-- SetPedArmour(ped, 100)
-- end
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.
Download sky_jobs_base from the CFX Portal.
Create a backup.
Replace the /source folder.
Replace the /config/locales folder.
In config/config.lua, update the existing Config.Tablet and Config.JobRadial blocks:
Config.Tablet = {
enabled = true,
+ requireItem = false, -- If true, the tablet requires the configured item and the item is registered as a usable item to open the tablet.
+ item = "tablet",
prop = { ... }
}
Config.JobRadial = {
- enabled = true,
+ enabled = true, -- Set to false only if you use ox_target for job actions and have both sky_base Config.enableOXTarget = true and the ox_target resource running, otherwise these actions cannot be triggered at all. Tablet access is not available through ox_target and must be handled through the tablet item's usable-item flow.
key = "g",
mode = "hold",
- deadzone = 0.25
+ deadzone = 0.25,
+ oxTarget = {
+ enabled = true -- Registers non-tablet job radial actions as ox_target actions so they can be used without opening the radial menu. Requires sky_base Config.enableOXTarget = true and the ox_target resource. Tablet access stays on the tablet item's usable-item flow.
+ }
}
If Config.AutoExecuteQuery = false, run the SQL migration manually:
ALTER TABLE `sky_jobs_vehicle_trunks` ADD COLUMN IF NOT EXISTS `metadata_key` VARCHAR(32) NOT NULL DEFAULT '__nil__';
ALTER TABLE `sky_jobs_storageitems` ADD COLUMN IF NOT EXISTS `metadata_key` VARCHAR(32) NOT NULL DEFAULT '__nil__';
ALTER TABLE `sky_jobs_lockeritems` ADD COLUMN IF NOT EXISTS `metadata_key` VARCHAR(32) NOT NULL DEFAULT '__nil__';
ALTER TABLE `sky_jobs_vehicle_trunks` DROP INDEX `uniq_plate_item`;
ALTER TABLE `sky_jobs_vehicle_trunks` ADD UNIQUE KEY `uniq_plate_item_metadata` (`plate`, `name`, `metadata_key`);
ALTER TABLE `sky_jobs_storageitems` DROP INDEX `uniq_station_item`;
ALTER TABLE `sky_jobs_storageitems` ADD UNIQUE KEY `uniq_station_item_metadata` (`station_id`, `name`(100), `metadata_key`);
ALTER TABLE `sky_jobs_lockeritems` DROP INDEX `uniq_station_player_item`;
ALTER TABLE `sky_jobs_lockeritems` ADD UNIQUE KEY `uniq_station_player_item_metadata` (`station_id`, `player_identifier`(255), `name`(100), `metadata_key`);
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.
Download sky_jobs_base from the CFX Portal.
Create a backup.
Replace the /source folder.
Replace the /config/locales folder.
If Config.AutoExecuteQuery = false, run the SQL migration manually:
CREATE TABLE IF NOT EXISTS `sky_jobs_blips` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`job_key` VARCHAR(100) NOT NULL,
`sprite` INT NOT NULL DEFAULT 1,
`color` INT NOT NULL DEFAULT 0,
`scale` FLOAT NOT NULL DEFAULT 0.8,
`display` INT NOT NULL DEFAULT 4,
`short_range` TINYINT(1) NOT NULL DEFAULT 1,
`label` VARCHAR(255) NULL,
UNIQUE KEY `uniq_job` (`job_key`)
);
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.
Download sky_jobs_base from the CFX Portal.
Create a backup.
Replace the /source folder.
Replace the /config/locales folder.
Add in config/config.lua:
-- Automatically create missing tables and add missing columns on resource start.
-- Set to false if you prefer to manually import the SQL file.
Config.AutoExecuteQuery = true
If Config.AutoExecuteQuery = false, run the SQL migration manually:
ALTER TABLE `sky_jobs_vehicles` ADD COLUMN `fuel` FLOAT NULL;
ALTER TABLE `sky_jobs_vehicles` ADD COLUMN `fuel_type` VARCHAR(50) NULL;
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).
Download sky_jobs_base from the CFX Portal.
Create a backup.
Replace the /source folder.
Replace the /config/locales folder.
Add in config/config.lua:
+Config.Cctv = {
+ requireBodycamItem = true,
+ bodycamItem = "bodycam"
+}
+
+----- REPLACE FULLY -----
+Config.JobRadial = {
+ enabled = true,
+ key = "g",
+ mode = "hold", -- "hold" (hold key, release to select) or "toggle" (press to open/close)
+ deadzone = 0.25 -- only used in "hold" mode (stick/mouse deadzone for directional selection)
+}
+
+Config.StationBlip.shortRange
+- shortRange = false
++ shortRange = true
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.