Some emulators are powerful tools, and some are toys for novices. The toys need not conform to the laws laid forth in the following document, which are designed to ensure that those who need power are able to get it without trouble.
An emulator MUST NOT attempt to be both powerful tool and toy. An emulator MUST choose which of these it is, and EXIT this document if it chooses to be a toy.
This document wields capitalized imperative words more flippantly than a typical RFC, as it is endeavoring to formalize design principles in addition to operational principles. Emulator authors ought to exercise less creativity than they historically have in implementing certain core functions.
An emulator MUST implement a scripting system that supports the Lua language. This in order to allow automated testing as well as custom tools that works with the emulation state.
An emulator MUST execute deterministically and exactly reproducibly, down to the very cycle level, on every host system given the same emulator configuration. An emulator SHOULD try to execute identically when operating under different configurations, especially with respect to video and audio plugins and the like. Obviously many configurations will alter the behavior of the emulator and so to that end the emulator MUST write all pertinent information to the movie header. Additionally, the emulator MUST either change configuration or warn the user when loading a savestate with incompatible configurations.
In keeping with the principle of deterministic execution, an emulator MUST have a straightforward internal reset process which yields identically initialized variables and can be called repeatedly. This process MUST be separate from any one-shot emulator host features initialization. In other words, emulation state reset and host state initialization MUST NOT be mixed.
An emulator MUST support, at all times, flawlessly round-tripping savestates.
An emulator MUST use an easily edited and transfered configuration file. Unformatted text files are strongly recommended for this.
An emulator SHOULD obey the operating system filesystem layout by default, but MUST allow the user to override this. In particular the checked location of the configuration file MUST include the install directory of the emulator executable file.
Guidelines of Interest Mostly to TASers
An emulator MUST keep a frame counter, which is to increment at the beginning of each draw cycle (at the end of the vertical blanking period.) The emulator MUST refer to the first frame as frame 0, which is to begin before the execution of cycle 0.
An emulator MUST change its internal record of input state exactly once per frame, and this at the beginning of a new frame as defined above. As a contrary example, the emulator would not call through to the operating system to retrieve the current mouse cursor position whenever the game software requests it, but rather retrieve it once per frame and cache it for the duration of the frame.
When paused on a frame-by-frame basis, the emulator MUST pause before cycle 0 of the frame, at the moment when the new frame is taking effect. Game input given to the emulator host right now will take effect for the current frame upon resuming. The emulator MUST, when requested to display frame number, display the frame number which is about to take effect.
( a diagram would be helpful )
In order to combat routinely-created bugs in menus, an emulator SHOULD set up all of its menu state in one block of code at the time when the menu is created, analyzing the current emulator state and setting disabled and checkmark states accordingly. For instance, in Win32 this would be done with WM_ENTERMENULOOP.
( Regarding whether configuration gets saved all at once or wherever it gets changed, I am ambiguous. I see virtues to both ways. )
An emulator SHOULD NOT overanalyze which internal variables need to be written to the savestate. If you store too many you merely waste space; if you store too few you create subtle bugs.
An emulator MUST justify in the savestate code blocks the conspicuous absence of any internal emulation state variables; otherwise it is to be assumed that virtually every piece of internal emulator state should be written to the savestate exactly in the same order and format as it is stored in memory.
In aiding the above goals, an emulator MUST clearly separate internal emulator state from host variables used for operating the emulator software itself.
(need to work out some formalized terminology for this and create a definitions section)
User Interface Guidelines
While admittedly a matter of opinion, to bring order to the unruly thicket of default hotkeys, the following recommendations have been drafted:
An emulator MUST offer to display the following items to the user:
- The current frame number
- The input state for this frame
An emulator MUST have command-line arguments at least implementing the following:
- Load state file
- Play movie file
- Loading a given rom file
Additionally it SHOULD have commandline arguments for the following:
- Dumping a playing movie file to video