My favorites | Sign in
Project Home Downloads Wiki Issues Source
Search
for
MacroLuaDocumentation  
This document is also available in the download package.
Featured
Updated Feb 18, 2011 by dammi...@hotmail.com


Introduction

The purpose of this Lua script is to play back and record sequences of button presses in a compact format that is easily readable and editable. Some applications:

  • an alternative to using serialized rerecords for recording input, which can be easier with multiple players
  • a functional, parseable markup that doubles as a shorthand transcript notation, good for fighting game combo videos
  • a converter that can change an input sequence from a cryptic format such as FBM to a human readable one for further editing
  • a converter that can change an input sequence from one emulator to another

MacroLua is portable to any emulator equipped with the core EmuLua functions. It can still work in a limited capacity if some of the functions are missing.


A word on MAME-rr

The current version of MAME-rr (0139-test2) has some oddities with the savestate system and the first few scripted frames get merged together. To avoid problems:

  • Start playing scripts with the emulator in an unpaused state. Starting from pause will be off by one frame.
  • Leave at least a few blank frames at the start.
  • If scripting a save, leave a few blank frames after the last input.
  • Don't try to load states if using recording mode. Recording is not bulletproof.

How to use macros

Download and set up one of the supported emulators. Choose the latest available version.

Extract the macro archive contents into the emulator's folder. Open macro-options.lua with a text editor and ensure that the macrofile to be played and the path settings are correct. The default path looks for the macros in a folder called ./macro.

Run the emulator and open the game. Find Lua Scripting in the menus (Ctrl+L in MAME-rr) and open a script window. Browse for macro.lua and run it. If there's a gamekey definition module available for your game, it is identified in the output console. In the case of arcade emus, the input-display.lua script is run alongside the macro script.

How to play back

Get to the desired point in the game and press the start key (semicolon, or whatever is bound to Lua hotkey 1) to start playback. The macro specified will be analyzed, and warnings appear in the output console if it is misformatted. The scripted sequence will proceed as the game runs normally or in frame advance.

You may replay the macro repeatedly. You may cut the playback short by pressing the start key again before playback is complete. You may also edit the macro file and play the new macro without reloading the script.

How to record

Get to the desired point in the game and press the record key (quote, or Lua hotkey 2) to start recording. Any keys input by the player(s), by keypress recordings such as FBM, or even by a playing macro will be recorded. You can use frame advance for more precision. Savestate operations and analog controls are not recorded. Pressing the record key again stops and writes the recording to a .mis file named after the date and time. If multiple players were recorded, the macro is output in asynchronous (bracket) format.

Key bindings

If the emulator supports input.registerhotkey(), the keys to start and stop macros are Lua hotkeys 1 and 2 rather than semicolon and quote. These keys can be bound in the emulator's hotkey configuration.

Savestates

Some emulators allow the progress of any macros being played or recorded to be saved alongside the savestate. Loading this savestate also restores the progress and the playing/recording status. If this is not supported, loading a savestate during a macro will cause a desync.

Even if those functions aren't available, savestate operations may always be written into the script, and scripts should start with a savestate to ensure consistent playback.


How to read and write macros

You may produce macros by recording them or by writing them out according to the format below.

In the following commands, n represents a number and k represents a key (direction, button or switch) defined by the game's module.

kInput the gamekey k. The key is pressed for the current frame only and then released.
_kHold the gamekey k. The key is pressed for the current frame and any subsequent frames until released.
^kRelease the gamekey k, if held.
*Release all held keys.
k[n]Set the analog control k to the (decimal) value n for one frame.
k[-nh]You may use a minus sign to set the an analog to a negative number, and h to signify a hexadecimal number.
_k[n]Hold an analog control at the value n. You may change the held value by entering another hold. There's no need to release first.
^k[n]When releasing an analog control, it makes no difference if there is a ^ or not. Either way the value is set for one frame and then the control is released. Use * or a value of 0 for immediate release.
FInput R for player 1 or odd numbered players, or L for player 2 or even numbered players.
BInput L for player 1 or odd numbered players, or R for player 2 or even numbered players.
F and B only get substituted if the module is using L and R and not already using F or B.
.Advance one frame.
WnAdvance (wait) n frames.
Wn?Incremental wait mode: If a wait command is followed by a ?, the macro will loop back to the beginning when it reaches the end and repeat indefinitely, both the savestates and the inputs. Stop by pressing the playback key again.

