> For the complete documentation index, see [llms.txt](https://atiysus-organization.gitbook.io/aty-scripts/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://atiysus-organization.gitbook.io/aty-scripts/zone-creator/guide/weather-script-compatibility.md).

# Weather Script Compatibility

Zone weather has to win against whatever weather/time script your server already runs. Those scripts work by **force-writing the weather in a loop** (qb-weathersync rewrites it every 100 ms), so simply calling `SetWeatherTypeNow` once is not enough — the other script overwrites it a fraction of a second later.

Zone Creator solves this with two mechanisms that work together.

### 1. The hold loop (always on, no setup)

While you are inside a weather zone, Zone Creator watches the live weather and **re-asserts it the instant anything moves it**. Whatever the other script writes, it is immediately written back.

* Runs **only** while a zone weather override is active — zero cost otherwise.
* Only **writes** when it detects a change; otherwise it is one cheap comparison.
* Also re-applies the **rain level** and a **frozen clock**, which sync loops zero out even when the weather type itself matches (this is why `RAIN` / `THUNDER` zones used to look dry).
* If another script hijacks the weather **during a fade**, the fade is abandoned and the weather is set instantly — a fade that is being fought never completes.

{% hint style="success" %}
This means zone weather works with **any** weather resource out of the box, even one Zone Creator has never heard of. You do not have to configure anything.
{% endhint %}

### 2. Pause adapters (optional, recommended)

The hold loop guarantees the result, but two systems writing the weather every frame is wasteful. If we can politely **pause** the other script while the override is active, they stop fighting entirely — and its clock/rain loops stop stomping on ours.

#### Built in

| Script             | Status                                                                                                                                                        |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **qb-weathersync** | Handled automatically. Verified against 2.3.0 — paused with `DisableSync`, resumed with `EnableSync`, and its three side effects are compensated (see below). |

#### Adding your own

Add an entry to `Config.WeatherSyncs` in `config.lua`:

```lua
Config.WeatherSyncs = {
    -- key   = resource name (only called when that resource is started)
    -- value = function(taking)  taking=true → pause it, false → resume it
    ['cd_easytime']         = function(taking) exports['cd_easytime']:PauseSync(taking) end,
    ['Renewed-Weathersync'] = function(taking) exports['Renewed-Weathersync']:setPermanentWeather(taking) end,
    ['vSync']               = function(taking) TriggerEvent('vSync:toggleSync', not taking) end,
    ['av_weather']          = function(taking) exports['av_weather']:SetSyncEnabled(not taking) end,
}
```

{% hint style="warning" %}
The lines above are **templates, not verified APIs**. Export and event names differ between versions and forks — check your script's own documentation and adjust. A wrong name is harmless (the call is wrapped in `pcall` and logged when `Config.Debug` is on) — the hold loop still keeps the override working.
{% endhint %}

For a single custom script you can also use the older one-off hook:

```lua
Config.Integrations = {
    onWeatherOverride = function(taking) exports['my-weather']:PauseSync(taking) end,
}
```

### 3. Patching a weather script that has no pause API

Some scripts expose no way to stop them. You do **not** need this for zone weather to work (the hold loop covers it), but patching gives the cleanest result. The recipe is the same for almost every weather resource:

1. Open its **client** file and find the loop that writes the weather — it will look something like:

```lua
CreateThread(function()
    while true do
        Wait(100)
        SetWeatherTypePersist(CurrentWeather)
        SetWeatherTypeNowPersist(CurrentWeather)
        SetRainLevel(...)
    end
end)
```

2. Add a module-level flag and an event to toggle it:

```lua
local zcPaused = false

RegisterNetEvent('myweather:pause', function(state) zcPaused = state end)
```

3. Guard the loop body with it:

```lua
CreateThread(function()
    while true do
        Wait(100)
        if not zcPaused then
            SetWeatherTypePersist(CurrentWeather)
            -- … the rest of the loop
        end
    end
end)
```

4. Point Zone Creator at it:

```lua
Config.WeatherSyncs = {
    ['my-weather'] = function(taking) TriggerEvent('myweather:pause', taking) end,
}
```

Do the same for the script's **time/clock** loop if it has a separate one.

### Side effects of pausing (and how they are handled)

Pausing a weather script usually has consequences. qb-weathersync's `DisableSync` is a good example — it does three things beyond stopping the loop, and Zone Creator compensates for all of them:

| Side effect of `DisableSync`                                      | How Zone Creator compensates                                                                                                                                                                                                   |
| ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `NetworkOverrideClockTime(18,0,0)` — the clock **locks at 18:00** | qb's server keeps broadcasting `SyncTime(base, offset)` every 2 s; we read it and drive the clock with qb's own formula, so time keeps running normally. If the zone asks to **Freeze Time**, the zone's hour is used instead. |
| `SetRainLevel(0.0)` and its loop stops                            | We set the rain ourselves from the weather type, using qb's own values (`RAIN` = 0.3, `THUNDER` = 0.5, otherwise 0).                                                                                                           |
| The weather is pulled to `CLEAR`                                  | Harmless — our weather is applied immediately afterwards.                                                                                                                                                                      |

If you write your own adapter and the clock freezes or the rain disappears, look for the same three behaviours in that script.

### Verifying it works

1. Set `Config.Debug = true`.
2. Walk into a weather zone. With `Config.Debug` on you will see a `[zc-weather] drift -> re-asserting <TYPE>` line **only** if another script is fighting the override. No line means the pause adapter is working cleanly.
3. Walk out — the weather should return to your server's normal weather within a few seconds.

{% hint style="info" %}
Zone weather is per-zone; see the **Weather** section in Zone Settings for the actual options (type, blend, freeze time, wind, snow, timed cycles, and *Only Player* vs *Everyone In* sync).
{% endhint %}
