> For the complete documentation index, see [llms.txt](https://jiffyjrdevelopment.gitbook.io/jiffyjrdevelopmentdocs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://jiffyjrdevelopment.gitbook.io/jiffyjrdevelopmentdocs/jiffy-jr-development-docs/jiffy-minigames/compatibility.md).

# Compatibility

`jiffy-minigames` intercepts calls from legacy minigame resources and serves them without any changes to the scripts that make those calls.

There are two types of adapters:

***

## Built-in adapters (always active)

These handle **event-based** legacy APIs. Events in FiveM are not tied to a resource name, so `jiffy-minigames` can intercept them directly. No extra resource needed.

| Legacy resource    | Calls handled                                                                 |
| ------------------ | ----------------------------------------------------------------------------- |
| `mhacking`         | `TriggerEvent('mhacking:start', circles, time, cb)`                           |
| `skillbar`         | `TriggerEvent('skillbar:start', ...)`                                         |
| `safecracker`      | `TriggerEvent('safecracker:start', ...)`                                      |
| `datacrack`        | `TriggerEvent('datacrack:start', ...)`                                        |
| `ps-ui`            | `TriggerEvent('ps-ui:...')` + `exports['ps-ui']:Circle/Thermite/...` via shim |
| `lockpick`         | `TriggerEvent('lockpick:client:openLockpick', cb)`                            |
| `qb-minigames`     | `TriggerEvent('qb-lock:client:lockpick', ...)`                                |
| `xmmx_circlesgame` | `exports['xmmx_circlesgame']:Start(...)` via shim                             |

Each adapter can be toggled in `editable/config.lua` under `Config.Compatibility`. When a call comes in, it is logged if `Config.LogCompatCalls = true`:

```txt
[Jiffy Compat] mhacking:start → pattern (circles: 9, time: 20)
```

***

## Standalone shims (optional)

Some scripts call their dependencies by export name, e.g. `exports['ps-ui']:Circle(...)`. An export can only be served by a resource that is **literally named** `ps-ui`. `jiffy-minigames` cannot answer to that name from the inside, so shims carry the legacy name and forward calls through.

Shims are located in the `compat/` folder. They are separate resources — install only the ones you need.

### Always-included shims (in `compat/`)

| Shim folder name                               | Legacy resource it replaces                               |
| ---------------------------------------------- | --------------------------------------------------------- |
| `compat/ps-ui` → name stays `ps-ui`            | `exports['ps-ui']:Circle/Thermite/Scrambler/VarHack/Maze` |
| `compat/skillbar` → `skillbar`                 | `exports['skillbar']:CreateSkillbar/Start`                |
| `compat/safecracker` → `safecracker`           | `exports['safecracker']:Start`                            |
| `compat/datacrack` → `datacrack`               | `exports['datacrack']:Start`                              |
| `compat/lockpick` → `lockpick`                 | `exports['lockpick']:Use`                                 |
| `compat/qb-minigames` → `qb-minigames`         | `exports['qb-minigames']:Skillbar/Lockpick/Hacking`       |
| `compat/xmmx_circlesgame` → `xmmx_circlesgame` | `exports['xmmx_circlesgame']:StartCircleGame`             |
| `compat/mhacking` → `mhacking`                 | `exports['mhacking']:start` (export form only)            |

### Extra standalone shims (in `compat/`)

These three handle resources that only expose their API via name-bound exports:

| Shim folder                | Replaces            | What it routes                                                                 |
| -------------------------- | ------------------- | ------------------------------------------------------------------------------ |
| `compat/pd-safe`           | `pd-safe`           | `exports['pd-safe']:createSafe(combination, cb)` → Safecrack                   |
| `compat/utk_fingerprint`   | `utk_fingerprint`   | `TriggerEvent('utk_fingerprint:Start', levels, lives, time, cb)` → Fingerprint |
| `compat/ultra-keypackhack` | `ultra-keypackhack` | `TriggerEvent('ultra-keypadhack', lives, time, cb)` → Keypad                   |

***

## Migration guide

### `server.cfg`

```cfg
# ── 1. Remove or comment out replaced resources ──────────────
# ensure ps-ui
# ensure mhacking
# ensure safecracker
# ensure lockpick
# ensure datacrack
# ensure qb-minigames
# ensure pd-safe
# ensure utk_fingerprint
# ensure utk_hackdependency
# ensure ultra-keypackhack

# ── 2. Start jiffy-minigames ──────────────────────────────────
ensure jiffy-minigames

# ── 3. Start only the shims you need ─────────────────────────
#    (only if a script calls that resource via exports by name)
ensure jiffy-compat-pd-safe
ensure jiffy-compat-utk_fingerprint
ensure jiffy-compat-ultra-keypackhack

# ── 4. Your other scripts start after — no changes needed ────
ensure my-robbery-script
ensure my-heist-script
```

### Rules

* **Never** run a shim alongside the real legacy resource of the same name — pick one or the other.
* Shim folder names must stay exactly as shipped. The resource name the shim declares in its `fxmanifest.lua` is what the calling script sees.
* If a built-in adapter already handles the call (event-based), you **do not** need the shim for that resource. Only install a shim when a script uses `exports['resource-name']:SomeFunction(...)`.

***

## How to check if compat is working

{% stepper %}
{% step %}

## Set logging

Set `Config.LogCompatCalls = true` and `Config.Debug = true` in `editable/config.lua`.
{% endstep %}

{% step %}

## Trigger the interaction

Trigger the interaction in-game that would normally open the legacy minigame.
{% endstep %}

{% step %}

## Check the console

Check the **client F8 console** for a `[Jiffy Compat]` line.
{% endstep %}

{% step %}

## Verify the route

If nothing appears, the call may be going through an export-name route — check whether you need the matching shim.
{% endstep %}
{% endstepper %}
