forge/docs/GARAGE_USAGE_GUIDE.md
2026-04-17 17:09:21 -05:00

7.9 KiB

Garage System Integration Guide

Overview

The garage system provides complete vehicle storage, retrieval, and management for Arma 3 players. Each player can store multiple vehicles with full damage and hit point tracking.

Data Storage

  • Each player's garage is persisted by the server extension through SurrealDB.
  • The map is keyed by the vehicle's unique plate (UUID)
  • Each vehicle tracks: plate (UUID), classname, overall damage, fuel, and detailed hit points
  • Plates are auto-generated when vehicles are added via garage:add
  • Empty garages are auto-created when a player first fetches their garage

Extension Commands

All commands are accessed via the garage group:

Create Garage

Creates a new empty garage for a player. Should be called when initializing a new player.

private _result = "forge_server" callExtension ["garage:create", [getPlayerUID player]];
private _emptyGarage = fromJSON (_result select 0);
// Returns: {} (empty map)

Get Garage

Retrieves all vehicles in a player's garage.

private _result = "forge_server" callExtension ["garage:get", [getPlayerUID player]];
private _garageMap = fromJSON (_result select 0);
// Returns: {"plate_uuid": {"plate":"plate_uuid","classname":"...","damage":0.0,"hit_points":{...}}, ...}

Add Vehicle

Adds a new vehicle to the garage. The system automatically generates a unique plate (UUID) for the vehicle.

private _data = createHashMapFromArray [
    ["classname", "B_Quadbike_01_F"],
    ["fuel", 1.0],
    ["damage", 0.0],
    ["hit_points", createHashMap] // Optional hit points map
];

private _result = "forge_server" callExtension ["garage:add", [
    getPlayerUID player,
    toJSON _data
]];

private _updatedGarage = fromJSON (_result select 0);
// Returns updated garage map

Update Garage (Sync)

Updates the entire garage state. Useful for syncing changes made locally.

// _garageMap is the local HashMap of vehicles
private _result = "forge_server" callExtension ["garage:update", [
    getPlayerUID player,
    toJSON _garageMap
]];

private _updatedGarage = fromJSON (_result select 0);

Patch Vehicle

Updates specific fields of a vehicle without sending the entire garage. Useful for frequent updates like fuel or damage.

private _plate = "some-plate-uuid";
private _data = createHashMapFromArray [
    ["plate", _plate],
    ["fuel", 0.8],
    ["damage", 0.1],
    // "hit_points" is optional
];

private _result = "forge_server" callExtension ["garage:patch", [
    getPlayerUID player,
    toJSON _data
]];

private _updatedGarage = fromJSON (_result select 0);

Remove Vehicle

Removes a specific vehicle from the garage by plate number. Note: If using the GarageStore, removing a vehicle locally and saving/syncing will also remove it from the server.

private _plate = "some-plate-uuid";

private _data = createHashMapFromArray [
    ["plate", _plate]
];

private _result = "forge_server" callExtension ["garage:remove", [
    getPlayerUID player,
    toJSON _data
]];

private _updatedGarage = fromJSON (_result select 0);

Delete Garage

Permanently deletes all vehicles from a player's garage.

private _result = "forge_server" callExtension ["garage:delete", [getPlayerUID player]];
// Returns: "OK" or "Error: ..."

Check Existence

Checks if a player has any vehicles in their garage.

private _result = "forge_server" callExtension ["garage:exists", [getPlayerUID player]];
private _exists = (_result select 0) == "true";

Complete Integration Example

Storing a Vehicle

fnc_storeVehicle = {
    params ["_vehicle"];

    // Get vehicle data
    private _hitPointsData = getAllHitPointsDamage _vehicle;
    private _hitPoints = createHashMapFromArray [
        ["names", _hitPointsData select 0],
        ["selections", _hitPointsData select 1],
        ["values", _hitPointsData select 2]
    ];

    // Create data hashMap
    private _data = createHashMapFromArray [
        ["classname", typeOf _vehicle],
        ["damage", damage _vehicle],
        ["hit_points", _hitPoints]
    ];

    // Add to garage (plate is auto-generated)
    private _result = "forge_server" callExtension ["garage:add", [
        getPlayerUID player,
        toJSON _data
    ]];

    // Check for error
    if ((_result select 0) find "Error:" == 0) exitWith {
        hint format ["Failed to store vehicle: %1", _result select 0];
        false
    };

    // Parse result to get the new vehicle's plate
    private _updatedGarage = fromJSON (_result select 0);
    private _newVehicle = _updatedGarage select ((count _updatedGarage) - 1);
    private _assignedPlate = _newVehicle get "plate";

    // Delete the actual vehicle from game world
    deleteVehicle _vehicle;

    hint format ["Vehicle %1 stored with plate %2!", _data get "classname", _assignedPlate];
    true
};

Retrieving and Spawning a Vehicle

fnc_spawnVehicleFromGarage = {
    params ["_vehicleIndex"];

    // Get garage
    private _result = "forge_server" callExtension ["garage:get", [getPlayerUID player]];
    private _garage = fromJSON (_result select 0);

    // Validate index
    if (_vehicleIndex >= count _garage) exitWith {
        hint "Invalid vehicle index!";
        objNull
    };

    // Get vehicle data
    private _vehicleData = _garage select _vehicleIndex;
    private _classname = _vehicleData get "classname";
    private _storedDamage = _vehicleData get "damage";
    private _hitPoints = _vehicleData get "hit_points";

    // Spawn vehicle
    private _spawnPos = player getPos [10, getDir player];
    private _vehicle = _classname createVehicle _spawnPos;

    // Apply damage
    _vehicle setDamage _storedDamage;

    // Apply hit point damage
    private _names = _hitPoints get "names";
    private _values = _hitPoints get "values";

    {
        _vehicle setHitPointDamage [_x, _values select _forEachIndex];
    } forEach _names;

    // Store plate on vehicle for future updates
    private _plate = _vehicleData get "plate";
    _vehicle setVariable ["garagePlate", _plate];

    // Remove from garage
    private _removeData = createHashMapFromArray [["plate", _plate]];
    "forge_server" callExtension ["garage:remove", [getPlayerUID player, toJSON _removeData]];

    hint format ["Vehicle %1 spawned with plate %2!", _classname, _plate];
    _vehicle
};

Hit Points Data Format

The hit points data matches Arma 3's getAllHitPointsDamage return format:

{
  "names": ["hitlfwheel", "hitlf2wheel", "hitfuel", "hitengine", "hitbody", ...],
  "selections": ["wheel_1_1_steering", "wheel_1_2_steering", "fuel_hitpoint", "engine_hitpoint", "body_hitpoint", ...],
  "values": [0, 0, 0.1, 0.2, 0, ...]
}
  • names: Hit point identifiers
  • selections: Physical selection names (can be empty strings "")
  • values: Damage values from 0.0 (no damage) to 1.0 (destroyed)

Error Handling

All commands return errors in the format "Error: <message>". Always check for this:

private _result = "forge_server" callExtension ["garage:get", [getPlayerUID player]];
private _data = _result select 0;

if (_data find "Error:" == 0) then {
    // Handle error
    systemChat format ["Garage error: %1", _data];
} else {
    // Parse and use data
    private _garage = fromJSON _data;
};

Best Practices

  1. Track Vehicle Plates: When spawning vehicles from the garage, store the plate (UUID) as a variable so you can update them later:
    _vehicle setVariable ["garagePlate", _plate];
    
  2. Auto-Creation: The system automatically creates an empty garage for new players on first access
  3. Validate Before Storage: Check that vehicles are in good condition before allowing storage
  4. Limit Garage Size: Implement a maximum number of vehicles per player
  5. Regular Updates: Update vehicle damage periodically while in use
  6. Clean Deleted Vehicles: Remove vehicles from garage when they're destroyed or sold