Skip to main content
This is unreleased documentation for the next Zaparoo Core release.
For up-to-date documentation, see the latest version (Stable).
Version: Next

Readers Config

Part of the config file reference. Keys are shown with their type and default, followed by what they do and an example.

Readers

[readers]
auto_detect = true
scan_history = 30

auto_detect

KeyTypeDefault
auto_detectbooleantrue

auto_detect enables or disables automatically searching for and probing possible connected readers on the host device.

It may be required to disable this option if auto-detection is causing problems with unrelated connected devices.

scan_history

KeyTypeDefault
scan_historyinteger30

scan_history specifies how many days of scan history to keep for the recent scans list. Old scan records are automatically cleaned up.

[readers]
scan_history = 30

Set to 0 to keep all scan history forever (disables cleanup).

readers.scan

readers.scan is a sub-section of readers and must be defined with the header: [readers.scan]

[readers.scan]
mode = 'hold'
exit_delay = 3.0
ignore_system = [ 'PC', 'MSX' ]
on_scan = '**echo:card was scanned'
on_remove = '**echo:card was removed'
ignore_on_connect = true
allow_relaunch = false

mode

KeyTypeDefault
modestring ("tap" | "hold")tap

mode defines the behavior of scans. It has two options:

  • tap is the default mode and means when a token is used with a reader it can be removed again without affecting the playing media. Tapping a token that resolves to the media already playing leaves it running, unless allow_relaunch is on.
  • hold mode makes it so a token must be held to the reader for as long as any launched media will play. That is, after a token is removed from the reader, it will exit the media. This makes a token act more like real physical media. Core does not currently make any attempt to save before exiting media. See exit_delay, ignore_system, and on_remove for related options.

mode is the device-wide default. One reader can override it with scan_mode on its [[readers.connect]] entry or on its driver, and one token can override its reader with the #tap and #hold traits.

exit_delay

KeyTypeDefault
exit_delayfloat (≥0.0)0.0

exit_delay adds a delay, in seconds, before media is exited after a token is removed from a reader. It's only active if hold mode is also active.

For example, if exit_delay was set to 2.3, it would mean when a token is removed from a reader, instead of immediately exiting the media, a timer is started for 2.3 seconds first. If the same token is placed back on the reader before the timer is complete, the timer will be cleared and the media won't exit.

This feature can be useful if you want to, using a single reader, scan other tokens such as adding credit without exiting the current game.

ignore_system

KeyTypeDefault
ignore_systemstring[][]

ignore_system is a list of systems which will not exit playing media on token removal. It's only active in hold mode.

on_scan

KeyTypeDefault
on_scanstring

on_scan is a hook containing a snippet of ZapScript. It runs immediately after a token is scanned but before ZapScript on the token itself (or a mapping) is run. It is always active if enabled.

This hook can block the scan by returning an error. If the ZapScript command fails or a script executed via **execute: returns a non-zero exit code, the token processing is blocked.

Scripts executed via **execute: receive a ZAPAROO_ENVIRONMENT environment variable containing the expression environment as JSON.

on_remove

KeyTypeDefault
on_removestring

on_remove is a hook containing a snippet of ZapScript. It runs immediately after a token is removed from the reader. It's only active in hold mode.

Note that this will always run in hold mode when a token is removed from the reader, no matter if any media was launched or is active. It also does not respect the exit_delay setting and runs before any media exit logic happens.

This hook can block the remove action by returning an error. If the ZapScript command fails or a script executed via **execute: returns a non-zero exit code, the remove processing is blocked.

Scripts executed via **execute: receive a ZAPAROO_ENVIRONMENT environment variable containing the expression environment as JSON.

ignore_on_connect

KeyTypeDefault
ignore_on_connectbooleanfalse

ignore_on_connect suppresses the first token scan from each newly-connected reader, preventing accidental launches from cards left on readers at startup.

[readers.scan]
ignore_on_connect = true

When enabled, if a token is already present on a reader when it connects (e.g., a card left on the reader when Zaparoo starts), that initial scan will be silently ignored. Subsequent scans from the same reader will work normally.

allow_relaunch

KeyTypeDefault
allow_relaunchbooleanfalse

In tap mode, a scan that resolves to the media already playing is skipped and the game keeps running. This covers any token that lands on the same file, not only a repeat scan of the same card. Other commands on the token still run, and no launch or exit hooks fire. Set allow_relaunch to true to make a repeat scan restart the game from the beginning instead. Hold mode and API launches are not affected.

[readers.scan]
allow_relaunch = true

readers.scan.launch_guard

readers.scan.launch_guard is a sub-section of readers.scan and must be defined with the header: [readers.scan.launch_guard]

[readers.scan.launch_guard]
enabled = true
timeout = 15
delay = 0
require_confirm = false

enabled

KeyTypeDefault
enabledbooleanfalse

enabled turns launch guard on or off. When enabled, tokens scanned while media is playing are staged rather than launched immediately. All scans are unaffected when nothing is playing.

[readers.scan.launch_guard]
enabled = true

timeout

KeyTypeDefault
timeoutfloat (≥-1.0)15.0

timeout sets how long, in seconds, a staged token waits for confirmation before being silently dropped.

Setting timeout to 0 uses the default of 15 seconds. Setting it to a negative value (e.g., -1) disables the timeout entirely. The staged token persists until it's confirmed, replaced by another scan, or cleared when media stops.

[readers.scan.launch_guard]
timeout = 30 # wait up to 30 seconds
timeout = -1 # wait indefinitely

delay

KeyTypeDefault
delayfloat (≥0.0)0.0

delay sets a mandatory cool-down period, in seconds, before re-tap confirmation is accepted. During this window, re-tapping the same card resets both the delay and the timeout. Confirmation is not accepted until the full delay has elapsed.

When the delay expires, a ready sound plays and a tokens.staged.ready notification is sent.

delay is clamped to half of timeout if it would equal or exceed it. It is forced to 0 when timeout is negative.

[readers.scan.launch_guard]
timeout = 30
delay = 5 # block re-tap for the first 5 seconds

Setting delay to 0 (the default) disables the cool-down and re-tap confirmation is accepted immediately after staging.

require_confirm

KeyTypeDefault
require_confirmbooleanfalse

require_confirm disables re-tap confirmation. When set to true, re-tapping the staged card does nothing. The only way to launch a staged token is via the confirm API method.

[readers.scan.launch_guard]
enabled = true
require_confirm = true

This is useful when you want an external device (a physical button, a companion app, or an automation script) to be the sole confirmation path.

readers.connect

readers.connect manually defines a reader which is physically connected to the host device and is not auto-detected. It's a sub-section that can be defined multiple times, and must have this header: [[readers.connect]]

Pay attention to the double pairs of square brackets. Each defined readers.connect section must have its own header.

[[readers.connect]]
driver = 'pn532uart'
path = '/dev/ttyUSB0'

[[readers.connect]]
driver = 'file'
path = '/tmp/some_file'

driver

KeyTypeDefault
driverstring

driver specifies which reader driver should be used to attempt connection to the reader device. See reader drivers for a list of available drivers.

path

KeyTypeDefault
pathstring

path is an argument for the specified reader driver for how the device should be found. See the documentation for your specific reader hardware for configuration examples.

id_source

KeyTypeDefault
id_sourcestring

id_source specifies which identifier source to use for token identification. This is only supported by certain reader drivers:

  • opticaldrive: uuid (disc UUID), label (disc label), or merged (UUID and label together). Unset behaves like merged.

Other reader drivers ignore this setting.

enabled

KeyTypeDefault
enabledboolean

enabled temporarily disables a reader connection without removing it from the config. When not set, the connection is enabled by default.

[[readers.connect]]
driver = 'pn532uart'
path = '/dev/ttyUSB0'
enabled = false

This is useful for keeping a connection definition in the config while not actively using it, without having to delete and re-add it later.

scan_mode

KeyTypeDefault
scan_modestring ("tap" | "hold")

scan_mode sets the scan mode for this one reader, so a cartridge slot can hold while an NFC antenna on the same device taps. It takes priority over the driver's scan_mode and the global mode.

[readers.scan]
mode = 'tap'

[[readers.connect]]
driver = 'pn532'
path = '/dev/ttyUSB1'
scan_mode = 'hold'

readers.drivers

readers.drivers configures driver-specific settings. It's a sub-section that uses driver IDs as keys, and must have this header format: [readers.drivers.DRIVER_ID]

[readers.drivers.acr122pcsc]
auto_detect = false

[readers.drivers.simpleserial]
enabled = false

[readers.drivers.opticaldrive]
scan_mode = 'hold'

enabled

KeyTypeDefault
enabledbooleanvaries by driver

enabled allows you to explicitly enable or disable a specific reader driver. When not specified, the driver uses its default enabled state.

auto_detect

KeyTypeDefault
auto_detectbooleanvaries by driver

auto_detect controls whether this specific driver should participate in automatic reader detection, overriding the global auto_detect setting for this driver only. Some drivers, such as libnfcacr122, are enabled but not auto-detected until this is set to true.

scan_mode

KeyTypeDefault
scan_modestring ("tap" | "hold")

scan_mode sets the scan mode for every reader that uses this driver. A [[readers.connect]] entry's own scan_mode takes priority over it, and it takes priority over the global mode.

[readers.drivers.opticaldrive]
scan_mode = 'hold'