After each iteration, the value of n increases by one, and the value is displayed on screen. This is a more efficient way of finding the optimal wait period for a setup. There can be no more than one incremental wait in a script. If incremental wait is used, standard loop mode is disabled.
+Select player 1.
-Select the next player.
<Open a bracketed section and switch control to player 1.
/Switch to the next player in a bracketed section.
>Close a bracketed section.
$nSave the current state to slot n.
This can save checkpoints in a long sequence of commands.
&nLoad savestate slot n. This is useful to put in the first frame.
()nRepeat the commands enclosed in the parentheses n times. Loops can be nested.
#textA comment. The rest of the line after the symbol is ignored by the parser.
Comments should explain the setup and goal of the macro.
!End the macro. Any content after the end is ignored by the parser, and can be used as comments.
Don't forget to advance at least one frame after the last input and before the end.
???If a script has three consecutive ? symbols in an uncommented area, MacroLua converts it to the expanded one-line-per-frame format. Analog control values are given as hexadecimal numbers. The conversion occurs instead of playback and is activated by the playback key. The result is saved as a text file. This feature can help in analyzing and debugging scripts.

Macros are case insensitive. Commas, whitespaces, tabs and newlines can be used for spacing and legibility, but are ignored by the script. The exception is that some separation is required between multiplier or index numbers (such as after a W) and numerical key presses.

Synchronous multi-player control with + -

  • Commands are applied only to the selected player.
  • Player 1 is selected by default.
  • The + and - symbols are used to switch between players.
  • Time advancement applies to all players.
  • Nonselected players can give input with their held keys.
  • To modify the input of multiple players on the same frame, switch between them before advancing frames.

Asynchronous multi-player control with < / >

  • Commands are applied only to the selected player.
  • Player 1 is selected when the brackets are opened.
  • Control is switched to the next player after each /.
  • Time advancement applies only to the selected player.
  • When the brackets are closed, time is advanced to the point of the player with the most frames, wait frames are added to the others to make up the difference, all player inputs are multiplexed, and control returns to player 1.
  • The + - symbols are ignored inside brackets.

Savestates

Save and load operations are performed one frame before the game inputs at the same position. For example, a state operation placed between the second and third dots is done after the second frame advance, while the game inputs there are done after the third. This behavior allows operations to be scripted on the zeroth frame of the macro, resulting in a movie that effectively starts from savestate.

Each emulator has its own limit on savestate indexes.


Control modules

The game inputs and the symbols used to activate them depend on game system. MacroLua selects the symbol-input mapping based on what emulator is running it, and in the case of arcade, based on the game being run. The traditional format is U,D,L,R for up, down, left and right, and numbers counting up from 1 for the buttons. Symbols should be a single character for digital controls, but analog symbols can have multiple characters.

Avoid using the reserved characters in symbols: . W w _ ^ * + - < / > ( ) [ ] $ & # ! ?

The available sets are written in macro-modules.lua, and more can be added. Ask for help if needed. The non-arcade systems have a single keyset for all games, so the format only needs to be defined once for each console. However, there are many undefined arcade profiles. MacroLua tries to autogenerate an arcade module if none is available by observing what keys are present in the game. This should work well with games that use an ordinary joystick and numbered buttons.


Configuration options

The macro-options.lua file contains the user's settings. This file can be edited with any text editor. To update settings, restart the Lua script.

The file, path and key options must be enclosed in quotes.
The hotkey options are ignored if the emulator supports Lua hotkeys.
playbackfileThis is the filename of the script to be played.
pathThis is the path where the script file is found and where recordings will be placed. The path may be either relative to macro.lua or absolute. Use either double forward slashes (.\\path\\) or single backslashes (./path/).
playkeyPress to start playing the specified script or to cancel an already playing script.
recordkeyPress to start recording input to a new script and to finish a recording in progress.
togglepausekeyWhen a script finishes, the game can be paused automatically. Press this to turn autopause on or off. There is a pause between each repetition in standard loop mode or incremental wait mode.
toggleloopkeyIf loop mode is active, the macro will loop back to the beginning when it reaches the end and repeat indefinitely, both the savestates and the inputs. Stop by pressing the playback key again.

This is useful if you want to make successive changes to a script without having to enter the play command each time. If the emulator supports lua+user input, this can also be used for practicing against a scripted attack from the other player.

If incremental wait mode is active, this key instead cycles between increasing, decreasing, or preserving the delay.
After recording player input, the results are written to file. The following three options affect the style of the output:
longwaitIdle frames are collapsed into Wn phrases as a shorthand. This option specifies the minimum number of idle frames to trigger this. Set it to 0 to never use Wn phrases.
longpressWhen an input is active for many consecutive frames, it is abbreviated as a _k at the beginning and a corresponding ^k at the end instead of writing k every frame. This option specifies the minimum number of held frames to trigger this. Set it to 0 to never use _k ^k phrases.
longlineEach player's input can be broken up into multiple lines. This option specifies the minimum number of characters to trigger a linebreak. Set it to 0 to not break up lines.
framemameSet to true only if running a script that was made for frameMAME, so that the parser can ignore the audio commands. Otherwise leave as false. This only applies to FBA-rr and MAME-rr.

If the emulator doesn't use Lua hotkeys, you must define hotkeys manually. They must be selected from the following list. Key names are case sensitive.

shift, control, alt, capslock, numlock, scrolllock, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24, backspace, tab, enter, pause, escape, space, pageup, pagedown, end, home, insert, delete, left, up, right, down, numpad0, numpad1, numpad2, numpad3, numpad4, numpad5, numpad6, numpad7, numpad8, numpad9, numpad*, numpad+, numpad-, numpad., numpad/, tilde, plus, minus, leftbracket, rightbracket, semicolon, quote, comma, period, slash, backslash


Special playback modes

Here is a review of MacroLua's special modes:

mode activated by function
text dump mode??? written in the scriptOutput the script to an expanded frame-by-frame form that may be easier to read.
(No playback.)
incremental wait modeWn? written in the scriptLoop and automatically adjust the wait period after each iteration.
(Macro file is not reread between loops.)
standard loop modepress the toggle loop keyLoop and automatically reread the macro file after each iteration.


How to mute the background music in arcade games

You may want to record videos with the sound effects but without the music. The reliable method to disable music is with a cheat code: The memory addresses that control music are forced to hold values that prevent it from playing.

For FBA-rr, find the code that works for your game in the ./FBA examples/mutecodes.txt file provided. Copy the code into an .ini file that matches the rom's short name and put it in FBA's cheat folder (e.g. ./support/cheats/sfa3.ini). You may augment this file with other codes as well. Then run the rom (restart if already running) and find Enable Cheats in the Misc menu. If the .ini is properly formatted, the option is available. Click the music entry and select the disable option from the dropbox.

The available FBA mute codes have been converted to MAME xml format and are found in the official cheat code pack. Place cheat.zip in MAME-rr's folder to make the codes available. Access the cheats from the in-game menu in MAME.

Not all games have known mute codes. You can request more at Pugsy's site.


Lua feature availability in each emulator

emulatorversion testedemu aliashotkey while pausedlua+user inputbulletproof savestatesadapt to ROMsanalog scripting
MAME-rr0139-test2mame××
FBA-rr0.0.5afba
PCSX-rr0.1.3bpcsx×××
psxjin2.0 svn619psxjin××××
Gens-rrsvn296gens×n/a
snes9x-rr1.43 svn146snes9x××n/a
1.51 svn1471snes9x××n/a
1.52 r1852××××n/a
VBA-rrsvn225vba×××n/a
23.4a3vba×××n/a
FCEUX2.1.3FCEU×n/a
PCEjinSVN1774××n/a
DeSmuMe0.9.6not yet tested
mednafen-rr1.1use TranScripter
yabause-rrsvn2541use TranScripter
mupen64-rrv8does not support Lua

  • [1] snes9x 1.51 svn147 only accepts Lua input from within a while true do loop, so playback won't work.
  • [2] snes9x 1.52 r185 lacks an emu alias, savestate.save, savestate.load and the entire joypad library.
  • [3] VBA versions after svn225 only accept Lua input from within a while true do loop and won't work.
  • [4] PCEjin may only need an emu alias to work.

emu aliasMacroLua identifies the emulator and control scheme by the name of this table of functions.
hotkey while pausedIf input.registerhotkey() is available, the user can start and stop recording during pause. The fallback is input.get(), which has the same function but cannot be done while paused.

However, it's possible to use input.get() while paused in FBA, PCSX and FCEUX, due to a defect in the Lua implementation. In these cases the hotkeys will activate even if the emulator is not in focus.
lua+user inputThe emulator may take input from both a Lua script and the user simultaneously if joypad.set() allows it.
bulletproof savestatesThe user may load savestates while playing or recording without losing progress if savestate.registersave() and savestate.registerload() are available. MAME-rr has other problems with savestates.

This feature has not been well tested.
adapt to ROMsMacroLua can name recordings and reset the control scheme based on the loaded game if emu.registerstart() and a function that returns the name of the game are present.
analog scriptingIf the emulator's system has analog controls and the emu handles them properly with joypad.set(), MacroLua can script analog inputs.

Comment by xeno_f...@hotmail.com, Mar 26, 2011

hey//


Sign in to add a comment
Powered by Google Project Hosting