Version 0.8.1
Highlights
- Added separate configurable limits for fixed laboratories owned or rented by each character and faction, with unlimited ownership retained by default.
- Added removal of installed laboratory equipment and additional storage shelves from their interaction menus, returning the installation item to laboratory storage and preserving its condition, fuel and oil for reinstallation.
- Fixed an issue where Crime failed to initialize when shared dependencies took more than 60 seconds to load.
Notable Changes
- Improved Crime startup so a failed migration is reported without aborting the entire initializer.
- Fixed an issue where death and injury handling could register before Ambulance was ready to accept it.
- Optimized inventory checks when loading drug, contact and market information while retaining fresh checks for player actions.
- Changed laboratory storage interactions to open a menu with storage access and shelf actions instead of opening the storage immediately.
- Fixed an issue where growing plant pots rose above their placement surface when their growth model changed.
- Fixed the Drug Creator import preview so saved entries are correctly marked as existing while their template entries remain selectable.
- Fixed an issue where invalid saved ATM or shop robbery settings could interrupt Crime System startup and prevent the remaining location editing tools from loading.
- Fixed an issue where rejected robbery alerts or unsuccessful shop clerk code handoffs could raise an additional logging error.
Other Changes
- Updated the release package to keep its own dependency bootstrap editable for support.
Changed Files
sky_crimesystem/config/drugs_laboratories.luasky_crimesystem/config/drugs_labs_power_workers.luasky_crimesystem/config/illegal_business.luasky_crimesystem/config/locales/*sky_crimesystem/fxmanifest.luasky_crimesystem/source/*— delete and reinsert
Update InstructionsA guided update for server owners0.8.00.8.1
Guided update
Update sky_crimesystem safely
Complete the five phases in order. Your progress is kept while this page remains open.
Phase 1 of 5
Prepare
These instructions cover sky_crimesystem 0.8.0 → the refreshed 0.8.1 package. If you installed an earlier 0.8.1 download today, download the current 0.8.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
Replace sky_crimesystem/fxmanifest.lua, the listed config files and the complete sky_crimesystem/config/locales/ folder from the matching download. Delete the installed sky_crimesystem/source/ folder and reinsert the complete new sky_crimesystem/source/ folder; merge your own configuration separately using the exact changes below. Preserve existing database rows and saved creator entries. The file list is based on the committed shipped resource tree; frontend source, tests, internal docs and output reports are not customer replacement paths.
Phase 3 of 5
Merge config
In sky_crimesystem/config/drugs_labs_power_workers.lua, add Config.Drugs.Labs.maxLaboratoriesPerCharacter and Config.Drugs.Labs.maxLaboratoriesPerFaction. Both fields were absent before this update; both new shipped values are 0, meaning unlimited. Valid values are whole numbers from 0 to 100. Preserve your existing laboratory settings and merge these two fields into the existing table; the complete new shipped table below is a reference, not a request to reset your custom values.
Config.Drugs.Labs = {
enabled = true,
maxLaboratoriesPerCharacter = 0, -- Fixed laboratories, owned or rented; 0 = unlimited.
maxLaboratoriesPerFaction = 0, -- Campers and shared access do not count.
camperHotVehicleMinutes = 240,
defaultRentDays = 7,
rentWarningHours = 24,
rentExpiredHeatGain = 8,
camperMoveCooldownMinutes = 30,
camperMoveHeatGain = 4,
upgradeCostMultiplier = 1.0,
ownershipRequired = true,
storageUnitsPerAmount = 1.0,
storageOverloadHeatGain = 1.4,
storageOverloadDecayMultiplier = 1.45,
cleanlinessDecayPerLifecycle = 1.2,
odorGainPerLifecycle = 0.9,
noiseDecayPerLifecycle = 0.8,
maintenanceDecayPerLifecycle = 0.7,
dirtyContaminationMultiplier = 1.35,
dirtyQualityPenalty = 4,
maintainPaymentAccount = "money",
rentPaymentAccount = "bank",
rentDepositMultiplier = 2,
maximumRentDays = 28,
seizureHeatThreshold = 96,
seizureChancePerLifecycle = 4,
seizureDurationMinutes = 90,
unusableMaintenanceThreshold = 8,
recoveryBaseCost = 12000,
maintainActions = {
clean = { cost = 180, cleanliness = 30, odor = -8, maintenance = 2, heat = -1 },
ventilate = { cost = 120, odor = -28, noise = 4, heat = -0.5 },
repair = { cost = 350, maintenance = 26, cleanliness = 4, heat = -1 },
sanitize = { cost = 260, cleanliness = 20, odor = -16, maintenance = 4, heat = -1.5 },
},
accessRoles = { "owner", "manager", "producer", "storage", "security", "guest" },
accessCapabilities = { "enter", "storage", "equipment", "workers", "keys", "upgrades" },
roleCapabilities = {
owner = { enter = true, storage = true, equipment = true, workers = true, keys = true, upgrades = true },
manager = { enter = true, storage = true, equipment = true, workers = true, keys = true, upgrades = true },
producer = { enter = true, storage = true, equipment = true, workers = false, keys = false, upgrades = false },
storage = { enter = true, storage = true, equipment = false, workers = false, keys = false, upgrades = false },
security = { enter = true, storage = false, equipment = false, workers = false, keys = false, upgrades = false },
guest = { enter = true, storage = false, equipment = false, workers = false, keys = false, upgrades = false },
},
actionCapabilities = {
enter = "enter",
batchStorage = "storage",
market = "storage",
route = "storage",
consume = "storage",
processing = "equipment",
placeEquipment = "equipment",
serviceEquipment = "equipment",
plantSeed = "equipment",
maintainPlant = "equipment",
harvestPlant = "equipment",
hireWorker = "workers",
manageKeys = "keys",
manageUpgrades = "upgrades",
},
labTypes = {
camper = { label = "Camper", slots = 3, storage = 120, power = 500, heatMultiplier = 1.35, mobile = true },
basement = { label = "Basement", slots = 8, storage = 450, power = 1500, heatMultiplier = 1.0 },
garage = { label = "Garage", slots = 10, storage = 650, power = 2200, heatMultiplier = 1.08 },
apartment = { label = "Apartment", slots = 7, storage = 360, power = 1250, heatMultiplier = 0.92 },
warehouse = { label = "Warehouse", slots = 18, storage = 1400, power = 5500, heatMultiplier = 1.25 },
industrial = { label = "Industrial Hall", slots = 21, storage = 1750, power = 7200, heatMultiplier = 1.34 },
bunker = { label = "Bunker", slots = 24, storage = 2200, power = 9000, heatMultiplier = 0.78 },
},
tiers = {
{ tier = 1, label = "Starter", cost = 0, slotBonus = 0, storageMultiplier = 1.0, security = 10, qualityBonus = 0, powerBonus = 0 },
{ tier = 2, label = "Improved", cost = 25000, slotBonus = 2, storageMultiplier = 1.25, security = 25, qualityBonus = 2, powerBonus = 250 },
{ tier = 3, label = "Professional", cost = 65000, slotBonus = 4, storageMultiplier = 1.55, security = 45, qualityBonus = 4, powerBonus = 700 },
{ tier = 4, label = "Industrial", cost = 145000, slotBonus = 7, storageMultiplier = 1.9, security = 65, qualityBonus = 7, powerBonus = 1500 },
{ tier = 5, label = "Elite", cost = 325000, slotBonus = 10, storageMultiplier = 2.35, security = 85, qualityBonus = 10, powerBonus = 3500 },
},
facilityUpgrades = {
concealment = { label = "Concealment", maxTier = 4, costs = { 9000, 24000, 52000, 110000 }, heatReduction = 4, raidDefense = 3 },
hidden_storage = { label = "Hidden Storage", maxTier = 4, costs = { 12000, 32000, 68000, 145000 }, protectedShare = 0.12, storageBonus = 15 },
door = { label = "Door & Lock", maxTier = 5, costs = { 7000, 18000, 42000, 95000, 190000 }, raidDefense = 7 },
keycards = { label = "Keycard System", maxTier = 3, costs = { 18000, 48000, 105000 }, raidDefense = 5 },
cctv = { label = "CCTV", maxTier = 4, costs = { 9500, 26000, 58000, 125000 }, raidDefense = 5 },
alarm = { label = "Alarm System", maxTier = 4, costs = { 7500, 22000, 50000, 115000 }, raidDefense = 5 },
clean_room = { label = "Clean Room", maxTier = 4, costs = { 16000, 44000, 92000, 185000 }, qualityBonus = 2, contaminationReduction = 4 },
worker_quarters = { label = "Worker Quarters", maxTier = 4, costs = { 11000, 30000, 65000, 135000 }, fatigueRecovery = 3 },
worker_supplies = { label = "Food & Water", maxTier = 4, costs = { 6500, 18000, 40000, 85000 }, moraleBonus = 2, hungerReduction = 4 },
medical_station = { label = "Medical Station", maxTier = 3, costs = { 14000, 38000, 82000 }, stressReduction = 3 },
break_room = { label = "Break Room", maxTier = 3, costs = { 8500, 24000, 54000 }, moraleBonus = 3, stressReduction = 2 },
},
}
With the Job Configurator enabled, open /jobconfig → Crime System → Drug System → General and check Laboratories per Character (drugMaxLaboratoriesPerCharacter) and Laboratories per Faction (drugMaxLaboratoriesPerFaction). These are central server settings, independent of the selected faction. The character limit applies separately to each character; the faction limit applies separately to each faction. Purchased and rented fixed laboratories count together. Campers and access to another owner's laboratory do not count. A stored laboratory still counts when its rental has expired. Lowering a limit blocks further acquisitions; it does not remove existing laboratories. Saved configurator overrides remain authoritative. Set or clear the two overrides there as needed and verify the effective values after a restart; editing the Lua file alone does not replace a saved override.
sky_crimesystem/config/drugs_laboratories.lua changes only two comments in the supplier block; its coordinates, heading, dealer model, stock and prices are unchanged. The complete new supplier block is:
supplier = {
enabled = true,
account = "money",
interactionDistance = 2.2,
-- Import templates: saved Drug Creator suppliers keep their persisted positions.
-- Move an imported supplier with Set position in the creator.
locations = {
{
id = "dock_supplier",
label = "Laboratory Supply Dealer",
coords = { x = 1218.0, y = -3114.83, z = 5.54 },
heading = 90.0,
pedModel = "s_m_y_dockwork_01",
scenario = "WORLD_HUMAN_CLIPBOARD",
marker = true,
},
},
items = {
{ id = "plant_pot", item = "plant_pot", label = "labSupplyPlantPot", category = "cultivation", price = 350, maxPurchase = 12, stockEnabled = true, stockMode = "fixed", stockAmount = 80, description = "labSupplyPlantPotDescription" },
{ id = "potting_soil", item = "potting_soil", label = "labSupplyPottingSoil", category = "cultivation", price = 180, maxPurchase = 20, stockEnabled = true, stockMode = "random", stockMin = 90, stockMax = 160, description = "labSupplyPottingSoilDescription" },
{ id = "plant_nutrients", item = "plant_nutrients", label = "labSupplyPlantNutrients", category = "cultivation", price = 240, maxPurchase = 15, stockEnabled = true, stockMode = "random", stockMin = 60, stockMax = 110, description = "labSupplyPlantNutrientsDescription" },
{ id = "water_bottle", item = "water_bottle", label = "labSupplyWater", category = "cultivation", price = 60, maxPurchase = 25, stockEnabled = false, description = "labSupplyWaterDescription" },
{ id = "trimming_shears", item = "trimming_shears", label = "labSupplyShears", category = "tools", price = 850, maxPurchase = 3, stockEnabled = true, stockMode = "fixed", stockAmount = 18, description = "labSupplyShearsDescription" },
{ id = "lab_gloves", item = "lab_gloves", label = "labSupplyGloves", category = "tools", price = 220, maxPurchase = 10, stockEnabled = false, description = "labSupplyGlovesDescription" },
{ id = "digital_scale", item = "digital_scale", label = "labSupplyScale", category = "tools", price = 950, maxPurchase = 2, stockEnabled = true, stockMode = "random", stockMin = 8, stockMax = 16, description = "labSupplyScaleDescription" },
{ id = "repair_kit", item = "repair_kit", label = "labSupplyRepairKit", category = "maintenance", price = 1200, maxPurchase = 4, stockEnabled = true, stockMode = "fixed", stockAmount = 20, description = "labSupplyRepairKitDescription" },
{ id = "fuel_can", item = "fuel_can", label = "labSupplyFuel", category = "maintenance", price = 500, maxPurchase = 6, stockEnabled = true, stockMode = "random", stockMin = 24, stockMax = 48, description = "labSupplyFuelDescription" },
{ id = "machine_oil", item = "machine_oil", label = "labSupplyOil", category = "maintenance", price = 420, maxPurchase = 8, stockEnabled = true, stockMode = "fixed", stockAmount = 45, description = "labSupplyOilDescription" },
{ id = "drug_packaging", item = "drug_packaging", label = "labSupplyPackaging", category = "processing", price = 180, maxPurchase = 25, stockEnabled = false, description = "labSupplyPackagingDescription" },
{ id = "lab_shelf_small", item = "lab_shelf_small", itemLabel = "Small Shelf", label = "labSupplyShelfSmall", category = "storage", price = 8000, maxPurchase = 2, stockEnabled = true, stockMode = "fixed", stockAmount = 10, description = "labSupplyShelfSmallDescription" },
{ id = "lab_shelf_medium", item = "lab_shelf_medium", itemLabel = "Industrial Shelf", label = "labSupplyShelfMedium", category = "storage", price = 18000, maxPurchase = 1, stockEnabled = true, stockMode = "random", stockMin = 3, stockMax = 7, description = "labSupplyShelfMediumDescription" },
{ id = "lab_shelf_large", item = "lab_shelf_large", itemLabel = "Secured Storage Rack", label = "labSupplyShelfLarge", category = "storage", price = 42000, maxPurchase = 1, stockEnabled = true, stockMode = "random", stockMin = 1, stockMax = 3, description = "labSupplyShelfLargeDescription" },
},
},
Supplier entries already imported into the Drug Creator keep their saved settings and position. To move one, open the Drug Creator (default command /drugcreator) with your existing creator permission, select the saved laboratory supplier, choose Set position, and confirm the new position and heading. The saved entry changes; its other settings remain intact. Editing the supplier template or restarting the resource does not move the saved entry. If you deliberately need to replace it from a template, select only that supplier in the import preview and enable replacement of existing entries; this also replaces its other imported settings, so review products and prices first. Keep Heist Creator imports separate.
No other released plaintext option, init/provider setting or command default changes in this follow-up. Update the resource's complete locale folder for new equipment and ownership messages, and update Jobs Base for the matching configurator labels.
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
No new SQL schema, manual SQL import, database reset, item definition, inventory icon or streamed model is required by these follow-up changes. Existing laboratory, equipment, inventory, construction-node and production tables are reused. Keep your existing items and assets. Equipment removal returns the already configured installation item to laboratory storage, including its condition, fuel and oil where applicable. If you use custom equipment, check that its existing return item is configured and available; a missing return item blocks removal. Your inventory integration must preserve item metadata when transferring the returned item if you want its saved equipment state to survive that transfer. Do not reimport the full seed SQL or overwrite all creator defaults to apply these fixes. Keep the existing database migration/provider setup from the 0.8.1 instructions; these changes add no new provider selection or credentials.
Phase 5 of 5
Restart & test
Perform a full server restart to reload the source and manifest file lists, then reconnect clients. Start the framework, database connector and selected providers first, then refreshed Base 1.45.1, Jobs Base 1.48.1 and Crime 0.8.1. Stop Crime System before replacing files. Start the updated Sky Base first, then Sky Jobs Base, then Crime System; restore other resources stopped with their dependencies in their normal dependency order. Confirm that both libraries complete startup and Crime System finishes registration. Read the console for actual startup errors and new warnings about invalid saved ATM/shop settings. This follow-up uses the existing startup and automatic migration owners; a successful file copy alone does not prove the running resource or database state.
- Open
/jobconfig→ Crime System → Drug System → General. Confirm both new limits, save your intended values and check them after restart. With a temporary limit of one on a test owner, purchase or rent one fixed laboratory, then check that a second acquisition is refused without charging the owner. Check character and faction owners separately; confirm existing ownership is preserved and camper/shared-access cases do not consume the fixed-laboratory limit. Restore your intended values. - In an idle laboratory, approach an installed machine, generator or additional storage shelf and open its interaction/status menu. Use Remove, check that exactly one installation item appears in laboratory storage, the prop and linked construction slot are freed, and condition/fuel/oil survive reinstallation. Check keyboard interaction and your configured target provider. The starting storage must remain; queued/running production and insufficient remaining storage capacity must refuse removal without losing equipment or stored contents. Users need the existing laboratory equipment capability.
- Let a planted pot change between small, medium and large growth stages on the same placement surface. Check that its pot remains on that surface and existing saved plant positions are preserved. If you use custom plant models, check their alignment separately.
- Open the Drug Creator import preview for an already imported supplier. It must be marked as existing, remain selectable and be skipped when replacement is off; do not overwrite it just to test the preview. If you move a saved supplier with Set position, check its saved heading and NPC on connected clients.
- Open the regular Crime location editing tools and ATM/shop configuration. Invalid saved robbery entries should produce useful warnings while remaining location tools register; repair the warned entries in the configurator. If applicable, confirm robbery alerts and clerk code handoff no longer add a logging error when the underlying action is rejected.
- Open drug contact and market views with inventory-backed batches. Change the player's carried quantity and reopen/refresh through the normal flow; quantities and eligible batches must reflect the current player's inventory, including separate characters. Complete ordinary laboratory/storage/production checks before allowing normal play. A long dependency wait no longer aborts at 60 seconds. Repair the original error behind any migration warning; failure to read saved settings remains an initialization error. Check the existing Ambulance death-handling integration on staging when installed.