Fork me on GitHub

Lua in MAME: Time for an Overhaul

27 Dec 2020

If you’ve been following along during our extended November/December development cycle for MAME 0.227, you might have noticed that we’ve migrated MAME to C++17. As part of this, we’ve upgraded the C++/Lua interface library to sol3. This has necessitated a shake-up of the Lua interface code. We’ve taken this opportunity to re-think some of MAME’s Lua interfaces.

Some of the changes are not backwards-compatible and will require scripts to be migrated. However, we believe these changes make our Lua interface more robust and efficient as well as making the Lua syntax more idiomatic. We’ve exposed more functionality, too. Most of the breaking changes fall into a few categories:

  • Better aligning the Lua interface with MAME’s architecture.
  • Using container wrappers rather than building Lua tables.
  • Replacing simple getter methods with read-only properties.
  • Moving the Lua API reference to our documentation web site.

In particular, using container wrappers makes a lot of properties far more efficient because the collection no longer needs to be iterated and copied into a Lua table for every access. We’ll go through most of the breaking changes and touch on some of the new functionality here. There will still be occasional changes to the Lua APIs going forward, but we’re not anticipating another major upheaval like this soon.

Documentation changes

Previously, most of the Lua classes had brief method and property descriptions in the source code. Most of this has been moved to a page on our documentation web site and expanded on. It’s easier to find the reference documentation here, the format is better-suited to detailed descriptions, and cross-references can be linked properly.

Like the rest of our documentation, this is a work in progress, and will be built upon.

Core classes

  • The MAME machine manager machine, ui, options and plugins methods have been replaced with properties. The plugin descriptions are now a container of objects rather than a table of tables.
  • The running machine system, parameters, video, sound, outputs, memory, ioport, input, uiinput, render, debugger and options methods have been replaced with properties.
  • The video manager frame_update method no longer takes an argument, it is assumed to be an out-of-band update. The speed_factor, speed_percent, effective_frameskip, skip_this_frame and is_recording methods have been replaced with properties. The size and pixels methods have been renamed to snapshot_size and snapshot_pixels, respectively. New snapshot_native and snapshot_target properties have been added for better control over snapshots.
  • The sound manager ui_mute, debugger_mute and system_mute methods have been replaced with properties. The samples method has been renamed to get_samples. New muted and recording properties have been added.
  • The MAME UI manager options, get_line_height and is_menu_active methods have been replaced with properties called options, line_height and menu_active, respectively.
  • The system driver default_layout property has been removed as it was never possible to use the object from Lua.


  • The tables of devices, screens and image devices have been replaced with wrappers for MAME’s device enumerators. These are far more efficient to create, can be created for parts of the device tree, are more flexible with tags, and iterate in consistent depth-first creation order. Image devices are now indexed by tag, which is more stable than the instance name when slot options are changed.
  • Device name, shortname, tag, owner and debug methods have been replaced with properties. Additional subtag, siblingtag, memshare, membank, memregion, ioport, subdevice, siblingdevice and parameter methods have been added for working with relative tags. Additional basetag, configured and started properties have been added.
  • Screen devices now expose all device methods and properties. The width, height, refresh, refresh_attoseconds, frame_number, xscale and yscale methods have been replaced with properties. The type method has been replaced with a property called screen_type to avoid ambiguity if the device type is exposed as an object in the future. The screen’s render container is now exposed as a property. Additional properties have been added to give current timing parameters.
  • The order of the last two parameters to the screen device draw_box method have been reversed, to make it consistent with the draw_text method and to allow the fill colour to be omitted while supplying the line colour. The flip flags returned by the orientation method have changed definition – they are now set if the screen image is flipped in addition to the rotation.
  • The image device interface exists, filename, software_list_name, image_type_name, and crc methods have been replaced with properties. The longname, manufacturer and year methods have been replaced with properties called software_longname, software_publisher and software_year to reduce potential confusion. Additional formatlist, readonly and loaded_through_softlist properties have been added, providing access to the supported image formats and additional information about the mounted image.
  • Cassette image devices and slot devices are now exposed to Lua scripts.

Memory system

  • The address space read_log_* and write_log_* methods have been renamed to readv_* and writev_* (“v” is a mnemonic for “virtual address”).
  • Address maps are now exposed as objects with a few properties that apply to the map as a whole. As a result, you now need to use to access an address space’s configured map entries.
  • Address map entries are now objects rather than tables, and the properties have changed to expose more detail. The offset and endoff properties have been replaced with address_start and address_end, and the address space’s mask is no longer applied to the values. Handler data is also exposed as objects, so the readtype and writetype properties have been replaced with read.handlertype and write.handlertype, respectively.
  • Memory shares and regions have had tag, length, endianness, bitwidth and bytewidth properties added.
  • Memory banks now have tag and entry properties, allowing Lua scripts to get or set the active bank number.
  • The memory manager’s shares, banks and regions properties now yield container wrappers rather than tables.

Input system

  • The I/O port manager’s natkeyboard method has been replaced with a property, and its ports property now yields a container wrapper rather than a table. New type_pressed, type_name, token_to_input_type and input_type_to_token methods have been added for working with general inputs.
  • The I/O port manager’s type_seq method now takes a sequence type string argument rather than an integer. This makes it consistent with other methods that take a sequence type argument.
  • The natural keyboard manager has several additional methods and properties. In particular, it’s now possible to enable or disable keyboard and keypad devices, mirroring options in the keyboard mode menu.
  • I/O port tag , active and live methods have been replaced with properties.
  • Methods used to poll for input sequences have been removed from the input manager class. Instead, you should use the methods to create a poller object with the desired intention and use that to poll for input codes or sequences.
  • The input device class enabled and multi properties have been made read-only. These properties should only be set by OSD input modules, based on capabilities and configuration.
  • The input device item code method has been replaced with a property.

Render system

  • Brand new layout scripting model with enhanced capabilities. Many layout objects are now exposed to layout scripts. Basic documentation with examples for the event-based model is available.
  • Render bounds and colour objects are no longer returned as multiple floating-point numbers on the stack and can be instantiated using emu.render_bounds() and emu.render_color(), respectively.
  • The render target width, height, pixel_aspect, hidder and is_ui_target methods have been replaced with properties. The view_name method has been replaced with a property view_names that yields a container wrapper. The view and zoom properties have been renamed to view_index and zoom_to_screen, respectively, for clarity.
  • The render target view_bounds method has been removed. The view object is exposed using the new current_view property. The bounds can be obtained using target.current_view.bounds (note that this now yields a render bounds object).
  • The render target index property is now one-based, in order to work better with Lua containers.
  • The render container orientation, xscale, yscale, xoffset and yoffset properties can be written from Lua. An additional user_settings property allows other image adjustment settings to be read or written.
  • The render container for a screen device is now accessible as a property. In combination with enhancements to the render container interface, this allows Lua scripts to control many image adjustments provided by UI sliders.
  • The render manager max_update_rate, ui_target and ui_container methods have been replaced with properties. The targets property now yields a container wrapper with one-based indices rather than a table.


  • The device debugger interface has additional bpenable, bpdisable, wpenable and wpdisable methods for enabling and disabling breakpoints and watchpoints.
  • The device debugger interface methods for clearing breakpoints and watchpoints have been renamed to bpclear and wpclear to match the debugger commands.
  • Breakpoints and watchpoints are now objects rather than tables.