This Rust plugin adds a virtual garage system that lets players store and respawn their vehicles through a simple UI. It supports modular cars, helicopters, boats, snowmobiles, and even custom vehicles from other plugins. Stored vehicles keep their fuel, health, inventory, and names. You can limit garage size, set per-vehicle-type caps, and block storing based on cupboard auth, safe zones, or combat status.
Features
- Store any supported vehicle with one click into your personal virtual garage, managed through a simple in-game UI.
- Save and restore vehicle health, fuel tank contents, and all inventory items, including their amounts, custom names, and skin ids.
- Preserve full modular car setups, including socket layouts, module health, engine parts, and car radios with their last tuned station.
- Tugboats and other vehicles keep their authorized players when stored and spawned back in.
- Supports saving and restoring extra storage containers attached to vehicles, whether placed by players (such as on tugboats) or by other plugins, including the contents inside them.
- Smart spawn near you with space and slope checks, requires clear line of sight to store, and blocks if someone is seated.
- View each vehicle's condition, fuel, and stored items at a glance.
- Open via chat command or an optional HUD button.
- Set per-type limits for air, land, water, and siege vehicles, plus an overall garage size.
- Upgrade limits for VIPs or groups using permission profiles.
- Block storing or spawning if you're not TC-authorized, in a safe zone, building-blocked, or under combat/raid block (Better No Escape).
- Let admins view another player's garage in read-only mode.
- Auto-purge on map wipe, or keep garages across wipes.
- Supports a wide range of vehicles including helicopters, boats, submarines, modular cars, bikes, snowmobiles, siege weapons, and more, with full compatibility for custom vehicles made with Karuza's plugin.
Permissions
virtualgarage.use- Lets a player open the garage, store a nearby vehicle, spawn it later, and remove their own saved entries.virtualgarage.admin- Staff power. Also allows viewing someone else's garage in read-only withgarage.view.virtualgarage.<suffix>- Tier perks from your config (e.g.virtualgarage.vip). Grant these to give bigger garages or different per-type limits.
Commands
/garage(chat) - Opens your Virtual Garage UI.garage.view <playerNameOrSteamId>(F1) - Admins only. Opens a read-only view of another player's garage. Useful for support/admin checks.
Configuration
JSON:
{
"Version": "1.0.0",
"Purge Garage Data After Server Wipe": true,
"Garage Chat Command": "garage",
"Hud Button": {
"Show HUD Button": true,
"Text (ignored if Icon Url or Icon Sprite is set)": "Virtual Garage",
"Font Size": 14,
"Text Color": "1 1 1 1",
"Background Color": "0 0 0 0.7",
"Anchor Min": "1 1",
"Anchor Max": "1 1",
"Offset Min (use -160 -60 for a text button layout)": "-68 -78",
"Offset Max (use -20 -30 for a text button layout)": "-20 -30",
"Icon Url (External)": "",
"Icon Sprite (Game Asset Path)": "assets/icons/level_metal.png",
"Icon Offset Min": "-18 -18",
"Icon Offset Max": "18 18"
},
"Default Garage Capacity (All Vehicles)": 4,
"Default Limit Per Vehicle Type (Air / Land / Water / Siege)": {
"Air": -1,
"Land": -1,
"Water": -1,
"Siege": -1
},
"Permission Profiles": [
{
"Permission Suffix": "vip",
"Garage Capacity (Total Stored Vehicles)": 8,
"Vehicle Type Limits": {
"Air": -1,
"Land": -1,
"Water": -1,
"Siege": -1
}
}
],
"Supported Vehicles": [
{ "Short Prefab Name": "minicopter.entity", "Category (Air / Land / Water / Siege)": "Air", "Friendly Name": "Minicopter", "Icon Url (External)": "", "Icon Sprite (Game Asset Path)": "assets/content/vehicles/minicopter/minicopter.entity.icon.png" },
{ "Short Prefab Name": "scraptransporthelicopter", "Category (Air / Land / Water / Siege)": "Air", "Friendly Name": "Scrap Transport Helicopter", "Icon Url (External)": "", "Icon Sprite (Game Asset Path)": "assets/content/vehicles/scrap heli carrier/scraptransporthelicopter.icon.png" },
{ "Short Prefab Name": "attackhelicopter.entity", "Category (Air / Land / Water / Siege)": "Air", "Friendly Name": "Attack Helicopter", "Icon Url (External)": "", "Icon Sprite (Game Asset Path)": "assets/content/vehicles/attackhelicopter/attackhelicopter.icon.png" },
{ "Short Prefab Name": "2module_car_spawned.entity", "Category (Air / Land / Water / Siege)": "Land", "Friendly Name": "Small Modular Car", "Icon Url (External)": "", "Icon Sprite (Game Asset Path)": "assets/prefabs/vehicle/vehiclechassisitems/2module_chassis/2module_chassis.icon.png" },
{ "Short Prefab Name": "3module_car_spawned.entity", "Category (Air / Land / Water / Siege)": "Land", "Friendly Name": "Medium Modular Car", "Icon Url (External)": "", "Icon Sprite (Game Asset Path)": "assets/prefabs/vehicle/vehiclechassisitems/3module_chassis/3module_chassis.icon.png" },
{ "Short Prefab Name": "4module_car_spawned.entity", "Category (Air / Land / Water / Siege)": "Land", "Friendly Name": "Large Modular Car", "Icon Url (External)": "", "Icon Sprite (Game Asset Path)": "assets/prefabs/vehicle/vehiclechassisitems/4module_chassis/4module_chassis.icon.png" },
{ "Short Prefab Name": "pedalbike", "Category (Air / Land / Water / Siege)": "Land", "Friendly Name": "Bicycle", "Icon Url (External)": "", "Icon Sprite (Game Asset Path)": "assets/content/vehicles/bikes/pedalbike.icon.png" },
{ "Short Prefab Name": "pedaltrike", "Category (Air / Land / Water / Siege)": "Land", "Friendly Name": "Trike", "Icon Url (External)": "", "Icon Sprite (Game Asset Path)": "assets/content/vehicles/bikes/pedaltrike.icon.png" },
{ "Short Prefab Name": "motorbike", "Category (Air / Land / Water / Siege)": "Land", "Friendly Name": "Motorbike", "Icon Url (External)": "", "Icon Sprite (Game Asset Path)": "assets/content/vehicles/bikes/motorbike.icon.png" },
{ "Short Prefab Name": "motorbike_sidecar", "Category (Air / Land / Water / Siege)": "Land", "Friendly Name": "Motorbike with Sidecar", "Icon Url (External)": "", "Icon Sprite (Game Asset Path)": "assets/content/vehicles/bikes/motorbike_sidecar.icon.png" },
{ "Short Prefab Name": "snowmobile", "Category (Air / Land / Water / Siege)": "Land", "Friendly Name": "Snowmobile", "Icon Url (External)": "", "Icon Sprite (Game Asset Path)": "assets/content/vehicles/snowmobiles/tomahasnowmobile.icon.png" },
{ "Short Prefab Name": "rowboat", "Category (Air / Land / Water / Siege)": "Water", "Friendly Name": "Rowboat", "Icon Url (External)": "", "Icon Sprite (Game Asset Path)": "assets/content/vehicles/boats/rowboat/rowboat.icon.png" },
{ "Short Prefab Name": "rhib", "Category (Air / Land / Water / Siege)": "Water", "Friendly Name": "RHIB", "Icon Url (External)": "https://cdn.rusthelp.com/images/256/rhib.png", "Icon Sprite (Game Asset Path)": "" },
{ "Short Prefab Name": "tugboat", "Category (Air / Land / Water / Siege)": "Water", "Friendly Name": "Tugboat", "Icon Url (External)": "", "Icon Sprite (Game Asset Path)": "assets/content/vehicles/boats/tugboat/tugboat.icon.png" },
{ "Short Prefab Name": "kayak", "Category (Air / Land / Water / Siege)": "Water", "Friendly Name": "Kayak", "Icon Url (External)": "", "Icon Sprite (Game Asset Path)": "assets/content/vehicles/boats/kayak/kayak.icon.png" },
{ "Short Prefab Name": "submarinesolo.entity", "Category (Air / Land / Water / Siege)": "Water", "Friendly Name": "Solo Submarine", "Icon Url (External)": "", "Icon Sprite (Game Asset Path)": "assets/content/vehicles/submarine/submarinesolo.entity.icon.png" },
{ "Short Prefab Name": "submarineduo.entity", "Category (Air / Land / Water / Siege)": "Water", "Friendly Name": "Duo Submarine", "Icon Url (External)": "", "Icon Sprite (Game Asset Path)": "assets/content/vehicles/submarine/submarineduo.entity.icon.png" },
{ "Short Prefab Name": "catapult.entity", "Category (Air / Land / Water / Siege)": "Siege", "Friendly Name": "Catapult", "Icon Url (External)": "https://cdn.rusthelp.com/images/256/catapult.png", "Icon Sprite (Game Asset Path)": "" },
{ "Short Prefab Name": "siegetower.entity", "Category (Air / Land / Water / Siege)": "Siege", "Friendly Name": "Siege Tower", "Icon Url (External)": "", "Icon Sprite (Game Asset Path)": "assets/content/vehicles/siegeweapons/siegetower/siegetower.entity.icon.png" },
{ "Short Prefab Name": "batteringram.entity", "Category (Air / Land / Water / Siege)": "Siege", "Friendly Name": "Battering Ram", "Icon Url (External)": "", "Icon Sprite (Game Asset Path)": "assets/content/vehicles/siegeweapons/batteringram/batteringram.item.icon.png" }
],
"Nearby Vehicle Detection Radius": 6.0,
"Garage Rules": {
"Only Allow Storing Owned Vehicles": false,
"Require Line Of Sight To Vehicles": true,
"Require Tool Cupboard Authorization To Store Vehicles": false,
"Require Tool Cupboard Authorization To Spawn Vehicles": false,
"Prevent Storing Vehicles In Safe Zones": true,
"Prevent Spawning Vehicles In Safe Zones": true,
"Prevent Storing Vehicles In Enemy Territory (Building Blocked)": true,
"Prevent Spawning Vehicles In Enemy Territory (Building Blocked)": true,
"Prevent Storing Vehicles While In Combat (Better No Escape)": false,
"Prevent Spawning Vehicles While In Combat (Better No Escape)": false,
"Prevent Storing Vehicles While Raid-Blocked (Better No Escape)": false,
"Prevent Spawning Vehicles While Raid-Blocked (Better No Escape)": false
}
}
Purge Garage Data After Server Wipe- Clears everyone's saved vehicles when you do a fresh map wipe. Turn off if you run no-wipe or want garages to carry over. Leave on for classic wipe cycles so old vehicles don't follow players into a new map.Garage Chat Command- The word players type to open the garage. Don't include the slash here—players will type/yourword.Hud Button- Controls the little on-screen button that opens the garage.Show HUD Button- Show/hide the button for players who have access.Text- The label on the button. If an icon is provided, text is hidden automatically.Font Size- How big the label looks.Text Color- Color of the label using"r g b a"(0–1). Example:"1 1 1 1"is white.Background Color- Button background color in the same"r g b a"format. Use some alpha (like0.7) so it blends.Anchor Min/Anchor Max- Where the button sits on the screen."1 1"sticks it to the top-right;"0 0"is bottom-left. Keep both at"1 1"for top-right.Offset Min/Offset Max- Nudge the button's position/size in pixels from that corner.Icon Url (External)- Optional image link. If set, this icon is shown instead of text.Icon Sprite (Game Asset Path)- In-game sprite path (e.g."assets/icons/level_metal.png"). Used if no URL is given.Icon Offset Min/Icon Offset Max- Controls the size of the icon itself. Anchors are fixed centered, so these offsets decide how large the icon appears.
Default Garage Capacity- How many vehicles each player can store by default (before any VIP or special perms).Default Limit Per Vehicle Type- Base caps for each category that apply to everyone.Air/Land/Water/Siege- Use-1for unlimited, or any number0+for a hard cap.
(If a saved vehicle can't be matched to a category for some reason, it's treated as Land.)
Permission Profiles- Optional VIP/tier perks that change capacity and per-type limits when a player has a matching permission.Permission Suffix- Becomesvirtualgarage.<suffix>automatically.Garage Capacity- Total slots granted by this tier. If a player has multiple tiers, they get the highest total capacity among them (or the default if that's higher).Vehicle Type Limits- Per-type caps for this tier. If a player has multiple tiers:- If any tier sets a type to
-1, that type is unlimited. - Otherwise, the smallest non-negative number across their tiers is used (the strictest cap).
- If no tier sets a non-negative cap for a type, the default type cap is used.
- If any tier sets a type to
Supported Vehicles- The whitelist of vehicles your garage recognizes (so names/icons show correctly and type limits work).Short Prefab Name- A lowercase bit of the game's internal name used to match the vehicle (e.g.,"minicopter.entity").Category- Decides which type cap applies and how much space is needed to spawn.Friendly Name- What players see in the UI (falls back to a generic name if left blank).Icon Url- Optional PNG link for a custom icon. The server will fetch and cache it at startup.Icon Sprite- In-game icon path to use if you don’t provide a URL (or as a fallback).
Nearby Vehicle Detection Radius- How far (in meters) around the player the plugin looks for a vehicle to store.Garage Rules- Flip these on/off to control when storing and spawning is allowed.Only Allow Storing Owned Vehicles- You can only store vehicles you own.Require Line Of Sight To Vehicles- If true, you must be able to see the vehicle to store it. Turn this off for servers using Karuza's custom vehicles, since parts of those can block the raycast.Require Tool Cupboard Authorization To Store Vehicles- You must be authorized on a nearby TC to store.Require Tool Cupboard Authorization To Spawn Vehicles- The spawn spot must be covered by a TC you're authorized on.Prevent Storing Vehicles In Safe Zones- No storing inside Outpost/Bandit (or any safe zone).Prevent Spawning Vehicles In Safe Zones- No spawning into safe zones.Prevent Storing Vehicles In Enemy Territory- If you're building-blocked, you can't store.Prevent Spawning Vehicles In Enemy Territory- If the spawn spot is under someone else's TC, spawning is blocked.Prevent Storing Vehicles While In Combat- Blocks storing while combat-blocked (only if Better No Escape is installed).Prevent Spawning Vehicles While In Combat- Same idea, but for spawning.Prevent Storing Vehicles While Raid-Blocked- Blocks storing while raid-blocked (needs Better No Escape).Prevent Spawning Vehicles While Raid-Blocked- Same, for spawning.
Stored Data
JSON:
{
"Player Garages": {
"76561198000000001": {
"Vehicles": [
{
"Id": "a1b2c3d4e5f6477f8a9b0c1d2e3f4a5b",
"Display Name": "Minicopter",
"Prefab Path": "assets/content/vehicles/minicopter/minicopter.entity.prefab",
"Health": 380.0,
"Maximum Health": 500.0,
"Fuel": 120,
"Modular Car": null,
"Storage Contents": [
{
"Short Name": "metal.fragments",
"Custom Name": "",
"Amount": 200,
"Skin Id": 0,
"Condition": 0.0,
"Maximum Condition": 0.0
},
{
"Short Name": "lowgradefuel",
"Custom Name": "",
"Amount": 120,
"Skin Id": 0,
"Condition": 0.0,
"Maximum Condition": 0.0
}
]
},
{
"Id": "f1e2d3c4b5a697887766554433221100",
"Display Name": "Small Modular Car",
"Prefab Path": "assets/content/vehicles/modularcar/2module_car_spawned.entity.prefab",
"Health": 220.0,
"Maximum Health": 300.0,
"Fuel": 60,
"Modular Car": {
"Total Sockets": 2,
"Modules": [
{
"Socket Index": 0,
"Item Id": 123456,
"Health": 150.0,
"Maximum Health": 200.0
},
{
"Socket Index": 1,
"Item Id": 123457,
"Health": 200.0,
"Maximum Health": 200.0
}
]
},
"Storage Contents": [
{
"Short Name": "engine.part.tier3",
"Custom Name": "",
"Amount": 4,
"Skin Id": 0,
"Condition": 0.0,
"Maximum Condition": 0.0
},
{
"Short Name": "lowgradefuel",
"Custom Name": "",
"Amount": 60,
"Skin Id": 0,
"Condition": 0.0,
"Maximum Condition": 0.0
}
]
}
]
}
}
}
Player Garages- Everyone's saved garages, listed by SteamID.Vehicles- The player's saved vehicles (the list you see in the UI).
Id- A unique ID we use behind the scenes.Display Name- The name you see in the UI.Prefab Path- The game's internal path so the vehicle can be brought back correctly.Health/Maximum Health- How healthy it was when saved, and its max health at that time.Fuel- How much low grade fuel was in it when saved. This goes straight back into the fuel tank on spawn.Modular Car- Only present for modular cars; stores what modules were on the chassis and their condition.Storage Contents- Items found in the vehicle's storage when saved. On spawn, non-fuel items are put back into its containers.
Short Name- The game's item short name (e.g.,metal.fragments).Custom Name- A custom name if the item had one.Amount- How many.Skin Id- Skin applied to the item, if any.Condition/Maximum Condition- For items that can take damage/durability.
Total Sockets- How many module slots the chassis supports.Modules- Each fitted module with:Socket Index- Which slot it starts in.Item Id- The module type (used to put the same module back).Health/Maximum Health- The module's condition when saved.
Localization
JSON:
{
"Error.NoPermission": "You do not have permission to use this command.",
"Error.CombatBlocked": "You are combat-blocked.",
"Error.RaidBlocked": "You are raid-blocked.",
"Error.BuildingBlocked": "You can't do that near an enemy base.",
"Error.SafeZone": "You can't do that in a safe zone.",
"Error.RequireAuthedTC": "You must be within range of a Tool Cupboard you're authorized on.",
"Error.SpawnPointBlocked": "Spawn point is blocked by an enemy Tool Cupboard.",
"Error.NoLineOfSight": "You must have a clear line of sight to the vehicle.",
"Error.GarageFull": "Your virtual garage is full ({0}/{1}).",
"Error.NoOwnedVehicleNearby": "No supported owned vehicle nearby.",
"Error.NoVehicleNearby": "No supported vehicle nearby.",
"Error.OnlyOwnedVehicles": "You can only store vehicles you own.",
"Error.HasPassengers": "You can't store a vehicle while it has passengers.",
"Error.CategoryCapacityFull": "Your {0} capacity is full ({1}/{2}).",
"Info.ItemStacksNote": ", {0} item stacks",
"Info.StoredVehicle": "Stored {0} ({1}/{2} HP, Fuel {3}{4}).",
"Info.SpawnedVehicle": "Spawned {0} near you.",
"Error.Usage.View": "Usage: vg.view <playerNameOrSteamId>",
"Error.PlayerNotFound": "Player not found (or ambiguous). Use a more specific name or a SteamID64.",
"Error.ReadOnlyView": "Read-only view.",
"Error.SpawnFailed": "Failed to spawn vehicle. Pick a clearer area and try again.",
"Error.InvalidVehicleIndex": "Invalid vehicle index.",
"Error.NothingToDelete": "Nothing to delete.",
"Error.VehicleNotFound": "Vehicle not found (already removed).",
"Info.RemovedStoredVehicle": "Removed {0} from your garage.",
"UI.Title": "Virtual Garage",
"UI.Viewing": "Virtual Garage — Viewing {0}",
"UI.Overview.Title": "Garage Overview",
"UI.Overview.Vehicles": "Vehicles",
"UI.Overview.Free": "free",
"UI.Overview.NeedRepair": "Need Repair",
"UI.Overview.LowFuel": "Low Fuel",
"UI.Overview.ItemStacks": "Item Stacks",
"UI.Type.Land": "Land",
"UI.Type.Air": "Air",
"UI.Type.Water": "Water",
"UI.Type.Siege": "Siege",
"UI.List.Title": "Stored Vehicles ({0})",
"UI.List.Title.ReadOnly": "Stored Vehicles ({0}) — Read-Only",
"UI.List.Empty": "You have no stored vehicles yet.",
"UI.Page": "Page {0} / {1}",
"UI.Prev": "Previous",
"UI.Next": "Next",
"UI.Button.Spawn": "Spawn Vehicle",
"UI.Button.Store": "Store Vehicle",
"UI.Button.Cancel": "Cancel",
"UI.Button.Delete": "Delete",
"UI.Hud.VirtualGarage": "Virtual Garage",
"UI.Current.NearVehicle": "Nearby vehicle:",
"UI.Current.NotNearOwned": "You are not near one of your supported vehicles that you own.",
"UI.Current.NotNear": "You are not near one of your supported vehicles.",
"UI.Current.Tagline.Save": "Save this vehicle to retrieve it at any garage",
"UI.Current.Tagline.LoS": "Line of sight to the vehicle is required",
"UI.Current.Tagline.Approach": "Approach a supported vehicle",
"UI.Delete.Title": "Delete {0} from your garage?",
"UI.Delete.Sub": "This will permanently remove the stored vehicle and its saved contents.",
"UI.Stats.Condition": "Condition",
"UI.Stats.Fuel": "Fuel",
"UI.Stats.Storage": "Storage",
"UI.Stats.Engine": "Engine",
"UI.Stats.Rockets": "Rockets",
"UI.Stats.Flares": "Flares",
"UI.Band.Destroyed": "Destroyed",
"UI.Band.Critical": "Critical",
"UI.Band.Poor": "Poor",
"UI.Band.Fair": "Fair",
"UI.Band.Good": "Good",
"UI.Band.Excellent": "Excellent",
"UI.Band.Empty": "Empty",
"UI.Band.Low": "Low",
"UI.Band.Medium": "Medium",
"UI.Band.High": "High",
"UI.Band.Full": "Full"
}
Developer Hooks
C#:
void OnVirtualGarageSaveAttachments(BaseEntity vehicle, Dictionary<string, JObject> metadata, BasePlayer owner, string vehicleGuid)
vehicle- TheBaseEntityof the vehicle being stored.metadata- A modifiable dictionary where your plugin can store any additional save data asJObjectvalues.owner- The player who is storing the vehicle.vehicleGuid- A unique string id for this saved vehicle entry.
- Storage boxes attached to a vehicle
- Auto turrets mounted on modular cars or minicopters
- Code locks or key locks
- Sirens or alarms
- Wooden signs with custom images
OnVirtualGarageRestoreAttachments hook when the vehicle is respawned.
C#:
void OnVirtualGarageRestoreAttachments(BaseEntity vehicle, Dictionary<string, JObject> metadata, BasePlayer owner, string vehicleGuid)
vehicle- TheBaseEntitythat was just spawned from garage data.metadata- The metadata dictionary previously stored during the save phase.owner- The player who requested the vehicle spawn.vehicleGuid- The unique string id for this vehicle in the stored data.
This example shows how the Vehicle License Plate plugin uses both hooks to save and restore attached license plate signs when vehicles are stored or spawned from Virtual Garage.
C#:
private void OnVirtualGarageSaveAttachments(BaseEntity vehicle, Dictionary<string, JObject> metadata, BasePlayer owner, string vehicleGuid)
{
if (vehicle == null || metadata == null)
return;
PlateInfo plateInfo = GetSavedPlateInfo(vehicle);
if (plateInfo == null)
return;
JObject plateData = new JObject
{
["VehiclePrefab"] = plateInfo.VehiclePrefab,
["PlateText"] = plateInfo.PlateText,
["FontSize"] = plateInfo.FontSize,
["TextColor"] = plateInfo.TextColor,
["BackgroundColor"] = plateInfo.BackgroundColor,
["PermitTierSuffix"] = plateInfo.PermitTierSuffix,
["SignLocalPosition"] = new JArray(plateInfo.SignLocalPosition),
["SignLocalRotation"] = new JArray(plateInfo.SignLocalRotation),
["SignLocalScale"] = new JArray(plateInfo.SignLocalScale),
["PlayerEdited"] = plateInfo.PlayerEdited
};
metadata["VehicleLicensePlate"] = plateData;
}
private void OnVirtualGarageRestoreAttachments(BaseEntity vehicle, Dictionary<string, JObject> metadata, BasePlayer owner, string vehicleGuid)
{
if (vehicle == null || metadata == null)
return;
JObject plateData;
if (!metadata.TryGetValue("VehicleLicensePlate", out plateData))
return;
float[] position = ReadFloatArray(plateData["SignLocalPosition"], new[] { 0f, 0.85f, -1.25f });
float[] rotation = ReadFloatArray(plateData["SignLocalRotation"], new[] { 0f, 180f, 0f });
float[] scale = ReadFloatArray(plateData["SignLocalScale"], new[] { 1f, 1f, 1f });
NextTick(() =>
{
if (vehicle == null || vehicle.IsDestroyed)
return;
// Recreate the sign and reapply saved styling
Signage signage = AddPlateSignAt(vehicle, new Vector3(position[0], position[1], position[2]), new Vector3(rotation[0], rotation[1], rotation[2]));
if (signage == null)
return;
ApplyAndNetworkScale(signage, scale[0]);
string text = (string)plateData["PlateText"];
string fg = (string)plateData["TextColor"];
string bg = (string)plateData["BackgroundColor"];
int font = (int)plateData["FontSize"];
string tierSuffix = (string)plateData["PermitTierSuffix"];
PermitTierConfig tier = GetPermitTierBySuffix(tierSuffix);
WritePlateSignTextWithStyle(signage, owner, text, tier, font, fg, bg);
SavePlateInfo(vehicle, signage, text, font, fg, bg, tier, GetVehicleProfile(vehicle));
});
}

