> For the complete documentation index, see [llms.txt](https://docs.rainmad.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.rainmad.com/resources/blackmarkets-player-run-contraband-operation/npc-vendor.md).

# NPC Vendor

NPC vendors are server-run sellers that **drive a van to a spot, park, sell from a customer UI, then depart** on a schedule. They give players a baseline place to buy without a live owner online. Everything lives under `cfg.npcVendor`.

{% hint style="success" %}
You don't have to write this config by hand. The admin panel has an **NPC Vendor wizard** that lets you pick locations in-world, set the schedule and items, and then copies a ready-to-paste config block. See [Admin Panel](/resources/blackmarkets-player-run-contraband-operation/admin-panel.md).
{% endhint %}

## Global settings

```lua
cfg.npcVendor = {
    enabled           = true,                 -- master switch for all NPC vendors
    npcModel          = `a_m_m_business_01`,  -- default ped model
    pricingMultiplier = 3.0,                  -- default sell price = item supplyPrice × this

    vendors = { --[[ list of vendors, see below ]] },
}
```

`pricingMultiplier` turns each item's `cfg.items.supplyPrice` into a sell price. A per-item `price` (below) overrides it.

## A vendor

```lua
vendors = {
    {
        name = 'Paleto Bay',                  -- label shown only in the admin dashboard
        npcModel = `a_m_m_business_01`,       -- optional per-vendor model override
        pricingMultiplier = 3.0,              -- optional per-vendor multiplier override

        locations = {                         -- van parks/sells at one of these (picked per spawn)
            vec4(-280.70, 6034.97, 30.52, 231.17),
        },

        schedule = {
            enabled = true,
            mode = 'real',                    -- 'real' (clock) | 'game' (in-game hour)
            real = {                          -- cron windows when mode = 'real'
                { open = '0 19 * * *', close = '0 23 * * *' },
            },
            game = {                          -- hour windows when mode = 'game'
                -- { startHour = 19, stopHour = 23 },
            },
        },

        items = {                             -- what this vendor sells
            { name = 'WEAPON_PISTOL' },       -- uses pricingMultiplier
            { name = 'WEAPON_SMG', price = 12000 }, -- fixed price override
            { name = 'ammo-9' },
        },
    },
}
```

### Fields

| Field               | Required | Description                                                                                                  |
| ------------------- | -------- | ------------------------------------------------------------------------------------------------------------ |
| `name`              | No       | A label shown only in the admin dashboard.                                                                   |
| `locations`         | Yes      | One or more `vec4` spots. The server picks one each time the vendor spawns and drives the van there by road. |
| `npcModel`          | No       | Per-vendor ped override (else the global `npcModel`).                                                        |
| `pricingMultiplier` | No       | Per-vendor multiplier override (else the global one).                                                        |
| `schedule`          | Yes      | When the vendor is open (see below).                                                                         |
| `items`             | Yes      | List of `{ name, price? }`. `name` must be in `cfg.items`; `price` overrides the multiplier.                 |

## Schedules

* **`mode = 'real'`** uses real-world time. Each window is a pair of cron expressions: `open` and `close`.

  ```lua
  real = {
      { open = '0 19 * * *', close = '0 23 * * *' }, -- every day, 19:00–23:00
      { open = '0 12 * * 6', close = '0 18 * * 6' }, -- Saturdays, 12:00–18:00
  }
  ```
* **`mode = 'game'`** uses the in-game clock with `startHour`/`stopHour` (0–23). Windows that wrap past midnight (e.g. `startHour = 22, stopHour = 4`) are supported.

  ```lua
  game = {
      { startHour = 19, stopHour = 23 },
  }
  ```
* **`enabled = false`** makes the vendor **always open** — it spawns permanently and never departs.

{% hint style="info" %}
When a vendor opens it drives in (`pre-spawn → driving → parking → open`) and when it closes it drives off (`departing`). You can force-start or force-stop any vendor live from the admin panel for testing.
{% endhint %}

## Picking valid locations

A location must be reachable by road. When you pick a spot in the admin wizard it's validated against the nearest road: you'll get an error if there's no road nearby, or the closest one is too far. Pick spots near drivable roads, not deep off-road or inside interiors.
