Tuesday, November 13, 2012

How MAMEHub works part 1: What to sync

Hey guys,

One day, I might stop working on MAMEHub.  It's morbid to think about, but life things could come up, or I could get hit by a truck, or I could get sued for MAMEHub, who knows...

The point is the question isn't "if", it's "when".  There's a clock ticking and when it runs out, I will have to stop working on MAMEHub.  I have a policy of open-sourcing the code once it is stable, but having a bunch of source code is not enough.  People need to know how MAMEHub works so they can pick up the torch in case I can't work on it anymore.

So this is the first of a series of posts which should explain how CSMAME/CSMESS & MAMEHub work internally.  Please comment if you have any questions: I want to make sure the explanation is clear and coherent.

PART 1: What to sync


Part 1 covers figuring out what data to sync among clients.  These are core elements to sync:


  1. Snap data:  This includes everything that is stored on disk when one does a state save.  It typically contains all of the memory address space for all of the chips and anything in the chip registers and/or cache.  Note that if you have all of the inputs (mentioned below), you can start from the power-up time of the machine and replay everything exactly, so syncing snap data is not necessary, but it prevents new people who join the game from having to replay the entire machine history and is also necessary for correcting desyncs (desyncs will be mentioned in future post).
  2. NVRAM:  NVRAM stands for "Non-volatile Random Access Memory" and contains data that persists from one power cycle to another  (the term "power cycle" means the time from which the machine is powered on until it is powered down).  Examples include the battery in the super nintendo cartridge that saves games or the high scores and settings on many arcade machines.  When starting a machine for the first time, a copy of the NVRam is created and put in the nvram/ directory.
  3. Inputs:  These are a ordered list of nested tuples in the form (player, (time, inputs)).  I will cover how the inputs are assembled in another part.

There are some things that could/should be synced but aren't.  Among these are:

  1. Dip switches:  Right now dip switches are not synced so it is the responsibility of the players to set the same switches at the same time and ensure that they match, otherwise desyncs can occurs (desyncs will be explained in a later post).
  2. CHD Diffs:  CHD stands for "Compressed Hard Disk".  Despite the name, CHDs are also used to represent CDs or other large media.  Many modern arcade machines contain hard drives instead of storing data on NVRAM because it's cheaper, and this savings is significant given the amount of data in modern games.  The CHD format is basically a bit-for-bit representation of a hard disk.  Just like in NVRAM, the data on the hard disk can change and the changes must persist between power cycles.  Because the CHD files are so big, it doesn't make sense to make a copy of them when a machine starts up like NVRAM.  Instead, a DIFF file is created, which only contains the differences between the original CHD and the current CHD.  For example, if you have some credits saved on the machine, the # of credits will be in the DIFF file, but other stuff (e.g. the character art) will not be in the file.  At the moment, MAMEHub does not load DIFF files and assumes that CHDs are unchanged on startup.
In the next part, I discuss the initial sync process and peer to peer networks.

No comments: