ZapScript

From Zaparoo Wiki

Tokens are set up to work with Zaparoo by writing a small piece of text to them, telling Zaparoo what it should do when it's read. The most common action is to launch a game, but it can perform other actions like launching a random game or even making an HTTP request.

This text can be as simple as a path to a game file, or perform multiple custom commands in a row.

Setting Up Tokens

Zaparoo App

The Zaparoo App is a mobile app available on iOS and Android which can be used to generate commands using your phone. It can search for games stored on your device, and write a tag using your phone's NFC reader with the correct format. Tag writing functionality is available for free.

TapTUI

This is a frontend to the Zaparoo service which lets you write and interact with tokens in many advanced ways. It can browse and search games on the MiSTer to be written, and has an awesome command palette to build up more complex commands.

Launching Games

For the most basic usage, a file path can be written to a token and Zaparoo will attempt to find the file on the device and launch it. The required system and configuration for the game will be automatically selected based on the file path. On MiSTer, you can also launch arcade .mra files, shortcut .mgl files and core .rbf files with just their path.

Zaparoo uses the following rules, in order, to find the game file. Keep these rules in mind if you want a token to work well between different devices.

If you're not sure what to do, it's recommended to use the System Lookup method for the best portability between devices.

Absolute Path

Any path starting with a / will be treated as an absolute path.

For example, to launch a game, write something like this to the token:

/media/fat/games/Genesis/1 US - Q-Z/Some Game (USA, Europe).md

This is the least portable method, as it will only work on the device with the exact same file path.

Relative Path

It's also possible to use a file path relative to the games folder. This will search for the file in all standard MiSTer game folder paths including CIFS and USB.

For example:

Genesis/1 US - Q-Z/Some Game (USA, Europe).md

This saves storage space on the token and will work if one device has games stored on a USB drive and another on the SD card. There's no downside to using it compared to an absolute path.

Some other examples:

_Arcade/Some Arcade Game.mra

_@Favorites/My Favorite Game.mgl

.zip files are also supported natively, same as they are in MiSTer itself. Just treat the .zip file as a folder name:

Genesis/@Genesis - 2022-05-18.zip/1 US - Q-Z/Some Game (USA, Europe).md

System Lookup

This is similar to a relative path, but the first "folder" will be treated as a reference to a system instead of a folder. Like this: <System ID>/<Game Path>.

Check the Systems documentation for a list of supported system IDs.

For example:

N64/1 US - A-M/Another Game (USA).z64

While this looks like a relative path, it will work on any device with the same system folder structure, even if the Nintendo 64 folder does not have the same name. Zaparoo will look up the system ID and find the game file based on that.

System ID aliases (listed in the Systems page as well) can also be used here.

For example, this will work:

TurboGrafx16/Another Game (USA).pce

Or this:

tgfx16/Another Game (USA).pce

Or even this:

PCEngine/Another Game (USA).pce

While this method is basically the same as a relative path right now, as Zaparoo develops, we will be adding more features to this System Lookup method so it's not necessary to use explicit paths. It will also be important going forward as more devices are supported with different file structures.

Special Cases

Some systems have special cases and extra support implemented for their launching capabilities.

ao486

If a .vhd file is launched via Zaparoo, and this .vhd file is sitting in its own folder with an .iso or .chd file, that .iso or .chd file will also be automatically mounted alongside the .vhd file.

AmigaVision (Amiga)

Launching games in the AmigaVision image on the Amiga core is supported via the games.txt files and demos.txt files located in the Amiga/listings folder on your SD card.

For example, to launch Beneath a Stell Sky in AmigaVision:

Amiga/listings/games.txt/Beneath a Steel Sky (OCS)[en]

The games.txt and demos.txt files contain a listing of all supported games and demos, generated by AmigaVision, and can be treated as a virtual folder for launching via Zaparoo. Other games can be launched using the same format of Amiga/listings/games.txt/<Game Name>.

Opening the games.txt and demos.txt files in a text editor will show the full list of supported games and demos.

NeoGeo

NeoGeo also supports launching .zip files and folders directly with Zaparoo, as is supported with the MiSTer core itself.

For example, a .zip file:

NeoGeo/mslug.zip

Or a folder:

NeoGeo/mslug2

Combining Commands

All commands and game/core launches can be combined on a single token if space permits using the || separator.

For example, to switch to MiSTer.ini number 3 and launch the SNES core:

**mister.ini:3||_Console/SNES

Or launch a game and notify an HTTP service:

_Console/SNES||**http.get:https://example.com

As many of these can be combined as you like.

Custom Commands

There are a set of special commands that can be written to tokens to perform dynamic actions. These are marked in a token by putting ** at the start of the stored text.

Launching Media

Generic Launch (launch)

This command works exactly the same as the basic game launch behavior. It's just a more explicit way of doing it.

For example:

**launch:/media/fat/games/Genesis/1 US - Q-Z/Some Game (USA, Europe).md

Launch a System (launch.system)

This command will launch a system, based on MiSTer Extensions own internal list of system IDs. This can be useful for "meta systems" such as Atari 2600 and WonderSwan Color which don't have their own core .rbf file.

For example:

**launch.system:Atari2600

**launch.system:WonderSwanColor

It also works for any other system if you prefer this method over the standard core .rbf file one.

Launch a Random Game (launch.random)

This command will launch a game at random for the given system. For example:

**launch.random:snes

This will launch a random SNES game each time you read the token.

System IDs can also be combined with the , separator. For example:

**launch.random:snes,nes

This will launch a random game from either the SNES or NES systems. You can also select all systems with **launch.random:all.

