[{"data":1,"prerenderedAt":886},["ShallowReactive",2],{"/docs/jobs/mechanicjob/features/fake-plate-integration":3,"/docs/jobs/mechanicjob/features/fake-plate-integration-surround":874,"/docs/jobs/mechanicjob/features/fake-plate-integration-implemented-suggestions":885},{"id":4,"title":5,"body":6,"description":865,"extension":866,"head":867,"implementedSuggestions":867,"meta":868,"navigation":158,"path":869,"schemaOrg":867,"seo":870,"sitemap":871,"stem":872,"__hash__":873},"docs/1.docs/0.jobs/2.mechanicjob/3.features/9.fake-plate-integration.md","Fake Plate Integration",{"type":7,"value":8,"toc":853},"minimark",[9,13,49,52,57,103,111,115,123,173,180,237,244,247,250,269,273,276,306,309,356,406,417,421,424,429,432,600,611,615,618,742,747,751,757,790,799,803,825,829,849],[10,11,12],"p",{},"Sky Mechanic Job keeps two plate identities while a fake plate is active:",[14,15,16,29],"table",{},[17,18,19],"thead",{},[20,21,22,26],"tr",{},[23,24,25],"th",{},"Value",[23,27,28],{},"Purpose",[30,31,32,41],"tbody",{},[20,33,34,38],{},[35,36,37],"td",{},"Real plate",[35,39,40],{},"Persistent ownership, garage database lookups, keys, and stored vehicle records",[20,42,43,46],{},[35,44,45],{},"Display plate",[35,47,48],{},"The plate visible on the vehicle and to Police, radar, dispatch, cameras, and UI",[10,50,51],{},"A resource must deliberately choose which identity it needs. Do not apply the real-plate override to every resource.",[53,54,56],"h2",{"id":55},"choose-an-integration-mode","Choose an integration mode",[14,58,59,69],{},[17,60,61],{},[20,62,63,66],{},[23,64,65],{},"Consumer",[23,67,68],{},"Recommended integration",[30,70,71,79,87,95],{},[20,72,73,76],{},[35,74,75],{},"Garage or framework code that always needs the stored vehicle identity",[35,77,78],{},"Native override",[20,80,81,84],{},[35,82,83],{},"Custom resource that sometimes needs the real plate and sometimes the displayed plate",[35,85,86],{},"Explicit helper functions",[20,88,89,92],{},[35,90,91],{},"Police, dispatch, radar, camera, or visible UI",[35,93,94],{},"No native override; keep the displayed plate",[20,96,97,100],{},[35,98,99],{},"Garage that despawns and later respawns vehicles",[35,101,102],{},"Server exports in addition to one of the lookup integrations",[104,105,108],"callout",{"color":106,"icon":107},"warning","i-lucide-triangle-alert",[10,109,110],{},"Load only one compatibility file in a consuming resource. Do not load both files together.",[53,112,114],{"id":113},"native-override-for-garage-resources","Native override for garage resources",[10,116,117,118,122],{},"Add the compatibility file to the ",[119,120,121],"strong",{},"consuming garage resource",", not to the Sky Mechanic Job manifest:",[124,125,130],"pre",{"className":126,"code":127,"language":128,"meta":129,"style":129},"language-lua shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","shared_script \"@sky_mechanicjob/compat/fakeplates_realplate_native.lua\"\n\ndependency \"sky_mechanicjob\"\n","lua","",[131,132,133,153,160],"code",{"__ignoreMap":129},[134,135,138,142,146,150],"span",{"class":136,"line":137},"line",1,[134,139,141],{"class":140},"s2Zo4","shared_script",[134,143,145],{"class":144},"sMK4o"," \"",[134,147,149],{"class":148},"sfazB","@sky_mechanicjob/compat/fakeplates_realplate_native.lua",[134,151,152],{"class":144},"\"\n",[134,154,156],{"class":136,"line":155},2,[134,157,159],{"emptyLinePlaceholder":158},true,"\n",[134,161,163,166,168,171],{"class":136,"line":162},3,[134,164,165],{"class":140},"dependency",[134,167,145],{"class":144},[134,169,170],{"class":148},"sky_mechanicjob",[134,172,152],{"class":144},[10,174,175,176,179],{},"When the resource already has a ",[131,177,178],{},"shared_scripts"," block, add the compatibility file as its first entry and retain its existing entries:",[124,181,183],{"className":126,"code":182,"language":128,"meta":129,"style":129},"shared_scripts {\n    \"@sky_mechanicjob/compat/fakeplates_realplate_native.lua\",\n    \"config.lua\"\n}\n\ndependency \"sky_mechanicjob\"\n",[131,184,185,193,206,215,221,226],{"__ignoreMap":129},[134,186,187,189],{"class":136,"line":137},[134,188,178],{"class":140},[134,190,192],{"class":191},"sTEyZ"," {\n",[134,194,195,198,200,203],{"class":136,"line":155},[134,196,197],{"class":144},"    \"",[134,199,149],{"class":148},[134,201,202],{"class":144},"\"",[134,204,205],{"class":191},",\n",[134,207,208,210,213],{"class":136,"line":162},[134,209,197],{"class":144},[134,211,212],{"class":148},"config.lua",[134,214,152],{"class":144},[134,216,218],{"class":136,"line":217},4,[134,219,220],{"class":191},"}\n",[134,222,224],{"class":136,"line":223},5,[134,225,159],{"emptyLinePlaceholder":158},[134,227,229,231,233,235],{"class":136,"line":228},6,[134,230,165],{"class":140},[134,232,145],{"class":144},[134,234,170],{"class":148},[134,236,152],{"class":144},[10,238,239,240,243],{},"Place the compatibility entry before the consuming resource's own shared scripts. It makes calls to ",[131,241,242],{},"GetVehicleNumberPlateText(vehicle)"," inside that resource return the real plate while a Sky fake plate is active. It also patches common vehicle-property readers loaded by that resource.",[10,245,246],{},"FiveM gives every resource its own Lua environment. The override therefore affects only the resource that loads this file.",[10,248,249],{},"Do not load this override in:",[251,252,253,257,260,263,266],"ul",{},[254,255,256],"li",{},"Police resources",[254,258,259],{},"Dispatch resources",[254,261,262],{},"Radar or speed-camera resources",[254,264,265],{},"Plate overlays",[254,267,268],{},"Other UI that should show the plate visible on the vehicle",[53,270,272],{"id":271},"explicit-realdisplay-plate-helpers","Explicit real/display plate helpers",[10,274,275],{},"Use the helper file when a resource must choose the identity per operation:",[124,277,279],{"className":126,"code":278,"language":128,"meta":129,"style":129},"shared_script \"@sky_mechanicjob/compat/fakeplates.lua\"\n\ndependency \"sky_mechanicjob\"\n",[131,280,281,292,296],{"__ignoreMap":129},[134,282,283,285,287,290],{"class":136,"line":137},[134,284,141],{"class":140},[134,286,145],{"class":144},[134,288,289],{"class":148},"@sky_mechanicjob/compat/fakeplates.lua",[134,291,152],{"class":144},[134,293,294],{"class":136,"line":155},[134,295,159],{"emptyLinePlaceholder":158},[134,297,298,300,302,304],{"class":136,"line":162},[134,299,165],{"class":140},[134,301,145],{"class":144},[134,303,170],{"class":148},[134,305,152],{"class":144},[10,307,308],{},"The file provides these functions inside the consuming resource:",[14,310,311,321],{},[17,312,313],{},[20,314,315,318],{},[23,316,317],{},"Function",[23,319,320],{},"Returns",[30,322,323,333,343],{},[20,324,325,330],{},[35,326,327],{},[131,328,329],{},"SkyGetVehicleDisplayPlateText(vehicle)",[35,331,332],{},"The currently displayed plate",[20,334,335,340],{},[35,336,337],{},[131,338,339],{},"SkyGetVehicleRealPlateText(vehicle)",[35,341,342],{},"The persistent real plate",[20,344,345,350],{},[35,346,347],{},[131,348,349],{},"SkyGetVehicleFakePlateState(vehicle)",[35,351,352,353],{},"Active fake-plate metadata, or ",[131,354,355],{},"nil",[124,357,359],{"className":126,"code":358,"language":128,"meta":129,"style":129},"local real_plate = SkyGetVehicleRealPlateText(vehicle)\nlocal display_plate = SkyGetVehicleDisplayPlateText(vehicle)\nlocal fake_plate = SkyGetVehicleFakePlateState(vehicle)\n",[131,360,361,378,392],{"__ignoreMap":129},[134,362,363,366,369,372,375],{"class":136,"line":137},[134,364,365],{"class":144},"local",[134,367,368],{"class":191}," real_plate ",[134,370,371],{"class":144},"=",[134,373,374],{"class":140}," SkyGetVehicleRealPlateText",[134,376,377],{"class":191},"(vehicle)\n",[134,379,380,382,385,387,390],{"class":136,"line":155},[134,381,365],{"class":144},[134,383,384],{"class":191}," display_plate ",[134,386,371],{"class":144},[134,388,389],{"class":140}," SkyGetVehicleDisplayPlateText",[134,391,377],{"class":191},[134,393,394,396,399,401,404],{"class":136,"line":162},[134,395,365],{"class":144},[134,397,398],{"class":191}," fake_plate ",[134,400,371],{"class":144},[134,402,403],{"class":140}," SkyGetVehicleFakePlateState",[134,405,377],{"class":191},[10,407,408,409,412,413,416],{},"Use ",[131,410,411],{},"real_plate"," for ownership and database keys. Use ",[131,414,415],{},"display_plate"," for player-facing labels and observations.",[53,418,420],{"id":419},"persist-fake-plates-through-garage-storage","Persist fake plates through garage storage",[10,422,423],{},"The compatibility file corrects plate reads, but it cannot persist entity state after the garage deletes the vehicle. A compatible garage must save the fake-plate state before despawning the entity and restore it after the new networked vehicle exists.",[425,426,428],"h3",{"id":427},"store","Store",[10,430,431],{},"Run this on the server while the vehicle entity still exists:",[124,433,435],{"className":126,"code":434,"language":128,"meta":129,"style":129},"local resolved = exports[\"sky_mechanicjob\"]:ResolveRealPlateForGarageStore(net_id)\n\nif resolved then\n    vehicle_data.plate = resolved.realPlate\n\n    if resolved.resetOnGarageStore then\n        exports[\"sky_mechanicjob\"]:ClearFakePlate(net_id, \"garage_store\")\n        vehicle_data.skyFakePlate = nil\n    else\n        vehicle_data.skyFakePlate = exports[\"sky_mechanicjob\"]:GetFakePlateState(net_id)\n    end\nend\n",[131,436,437,464,468,479,497,501,514,544,558,564,588,594],{"__ignoreMap":129},[134,438,439,441,444,446,449,451,453,455,458,461],{"class":136,"line":137},[134,440,365],{"class":144},[134,442,443],{"class":191}," resolved ",[134,445,371],{"class":144},[134,447,448],{"class":191}," exports[",[134,450,202],{"class":144},[134,452,170],{"class":148},[134,454,202],{"class":144},[134,456,457],{"class":191},"]:",[134,459,460],{"class":140},"ResolveRealPlateForGarageStore",[134,462,463],{"class":191},"(net_id)\n",[134,465,466],{"class":136,"line":155},[134,467,159],{"emptyLinePlaceholder":158},[134,469,470,474,476],{"class":136,"line":162},[134,471,473],{"class":472},"s7zQu","if",[134,475,443],{"class":191},[134,477,478],{"class":472},"then\n",[134,480,481,484,488,491,494],{"class":136,"line":217},[134,482,483],{"class":191},"    vehicle_data.",[134,485,487],{"class":486},"sBMFI","plate",[134,489,490],{"class":144}," =",[134,492,493],{"class":191}," resolved.",[134,495,496],{"class":486},"realPlate\n",[134,498,499],{"class":136,"line":223},[134,500,159],{"emptyLinePlaceholder":158},[134,502,503,506,508,511],{"class":136,"line":228},[134,504,505],{"class":472},"    if",[134,507,493],{"class":191},[134,509,510],{"class":486},"resetOnGarageStore",[134,512,513],{"class":472}," then\n",[134,515,517,520,522,524,526,528,531,534,536,539,541],{"class":136,"line":516},7,[134,518,519],{"class":191},"        exports[",[134,521,202],{"class":144},[134,523,170],{"class":148},[134,525,202],{"class":144},[134,527,457],{"class":191},[134,529,530],{"class":140},"ClearFakePlate",[134,532,533],{"class":191},"(net_id, ",[134,535,202],{"class":144},[134,537,538],{"class":148},"garage_store",[134,540,202],{"class":144},[134,542,543],{"class":191},")\n",[134,545,547,550,553,555],{"class":136,"line":546},8,[134,548,549],{"class":191},"        vehicle_data.",[134,551,552],{"class":486},"skyFakePlate",[134,554,490],{"class":144},[134,556,557],{"class":144}," nil\n",[134,559,561],{"class":136,"line":560},9,[134,562,563],{"class":472},"    else\n",[134,565,567,569,571,573,575,577,579,581,583,586],{"class":136,"line":566},10,[134,568,549],{"class":191},[134,570,552],{"class":486},[134,572,490],{"class":144},[134,574,448],{"class":191},[134,576,202],{"class":144},[134,578,170],{"class":148},[134,580,202],{"class":144},[134,582,457],{"class":191},[134,584,585],{"class":140},"GetFakePlateState",[134,587,463],{"class":191},[134,589,591],{"class":136,"line":590},11,[134,592,593],{"class":472},"    end\n",[134,595,597],{"class":136,"line":596},12,[134,598,599],{"class":472},"end\n",[10,601,602,603,606,607,610],{},"Persist ",[131,604,605],{},"vehicle_data.skyFakePlate"," with the garage's other vehicle properties. Never replace the persistent database plate with ",[131,608,609],{},"displayPlate",".",[425,612,614],{"id":613},"restore","Restore",[10,616,617],{},"After the garage has spawned the vehicle and its network ID resolves to an existing server entity:",[124,619,621],{"className":126,"code":620,"language":128,"meta":129,"style":129},"if vehicle_data.skyFakePlate then\n    local restored, result = exports[\"sky_mechanicjob\"]:RestoreFakePlateState(\n        net_id,\n        vehicle_data.skyFakePlate,\n        \"garage_spawn\"\n    )\n\n    if not restored then\n        print((\"[garage] Fake plate restore failed: %s\"):format(tostring(result)))\n    end\nend\n",[131,622,623,634,660,665,673,683,688,692,704,734,738],{"__ignoreMap":129},[134,624,625,627,630,632],{"class":136,"line":137},[134,626,473],{"class":472},[134,628,629],{"class":191}," vehicle_data.",[134,631,552],{"class":486},[134,633,513],{"class":472},[134,635,636,639,642,644,646,648,650,652,654,657],{"class":136,"line":155},[134,637,638],{"class":144},"    local",[134,640,641],{"class":191}," restored, result ",[134,643,371],{"class":144},[134,645,448],{"class":191},[134,647,202],{"class":144},[134,649,170],{"class":148},[134,651,202],{"class":144},[134,653,457],{"class":191},[134,655,656],{"class":140},"RestoreFakePlateState",[134,658,659],{"class":191},"(\n",[134,661,662],{"class":136,"line":162},[134,663,664],{"class":191},"        net_id,\n",[134,666,667,669,671],{"class":136,"line":217},[134,668,549],{"class":191},[134,670,552],{"class":486},[134,672,205],{"class":191},[134,674,675,678,681],{"class":136,"line":223},[134,676,677],{"class":144},"        \"",[134,679,680],{"class":148},"garage_spawn",[134,682,152],{"class":144},[134,684,685],{"class":136,"line":228},[134,686,687],{"class":191},"    )\n",[134,689,690],{"class":136,"line":516},[134,691,159],{"emptyLinePlaceholder":158},[134,693,694,696,699,702],{"class":136,"line":546},[134,695,505],{"class":472},[134,697,698],{"class":144}," not",[134,700,701],{"class":191}," restored ",[134,703,478],{"class":472},[134,705,706,709,712,714,717,719,722,725,728,731],{"class":136,"line":560},[134,707,708],{"class":140},"        print",[134,710,711],{"class":191},"((",[134,713,202],{"class":144},[134,715,716],{"class":148},"[garage] Fake plate restore failed: %s",[134,718,202],{"class":144},[134,720,721],{"class":191},"):",[134,723,724],{"class":140},"format",[134,726,727],{"class":191},"(",[134,729,730],{"class":140},"tostring",[134,732,733],{"class":191},"(result)))\n",[134,735,736],{"class":136,"line":566},[134,737,593],{"class":472},[134,739,740],{"class":136,"line":590},[134,741,599],{"class":472},[10,743,744,746],{},[131,745,656],{}," validates the real plate, display plate, active state, vehicle entity, and expiry time. An expired fake plate is not restored.",[53,748,750],{"id":749},"configuration","Configuration",[10,752,753,756],{},[131,754,755],{},"Config.FakePlates.resetOnGarageStore"," controls the intended storage policy:",[14,758,759,768],{},[17,760,761],{},[20,762,763,765],{},[23,764,25],{},[23,766,767],{},"Behavior",[30,769,770,780],{},[20,771,772,777],{},[35,773,774],{},[131,775,776],{},"true",[35,778,779],{},"Storing the vehicle removes the fake plate",[20,781,782,787],{},[35,783,784],{},[131,785,786],{},"false",[35,788,789],{},"A compatible garage may save and restore the fake plate",[10,791,792,793,796,797,610],{},"The default in version ",[131,794,795],{},"1.20.0"," is ",[131,798,786],{},[53,800,802],{"id":801},"test-checklist","Test checklist",[251,804,805,808,811,814,817,820],{},[254,806,807],{},"Store a normal vehicle and confirm its database plate is unchanged.",[254,809,810],{},"Install a fake plate and confirm the garage still finds the vehicle by its real plate.",[254,812,813],{},"Confirm Police, radar, dispatch, and visible UI continue to show the display plate.",[254,815,816],{},"Store and respawn the vehicle and confirm the configured reset/persist policy is respected.",[254,818,819],{},"Confirm expired fake plates are not restored.",[254,821,822,823,610],{},"Restart the consuming garage resource and verify its dependency starts after ",[131,824,170],{},[53,826,828],{"id":827},"related-pages","Related pages",[251,830,831,837,843],{},[254,832,833],{},[834,835,750],"a",{"href":836},"../setup/configuration",[254,838,839],{},[834,840,842],{"href":841},"../reference/exports","Exports",[254,844,845],{},[834,846,848],{"href":847},"../changelog","Changelog",[850,851,852],"style",{},"html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}",{"title":129,"searchDepth":137,"depth":155,"links":854},[855,856,857,858,862,863,864],{"id":55,"depth":155,"text":56},{"id":113,"depth":155,"text":114},{"id":271,"depth":155,"text":272},{"id":419,"depth":155,"text":420,"children":859},[860,861],{"id":427,"depth":162,"text":428},{"id":613,"depth":162,"text":614},{"id":749,"depth":155,"text":750},{"id":801,"depth":155,"text":802},{"id":827,"depth":155,"text":828},"Integrate garages, frameworks, Police tools, and custom resources with real and displayed vehicle plates.","md",null,{},"/docs/jobs/mechanicjob/features/fake-plate-integration",{"title":5,"description":865},{"loc":869},"1.docs/0.jobs/2.mechanicjob/3.features/9.fake-plate-integration","XHpbwE54aGZVXuWTV8_wH3NgwOSkAHG4Rxe44zhEJ20",[875,880],{"title":876,"path":877,"stem":878,"description":879,"children":-1},"External Nitro HUD","/docs/jobs/mechanicjob/features/nitro-hud-integration","1.docs/0.jobs/2.mechanicjob/3.features/8.nitro-hud-integration","Connect an external HUD to Nitro state, consumption, bottle data, and live client updates.",{"title":881,"path":882,"stem":883,"description":884,"children":-1},"Inventory Items","/docs/jobs/mechanicjob/reference/inventories","1.docs/0.jobs/2.mechanicjob/4.reference/1.inventories","Use these configurations to prepare your inventory for the Sky Mechanic Job resource.",[],1784891952492]