An absolute path to a folder will pick a random file from that folder and attempt to launch it:

**launch.random:/media/fat/_#Favorites

This is useful for folder full of .mgl file on MiSTer.

A random game can also be chosen using the launch.search syntax. Instead of picking and launching the first result, Zaparoo will pick a random one:

**launch.random:Genesis/*sonic*

Search for and Launch Game (launch.search)

This command will search for a game with the given query by filename and launch the first result. The syntax of the command is similar to the generic launch command, but with the addition of "globbing" to create a fuzzy search query. For example:

**launch.search:SNES/*mario*

Will search for all SNES games with the word "mario" in the filename and launch the first result. Narrow it down:

**launch.search:SNES/super mario*(*usa*

To launch the US version of Super Mario something.

Search queries are case insensitive.

HTTP Requests

Make an HTTP GET Request to a URL (http.get)

Perform an HTTP GET request to the specified URL. For example:

**launch.random:snes,nes

This is useful for triggering webhooks or other web services.

It can be combined with other commands using the || separator. For example:

**http.get:https://example.com||_Console/SNES

If your URL contains any of the following characters, you must URL encode them by replacing them with the following:

  • , with %2C
  • || with %7C%7C
  • ** with %2A%2A

Make an HTTP POST Request to a URL (http.post)

Perform an HTTP POST request to the specified URL. For example:

**http.post:https://example.com,application/json,{"key":"value"}

Or with Remote, to launch the Update All script:

**http.post:http://localhost:8182/api/scripts/launch/update_all.sh,application/json,

The command is in the format URL,Content-Type,Body.

If your URL contains any of the following characters, you must URL encode them by replacing them with the following:

  • , with %2C
  • || with %7C%7C
  • ** with %2A%2A

Virtual Input Devices

Press a Keyboard Key (input.keyboard)

Press a key or multiple keys on a virtual keyboard attached to the host. One key:

**input.keyboard:@

Multiple keys in sequence:

**input.keyboard:qWeRty{enter}{up}aaa

Special keys can be entered by with a key name surrounded by curly braces ({}) as shown above. If you want to enter an literal curly brace, type a backslash before it like \{ and \}. Backslashes can also be escaped (\\).

Possible special key names are: esc, backspace, tab, enter, lctrl, lshift, backslash, rshift, lalt, space, caps, num, scroll, f1-f12, home, up pgup, left, right, end, down, pgdn, ins, del, volup, voldn.

Press a Gamepad Button (input.gamepad)

Press a button or multiple buttons in sequence on a virtual gamepad attached to the host.

This works the same as the input.keyboard command but with the following name mappings:

  • ^, {up}: Dpad up
  • V, {down}: Dpad down
  • <, {left}: Dpad left
  • >, {right}: Dpad right
  • A, a: East button
  • B, b: South button
  • X, x: North button
  • Y, y: West button
  • {start}: Start
  • {select}: Select
  • {menu}: Menu (Xbox/PlayStation/etc. button)
  • L, l, {l1}: Left bumper
  • R, r, {r1}: Right bumper
  • {l2}: Left trigger
  • {r2}: Right trigger

For example:

**input.gamepad:^^VV<><>BA{start}{select}

Be aware that this gamepad likely needs to be mapped manually first to work, and that it will show to the game as an additional controller not imitate an existing connected controller.

Insert a Coin/Credit (input.coinp1/input.coinp2)

Insert a coin/credit for player 1 or 2. For example (to insert 1 coin for player 1):

**input.coinp1:1

This command presses the 5 and 6 key on the keyboard respectively, which is generally accepted as the coin insert keys in MiSTer arcade cores. If it doesn't work, try manually mapping the coin insert keys in the OSD.

It also supports inserting multiple coins at once. For example (to insert 3 coins for player 2):

**input.coinp2:3

MiSTer

These commands are only available on the MiSTer platform.

Change the Active MiSTer.ini File (mister.ini)

Loads the specified MiSTer.ini file and relaunches the menu core if open. Specify the .ini file with its index in the list shown in the MiSTer menu. Numbers 1 to 4.

For example:

**mister.ini:1

This switch will not persist after a reboot, same as loading it through the OSD.

Launch a Core RBF File (mister.core)

This command will launch a MiSTer core .rbf file directly. For example:

**mister.core:_Console/SNES

Or:

**mister.core:_Console/PSX_20220518

It uses the exact same format as the rbf tag in a .mgl file, where the ending of a filename can be omitted. The path is relative to the SD card.

Launch a Script (mister.script)

It's possible to launch a MiSTer script which already exists on the MiSTer:

**mister.script:update_all.sh

Zaparoo will close the currently running game back to the menu core if necessary, then launch the script on screen as if it were launched from the Scripts menu. The script must exist already in /media/fat/Scripts or it won't be run.

Arguments to the script are allowed, just type them after the filename as you would on a shell. Arguments are escaped for security.

Utility Functions

Run a System/Linux Command (shell)

This feature is intentionally disabled for security reasons when run straight from a token. You can still use it by enabling the allow_commands option in the Zaparoo config file.

This command will run a MiSTer Linux command directly. For example:

**shell:reboot

Delay Command Execution (delay)

This command will delay the execution of the next command by the specified number of milliseconds. For example:

**delay:500

Will delay the next command by 500ms (half a second). This is a blocking command and will delay the entire token read by the specified time.

It can be combined with other commands using the || separator. For example, to launch SNES, wait 10 seconds, then press F12:

_Console/SNES||**delay:10000||**input.key:88