ACBLscore Game Files Decoded

by Matthew Kidd
Original: September 30, 2013
Last Revised: October 30, 2014

As far as I know the internal format of the ACBLscore game files has never been published. The information presented below is the result of a few days of reverse engineering, most of it spent staring at a hex editor display much like the screenshot below. This documentation is not complete but it is quite detailed and should be a good start for anyone else. I update it from time to time but an exhaustive reverse engineering would be very time consuming. The effort also seemed pointless because ACBLscore+, the long awaited successor to ACBLscore, was due in perhaps a year. But the ACBL discontinued ACBLscore+ development in July 2014 with little explanation, stating that ACBLscore would be tweaked to meet some of the needs that ACBLscore+ was to address. This continuance of ACBLscore makes a documentation of its internal file format more relevant.

Hex editor view of an ACBLscore game file

Example of a Pair Entry in a Pair Entry Table in an ACBLscore game file. Entry length is 0x192 = 402 bytes (red box). Pair percentage is 0x1505 = 5381 ⇒ 53.81% (purple box). Last name of first player in partnership is "Angione”, seven ASCII characters (green box).

Why even bother at all? The initial motivation was to compute the field strength and display each player’s masterpoint total in ACBLmerge. Both of these features require the player numbers in order to lookup each player’s current masterpoint total. ACBLscore used to print the player numbers on the text and HTML reports but a couple of years ago ACBLscore stopped including them in most cases, perhaps to make the report format more compact. Since the player numbers had to be in the ACBLscore game files, I went looking for them. It was a fairly easy to search the entire game file for strings that looked like player numbers and then find the corresponding player names which were always at a fixed offset from the player numbers. This simplistic methods works pretty well though it can lead to incorrect results if two players have the same first and last names in a single game file, a rare event that nonetheless has happened at regionals where many events are contained in a single game file. A better understanding of the internal format would allow each player number to be associated with a section, pair number, and direction (N-S or E-W).

The second reason is to perform statistical analyses on players and partnerships across many sessions, typically in a regular game, say the La Jolla unit game or Thursday evening at the Soledad Club. For the Social Network graphs, it was enough to pull additional pair data using the same technique that ACBLmerge uses. But the Payoff Matrix requires more detail, specifically results from every board. It is possible to do these analyses by parsing the text and HTML reports generated by ACBLscore. However, there are many little quirks involved in the text parsing. And different clubs choose to generate different ACBLscore reports. Worse, I don’t know any way to systematically generate a particular style of report from the ACBLscore games files, i.e. from the command line; it is quite tedious to manually open several hundred game files in ACBLscore and create the desired report for each one. Directly reading the binary game files solves both these problems.

Third, some information in the game files is not readily obtainable elsewhere. For example, an analysis of whether some pairs routinely choke on the last round requires knowing which round each pair played each board. For a Mitchell movement this is straightforward to calculate. For a Howell movement it is necessary to know the exact movement. But when parsing game files directly, the round information is available from game file itself.

Finally, directly parsing the binary format is really fast. For example, my Payoff Matrix Perl program scans through 600 games files in about four seconds on a Windows 7 era laptop. It wouldn’t be intolerably slow to scan the text based reports but performance is always a win. Users don’t like to wait, especially when the user is also the developer.

Acknowledgments

Game Scan logo

Don Greenwood sent me his GameScan C# code for parsing ACBLscore games files in early January 2014. At the start of March I was finally able to integrate my reverse engineering with his reverse engineering to produce the most complete and accurate documentation to date. In the middle of September he sent me updated code which I have used to further refine the documentation.

Ping Hu unraveled some of the remaining mysteries of the Section Details structure in late September, including the initial seating arrangement.

Data Types, Data Layout, and Notation

It is worth making several general observations which will simplify the rest of the documentation.

Let uint and int designate unsigned and signed integers respectively. Let uint8, uint16, and uint32 designate a 1, 2, and 4 byte unsigned integers respectively where int8, int16, and int32 are the corresponding signed types. Let pointer designate a 4-byte integer file pointer, a uint32 that happens to be a pointer; zero indicates a NULL pointer. Let boolean designate a uint8 meant to be interpreted as true (non-zero) or false (zero).

There can be some ambiguity about the size of a field. Often a zero always seems to appear after what might be reasonably be stored in a uint8, leading to the assumption that it is really a uint16. Similarly, some conceivable uint16 values are always followed by a pair of zeros, leading to the conclusion that the data is interpreted as a uint32 value. This documentation uses the most reasonable interpretation. Please report assumptions that are falsified.

Most floating point values have exactly two digits after the decimal point. For example, the percentage 53.81% is stored as 5381 which has the hexadecimal representation of 0x1505 and hence the byte order 0x05 0x15 since data is stored little-endian. Both matchpoint and masterpoint quantities are handled in the same manner. Let the intfloat(n) designate a fixed decimal value with n digits after the decimal point. I have seen no evidence of standard IEEE-754 floating point values in the ACBLscore game files. Most infloat values are intfloat(2) data types have been observed but intfloat(4) is seen for the masterpoint M-factor for each strat and intfloat(1) is seen elsewhere. Some intfloat(2) values appear to occupy 2 bytes which others most likely occupy four bytes. Some intfloat values are signed.

Let string(n) designate a string containing up to n ASCII characters. These fields occupy n+1 bytes because the first byte indicates the actual length of string. The unused part of the string field is almost always zero padded but this is not completely reliable and even if it were, relying on a terminating NUL will fail whenever the string length is as long as longest string allowed. Use the first byte to determine the string length. Let char(n) designate an array of n bytes intended to be interpreted as characters, e.g. ‘A’ without nul termination. In practice only char(1) has been relevant.

Let datetime designate a uint32 which represents a date and time after Jan 1, 1980 decodable as shown in the table below, where date = datetime >> 16 (high bytes) and time = datetime & 0xFFFF (low bytes).

Field Formula
Year (date >> 9) + 1980
Month (1-12) (date >> 5) & 0x0F
Day (1-31) date & 0x0F
Hour (0-23) time >> 11
Minute (0-59) (time >> 5) & 0x3F
Second (0-59) (time << 1) & 0x1F

Let struct mean a C style structure where members are laid out at fixed offsets from the start of the structure. Let table mean a structure whose primary purpose is to contain many entries (records) of another structure. Tables usually consist of a table header followed by multiple table entries. Usually the table entries start immediately after the table header and are laid out without gaps. However, it is unsafe to rely on this if the table has a corresponding index table. Use the index table to find the starting location of each entry in the table.

None of the structure or table names described here are official names. This is strictly a reverse engineering effort.

The word “flag” is used to mean that a value should be interpreted as a Boolean. Typically a uint8 or uint16 is interpreted as such.

All relative offsets shown in blue in the charts below are in hexadecimal, even though they are not prefixed with 0x. All other values should be assumed to be decimal values unless prefixed by 0x.

Block Layout

An ACBLscore game file consists of a set of blocks where the first two bytes (int16) give the size of the data in the block. The Master Table and the Pair, Team, Events Details, and Section Details structures as well as the Pair Index, Team Index, and Board Results Index tables are all examples of data which fully occupy a block. Other structures presented below are never allocated separately in their own block but instead are constituents of one or more block allocated objects. For example the Player Structure appears twice in the Pair Structure and six times in the Team Structure. The Masterpoint Award and Ranking structures appear in multiple places.

Free blocks are designated by a negative size and include a pointer to the next free block as shown below such that the free blocks form a linked list. The Master Table includes a pointer to the first free block.

Free Block Structure
Offset Type Description
0000 int16 Negative size of the remainder of the free block.
Example: 0xa6ff = -90 → 90 bytes of free space follow
0002 pointer Pointer to next free block

Block allocation in ACBLscore is closer to memory allocation than disk allocation because there is no minimum unit of allocation corresponding a physical object (i.e. a 4096 byte allocation corresponding to eight old size 512 bytes sectors or one modern 4096 byte sector). Deleted structures are presumably turned into free blocks, coalesced with adjacent free blocks into a larger free block if possible. When a new structure is allocated, the free block list is traversed until a large enough free block is found whereupon it is converted to an allocated block and a smaller free block. If no free blocks are available, the file size is extended to accommodate a new block at the end. Unlike similar block allocated formats such as the JPEG image format, blocks are not necessarily consecutive. Some file bytes do not belong to either an allocated or free block. This means it is necessary to follow pointers to find all the blocks rather than simply traverse the file linearly.

Freed blocks are dirty, i.e. the block is not overwritten with zeros beyond the next block pointer when it is freed. The particular behavior of ACBLscore makes it common for freed blocks to look like a Pair Index Table.

Entity Relationships

ACBLscore Entity Diagram Click on image for an enlarged view in Scalable Vector Graphics (SVG) format.

The diagram above shows the relationship between the entities documented below. Blue boxes indicate block allocated entities. Black arrows represent pointers. These always point to block allocated entities. Yellow boxes represent entities which are constituents of one or more block allocated entities. Dashed blue arrows originate from entities that contain the constituent entity that the arrow ends on. Numbers along an arrow represent the number of pointers or the number of times the constituent entity is contained in the parent entity.

Some entities are grouped for simplicity in the diagram. In some cases it may make sense to consolidate these entities into a single entity in the documentation. For example, the Individual, Pair, and Team Structures appear to have a common start which is then followed by one, two, or six Player Structures respectively. Don Greenwood’s GameScan program consolidates these as a single Entry Structure (as in tournament entry). The Individual, Pair, and Team Match Table could be consolidated but they are small and the consolidation would likely make the documentation harder to understand. Likewise, the Board2 and Board4 Structures, for pair and individual events respectively, could also be consolidated but only at similar cost.

The inclusion of the Masterpoint Award Structure in both the Individual/Pair/Team Structures and the Player Structure may seem odd. But it really works this way. For team games this makes sense because up to six players are allowed on a team and the individual players can end up with different awards depending on who is playing when. For example, to qualify for the main awards, a player must play at least 50% of the time but could qualify for a match award simply by playing for the duration of a match. It is not clear if the two players in a pair can end up with different masterpoint awards. The individual case is clearly silly, no doubt a side effect of implementing pair and team games first.

Events and Sections

Each ACBLscore game file contains one or more events. Examples of events are Open Pairs, 0-750 Pairs, Swiss Teams, Knockout Teams, etc. Each event contains one or more sections. Sections are designated by letter designations, A-Z or AA-ZZ. In this documentation, a section refers to both the N-S and E-W pairs, i.e. both directions. The use of section in ACBL documentation is inconsistent. Sometimes it has the meaning above; other times it means only one direction, e.g. when an section masterpoint award is computed for the each direction of a lettered section in a Mitchell movement.

Master Table and Section Summary Structure

An ACBLscore game file begins with the Master Table. Therefore in this case only, the relative file offsets are identical to the absolute file offsets.

Master Table
Offset Type Description
0000 int16 Length of rest of table (seems to always be 0x0a12 = 2578 bytes)
0002 string(3) ‘AC3’ string
0006 uint32 Length of game file (in bytes)
000a pointer Pointer to first free block (often NULL)
000e pointer Pointer to Instant Matchpoint Table (usually NULL)
0012 pointer Pointer to 1st Event Details Structure
0016 pointer Pointer to 2nd Event Details Structure (if at least two events; otherwise null). 50 event pointers are permitted.
00da uint8 Event Type for 1st Event: 0 → Pairs, 1 → Teams, 2 → Individual, 3 → Home Style pairs, 4 → Board-A-Match Teams, 5 → Series winner (a zero-based offset for the “Select type of game” dialog in ACBLscore).
00db uint8 Event Type for 2nd Event and so on (up to 50 events)
010c uint8 Event Scoring for 1st Event. For Pairs events the options are 0 → Matchpoints, 1 → IMPs with computed datum, 2 → Average IMPs, 3 → Total IMPs, 4 → Instant Matchpoints, 5 → Board-a-Match Matchpoints, 13 → IMPs with predetermined datum, 14 → Double Matchpoints (European), 15 → Total Points. The first few values are a zero-based offset of the “Select scoring method” dialog in ACBLscore, reached via F9 → 9. Change scoring method. For Teams events the options are 6 → Win/Loss, 7 → Victory Points, 8 → Knockout, 9 → ZIP Knockout, 16 → Board-a-Match Matchpoints, 18 → Compact KO. 10 → Series Winners.
010d uint8 Event Scoring for 2nd Event and so on (up to 50 events)
013e struct 1st Section Summary Structure (22 bytes)
0160 struct 2nd Section Summary Structure (if at least two sections; otherwise zero filled). 100 Section Structures are permitted.
09d6 pointer Pointer to Memo Structure (usually 0 → No Memo). See section 3.2.34 of the ACBLscore Manual (MEMO command). Applies to all events and hence all sections.
09da 1 mystery byte
09db intfloat(2) ACBLscore version
09dd datetime Game file creation timestamp
09e1 intfloat(2) Earliest version of ACBLscore that can read this game file format?
09e3 pointer Pointer to Note Structure (usually 0 → No Note)
09e7 45 mystery bytes
0a13 uint8 1 → results imported from Bridgemate devices

The ‘AC3’ string seems like a reliable way to test whether a file is an ACBLscore game file, i.e. the bytes of the ‘AC3’ string are good magic bytes. The Master Table length can probably also be used as part of the magic bytes because the limits of 50 event and 100 sections are hard coded into ACBLscore according to the ACBLscore manual.

Section Summary Structure
Offset Type Description
0000 uint8 Event number that section belongs to. Event numbering starts at 1. Zero if section structure is not used.
0001 string(2) Section designation. Examples: ‘A’, ‘B’, or ‘TT’
0004 pointer Pointer to Section Details Structure
0008 pointer Pointer to Board Results Index Table. NULL for team events.
000c uint16 Total matchpoint score for a 100% game (pair or individual events only)
000e uint8 Scoring Status bit field. 1 → Scored, 2 → Scores posted, 4 → Pending late play(s).
000f uint8 Previous section when sections are scored together within an event.
0 → first section in group (no previous section).
0010 uint8 Next section when sections are scored together within an event.
0 → last section in group (no next section).
0011 uint8 Previous section when sections are ranked together within an event.
0 → first section in group (no previous section).
0012 uint8 Next section when sections are ranked together within an event.
0 → last section in group (no next section).
0013 uint8 Number of rounds entered so far
0014 uint8 Number of rounds total
0015 uint8 Bit field of flags. 1 → Has Club Number, 2 → DBADD done (see Section 3.2.13 of ACBLscore Manual). 4 → Changes since last DBADD.

Section and Event numbering begin at 1. The Event number associated with each section can be used to determine which sections belong to a specific event. But this is not the whole story. Within an event, sections can be partitioned into groups where the sections in each group are scored together. Sections in each group are said to be combined with each other in ACBLscore parlance. See section 3.2.9.2 of the ACBLscore Manual (CFIG2 command). Scored together means the matchpointing is performed across all combined sections. For example if a board is played nine times in both section A and B, the matchpoint top will be 8 if the sections are scored separately and 17 if the sections are combined for scoring. When sections are scored together (combined), all pairs from each direction (N-S or E-W) are ranked for the overall awards. Within a group of combined sections, sections may be grouped again for section award rankings. For example if sections A and B are combined and also ranked together, the section awards will be based on all N-S pairs and all E-W. If they are not ranked together, their will be separate section awards for the N-S pairs in A, N-S pairs in B, the E-W pairs in A, and the E-W pairs in B. Ranking sections together increases the section award for first place but has little impact on the overall masterpoints awarded. Gold Rush pair events are often ranked separately in each section because only the top section rank gets gold points and a little gold for the top pair in each section is deemed more desirable than more gold for the single pair in these events that have become the ACBL equivalent of a diploma mill.

The partitioning of sections for scoring and ranking is handled by what is effectively a pair of forward and backward linked lists where 0 is the null pointer at the end of each list.

For pairs events, the score on each board is scaled up to the matchpoint top (N-1) when the number of results for the board is fewer than N. This can happen when a table does not have time to play the board (and there is no late play), there is a sitout in one section, there are differing numbers of tables in each section such that some boards (usually high numbered one) are not used at all in some section(s), or one or more sections do not complete all scheduled rounds. This scaling can lead to curious looking matchpoint score. For example, consider this ugly situation of a pairs event with a 12½ table section and a 12 table section. Each section played two board rounds. ACBLscore come up with a combined top of 23 on the assumption that a board could be played a maximum of 24 times, 12 times in each section; however the 21½ section which by itself would be played 13 rounds was terminated after 12 rounds to end at the same time as section B. Due to the sitout in Section A, most boards were played 11 times so the results were scaled by 23/22. Boards 25 and 26 were only played in Section A so they got scaled by 23/10. Even this is not quite right because the scaling is not to 0 and N-1 but rather to a slightly smaller interval in an attempt to make a top based on more results a bit more worthy than a top based on fewer boards. This explains the tops and bottoms of 22.98 and 0.02 respectively instead of 23 and 0 for board subject to the nominal scaling by 23/22.

Note: the ACBLscore documentation confusingly uses the term factoring instead of scaling, despite the completely different meaning of the word factoring in algebra. Don Greenwood does not share my aversion to factoring, citing a definition of the term meaning, “to bring to a common base.”

Event Details Structure

Each event has a pointer in the Master Table to an Event Details structure.

Event Details Structure
Offset Type Description
0000 int16 Length of rest of structure (should always be 0x02e4 = 740 bytes)
0002 uint8 Event number (numbering starts at 1).
0003 ?? (1 byte - always seems to be zero. Perhaps the preceding field is really uint16, though it needn’t be because 50 is the maximum number of events).
0004 string(25) Event name, e.g. ‘Sunday Afternoon Pairs’
001e string(13) Session name, e.g. ‘Sunday Aft’
002c string(16) Director’s name (City when ACBLscore is in Tournament mode)
003d string(10) Tournament sanction, e.g. ‘R1204034’ (empty for club games)
0048 string(19) Date, e.g. ‘August 25, 2013’
005c string(25) Club or tournament name, e.g. ‘La Jolla Unit 526’
0076 string(4) Event code, e.g. ‘AMSS’ for Morning (AM) Side Series. Probably only used for tournaments.
007b ?? (2 bytes)
007d intfloat(1) Masterpoint Rating P-factor (as percent). See Masterpoint Awards, Rules, & Regulations. Example: 0xE803 → 100% → 1. (80% for one restriction, 70% for two restrictions)
007f ?? (4 bytes)
0083 intfloat(1)? Masterpoint Rating T-factor (as percent). See Masterpoint Awards, Rules, & Regulations. Example: 0xE803 → 100% → 1. (75% for Individual events, 110% for BAM events)
0085 ?? (3 bytes)
0088 uint8 Rating: 0 → No Masterpoints Awarded, 1 → Club Masterpoint, etc. Refer to the auxiliary Event Rating Enum table below for a list of all known values. Note: In ACBLscore, the rating is set via F9 → “10. Set masterpoint rating”.
0089 uint8 End of event flag (0xFF = 255 indicates the last session of a multi-session event)
008a uint16 Board Average (usually 0, purpose unclear).
008c uint8 Session number (starting at 1)
008d int8 Handicap Type (0 → Not Handicapped, ±1 → Percentage based on previous performance, ±2 → Matchpoints, ±3 → Boards). Negative values mean ranking is based on score + handicap. Positive values mean both handicapped and un-handicapped rankings are generated. See section 3.2.26.2 of the ACBLscore Manual (HAND command).
008e uint8 Start session number (starting at 1)
008f boolean Carryover calculated flag
0090 boolean Tournament data edited flag
0091 boolean Negative Handicap flag (nonzero means strong pairs can be assigned a negative handicap)
0092 uint8 0xFF → Masterpoint awards verified (see OALL ACBLscore command)
0093 ?? (1 byte)
0094 uint8 Max IMP swing
0095 uint8 Club Session (0-22). 0 → Not a club game; 1 → Mon Mor; 2 → Mon Aft; 3 → Mon Eve; … 19 → Sun Mor; 20 → Sun Aft; 21 → Sun Eve; 22 → Cruise Ship)
0096 intfloat(2) Tie Break Spread. Usually 0.01.
See section 3.2.53 of the ACBLscore Manual (SET command).
0098 uint16 Total matchpoints for a perfect game = Number of boards played (if no sitout) × top on single board
009a uint16 Top on a board
009c ?? (2 bytes)
009e uint8 Number of strats
009f uint8 Total number of sessions
00a0 boolean Consolation flag
00a1 ?? (8 bytes)
00a9 uint8 Rating (see above). Why is this repeated?
00aa ?? (4 bytes)
00ae uint8 Number of Newcomer Tables
00af ?? (1 byte)
00b0 string(6) Club number, e.g. ‘146506’
00b7 datetime Event creation timestamp
00bb ?? (2 bytes)
00bd pointer Pointer to Memo Structure for event wide memo
00c1 ?? (1 byte)
00c2 uint8 Number of brackets
00c3 uint8 Bracket number for this event
00c4 ?? (1 byte)
00c5 string(4) Qual Event Code
00ca uint8 Handicap dual ranking masterpoint award method (0 → Better of full award from un-handicapped ranking or 50% of award that handicapped ranking would give it were un-handicapped; 50 → 50% of award from each of un-handicapped and handicapped rankings). See section 3.2.26.2 of the ACBLscore Manual.
00cb ?? (1 byte)
00cc boolean IMP Datum Calc flag
00cd ?? (7 bytes)
00d4 struct Strat 1 Strat Structure
0133 struct Strat 2 Strat Structure
0192 struct Strat 3 Strat Structure
01f1 ?? (76 bytes)
023d boolean Split Site flag
023e ?? (6 bytes)
0244 string(8) Set number of ACBL supplied hands for a tournament. This number sometimes appears as “Set #####” on the paper recap sheets. String is “SHUFFLE” when there are no hand records.
024d ?? (2 bytes)
024f intfloat(2) Masterpoint Rating S-factor (Multi-Session factor). See Masterpoint Awards, Rules, & Regulations.
0251 uint16 Restrictions. Event Restrictions such as Mixed Pairs, Junior, Senior, and Women’s and Invitational Only (only for Club Games), etc reduce the Masterpoint award. See P-factor in Masterpoint Awards, Rules, & Regulations. Note: A Masterpoint Limited event (e.g. 749er) is not a Restricted event in ACBL parlance. 0 → No Restrictions. This a bit field: Bit 0 (LSB) set → Senior Event; Bits 1-3 probably cover Junior, Mixed, and Women’s event though this has not been confirmed and order may not be as listed. Bit 8 set → 80% award reduction applies; Bit 9 set → 70% reduction applies (because two or more restrictions have been applied).
0253 boolean Side Game flag. Side game series are seen at regionals and nationals. Masterpoint are given for individual sessions are commutative performance over multiple sessions.
0254 ?? (23 bytes)
026b boolean Print Unpaid flag. Can be set in Tournament Mode to print out player data sheets for non-current (unpaid) players.
026c ?? (92 bytes)
02c8 boolean Stratify by average flag. In the old days, pair event were stratified based on the player with the highest number of masterpoint. In recent years a new option to stratify by each pair’s average masterpoint holding was added.
02c9 boolean Recaps in Percent flag. If non-zero, recaps will be shown as a percentage instead of matchpoints.
02ca boolean Non-ACBL flag.
02cb ?? (27 bytes)
Event Rating Enum
Value Description
0 No Masterpoints Awarded
1 Club Masterpoint
2 Club Championship
3 Charity Club Championship
4 Unit Championship
5 Regional
6 Sectional
7 Club International Fund
8 Club Membership
12 Upgraded Club Championship
14 STAC
15 National
16 Bridge Plus
17 Progressive Sectional
18 Unit Charity Game
19 Unit Extended Team Game
20 NAP Club Level
21 NAP Unit Level
22 GNT Club Level
23 GNT Unit Level
24 ACBL Wide Charity
25 ACBL Wide International Fund
Value Description
27 Canada Wide Olympiad
28 World Wide Instant Matchpoints
29 ACBL Wide Instant Matchpoints
30 Junior Fund
32 ACBL Wide Senior
33 COPC Club Level
34 CNTC Master/Non Master
35 CNTC Club Level
36 CNTC Unit Level
37 CWTC
38 Canada Rookie/Master
39 Inter-Club Championship
40 Unit Wide Championship
43 Club Appreciation
49 Club Appreciation Team
50 NABC Fund Raiser
51 GNT Fund Raiser
52 CNTC Fund Raiser
55 Club Education Foundation
56 Unit International Fund
57 Club Membership
58 Unit Education Fund
63 Grass Roots Fund
Strat Structure
Offset Type Description
0000 ?? (16 bytes)
0010 intfloat(2) ?? - Masterpoints for 1st Overall in side series
0012 ?? (2 bytes)
0014 intfloat(4) Masterpoint factor for masterpoint calculation. This definitely includes the M-factor but is probably actually M-factor × P-factor (restrictions) × T-factor. See Masterpoint Awards, Rules, & Regulations. The M-factor only applies to tournament games and club games which are based on a sectional rating, e.g. Unit Championships. Example: 0x3621 → 0.8502.
0016 intfloat(2) Masterpoints for 1st Overall in strat
0018 uint16 Rank depth (number of ranks that can receive masterpoints in strat). Can (not will) because an individual, pair, or team receives their best award from all strats they are eligible to be ranked in.
001a uint16 Number of tables assumed for determining 1st overall award. The top flight in an open event gets to count the tables from concurrent limited events in determining the masterpoint award on the implicit assumption that if the players in the limited event(s) had been in the open event they would have been beaten. Yes this is hokey, but the ACBL has shied away from a Strength of Field based calculation despite using the M-factor to reduce the masterpoint award in limited flights. See “Include tables from lower flights and events?” and “Tables to base overall awards in strat?” questions in ACBLscore when in Tournament Mode.
001c uint16 Defines ranks to omit at current site in a multi-site event.
001e uint16 Strat minimum masterpoints (typically 0).
0020 uint16 Strat masterpoint cutoff (0 for Strat 1 = Unlimited, i.e. an open game)
0022 char(1) Strat ASCII letter, e.g. ‘A’, ‘B’, or ‘C’. Occasionally single digits are used, e.g. ‘7’ and ‘3’ if the Swiss Team cutoffs are say 750 MP and 300 MP.
0023 uint8 Percent of open game rating for Strat in club game, e.g. 80 (for strat 1) or 60 (for strat 2 or 3) if the ACBLscore report says: RATING>Club Masterpoint (80%, 60%, 60% Open). Set to 100 for Strat 1 in an open game. M-Factor at offset 0x0014 is not relevant for club game masterpoint calculations. See The Club Sanctioned Bridge Game, Section 4 (Club Masterpoint Awards).
0024 ?? (6 bytes)
002a ?? (6 bytes)
0030 ?? (2 bytes)
0032 struct Masterpoint Pigmentation Structure for Overall Award in Strat
0041 struct Masterpoint Pigmentation Structure for Session Award in Strat
0050 struct Masterpoint Pigmentation Structure for Section Award in Strat
Masterpoint Pigmentation Structure
Offset Type Description
0000 intfloat(2) Percent of total masterpoint award given as first pigmentation type
0002 intfloat(2) Percent of total masterpoint award given as second pigmentation type
0004 intfloat(2) Percent of total masterpoint award given as third pigmentation type
0006 intfloat(2) Masterpoints of first pigmentation type awarded for top award
0008 intfloat(2) Masterpoints of second pigmentation type awarded for top award
000a intfloat(2) Masterpoints of third pigmentation type awarded for top award
000c uint8 First pigmentation type
(0 = Not used, 1 = Black, 2 = Silver, 3 = Red, 4 = Gold, 5 = Platinum)
000c uint8 Second pigmentation type
000d uint8 Third pigmentation type
Section Strat Structure
Offset Type Description
0000 int16 Section rank depth for N-S pairs or North individuals (-1 → standard depth of 40%, See Masterpoint Awards, Rules, & Regulations.)
0002 int16 Section rank depth for E-W pairs or East individuals
0004 int16 Section rank depth for South individuals
0006 int16 Section rank depth for West individuals
0008 uint16 N-S pairs (or North individuals) in strat. This is the actual number of pairs in the strat, not the number of pairs eligible to be ranked in the strat.
000a uint16 E-W pairs (or East individuals) in strat
000c uint16 West individuals in strat
000e uint16 South individuals in strat
0010 int16 Qualification depth for N-S pairs
0012 int16 Qualification depth for E-W pairs
0014 int16 Qualification depth for South individuals
0016 int16 Qualification depth for West individuals
0018 ?? - (1 byte)

Section Details Structure

Each Section Summary Structure has a pointer to a Section Details Structure.

Section Details Structure
Offset Type Description
0000 int16 Length of rest of structure (should always be 0x0322 = 802 bytes)
0002 uint16 Section number within event (numbering originally starts at 1).
0004 pointer Pointer to Pair Index Table for N-S pairs at first round (if pairs event)
Pointer to Team Index Table (if teams event)
Pointer to Individual Index Table for North (if individual event)
0008 pointer Pointer to Pair Index Table for E-W pairs at first round (if pairs event)
Point to Individual Index Table for East (if individual event)
000c pointer Pointer to Individual Index Table for South (individual events only)
0010 pointer Pointer to Individual Index Table for West (individual events only)
0014 pointer Pointer to the Pair Match Table
0018 uint8 Pair Movement Type. 0 → Mitchell, 1 → Howell, 2 → Web, 3 → External, 4 → External BAM, 5 → Barometer, 6 → Manual Mitchell, 7 → Manual Howell. For team games value is set to 0.
0019 uint16 Number of boards in play
001b uint16 Highest pair number. For a Mitchell movement, this equals the number of tables. For a Howell movement it is twice the number of tables (haven’t checked what happens if highest pair number is a phantom pair).
001d uint8 Number of boards / round
001e uint16 Top on a board
0020 uint16 Location of bye stand (0 → no bye stand)
0022 uint16 Rover Movement Mode: 0 → No Rover, -1 for N-S Rover, 2 for E-W Rover. Rover movements are an alternative to a phantom pair or bump pair for handling a half table.
0024 uint16 Starting table for Board #1
0026 uint16 Round after which E-W pairs skip a table in a Mitchell movement
(applies when number of tables is even). 0 → No skip.
0028 ?? (2 byte)
002a uint16 Player Names Entered Status (0 → No names entered, 1 → Some names entered; 100 → All names entered)
002c boolean Carry over scores flag
002d uint8 Maximum number of boards to play (for pairs) / matches (for teams)
002e infloat(1) Board Factor. This is usually zero which means it doesn’t apply. But it can be used to scale (factor in ACBLscore parlance) the scores on each board to give them the same weight across each session of a multi-session event. This value can be specified when setting up a game (F9 → Option #6).
0030 intfloat(1) Score Adjust Average. This value can be specified when setting up a game (F9 → Option #13). Rarely used.
0032 boolean Whether or not scores have been factored (flag)
0033 uint8 Posting Method. 0 → Pickup Slips, 1 → Travelers
0034 boolean Posted flag
0035 uint16 Number of rounds
0037 string(11) Movement filename, e.g. ‘H0509.HOW’ for a five table Howell movement. These files are stored in the MOV subfolder of the ACBLscore installation. Mitchell movements do not seem to get a name, probably because they are programmatically easy to handle for any number of tables and presumably no movement file is consulted.
0043 int16 Phantom pair number. Zero if no phantom pair. A positive value indicates a N-S phantom; negative indicates an E-W phantom.
0045 uint8 Section color index
0046 uint8 DBADD count
0047 boolean Barometer game flag
0048 uint16 Number of tables
004a ?? (4 bytes)
004e uint16 Total matchpoint score for a 100% game, i.e. the denominator when working out a pair’s percentage. Maximum number of Victory Points for Victory Point scoring of team games.
0050 string(6) Color designation for section, e.g. ‘BLUE’. These colors are used in the ACBLscore user interface.
0057 ?? (4 bytes)
005b uint8 Round number after which there is a change in the posting method.
005c ?? (4 bytes)
0060 boolean Web Movement flag
0061 uint8 Maximum times a board is played
0062 boolean Outside adjustments entered flag
0063 uint8 Sequence used in posting method. 0 → table/round, 1 → N-S pair number.
0064 uint16 Table where rover pair start for a rover movement
0066 ?? (2 bytes)
0068 struct Section Strat Structure for strat 1
0081 struct Section Strat Structure for strat 2
009a struct Section Strat Structure for strat 3
00b3 uint8 ?? (2 bytes)
00b5 intfloat(2) Match award masterpoints (team game)
00b7 uint8 ?? (2 bytes)
00b9 uint8 Victory Point scale used (team game). 0 → 20, 1 → 30, 2 → 25
00ba ?? (3 bytes)
00bd datetime Section modification timestamp
00c1 ?? (16 bytes)
09d1 pointer Pointer to Memo Structure for section wide memo (usually 0 → No Memo). See section 3.2.34 of the ACBLscore Manual (MEMO command).
00d5 boolean BAM Movement flag
00d6 ?? (2 bytes)
00d8 intfloat(2) ACBLscore version of last version of ACBLscore to modify the section.
00da uint8 Phantom pair related for individual movements
00db uint8 Phantom pair related for individual movements
00dc ?? (81 bytes)
012d struct Initial table and direction for pair 1 in a Howell Movement (2 bytes)
Table number (uint8), direction (uint8) where 1 → N-S, 2 → E-W
012f struct Initial table and direction for pair 2 in a Howell Movement (2 bytes)
Table number (uint8), direction (uint8) where 1 → N-S, 2 → E-W
0131 struct (etc…but for up to how many pairs? Could be up to 40 before running into Mitchell area though that area wouldn’t be needed for a Howell.)
017d struct Initial pairs at Table 1 for a Mitchell Movement (4 bytes)
N-S pair ID (uint8), E-W pair (uint8), 0 (uint16)
Probably North, East, South, and West for an individual movement.
For a Mitchell movement the pair ID matches the pair number unless things are adjusted manually.
0171 struct Initial pairs at Table 2 for a Mitchell Movement (4 bytes)
0175 struct (etc…but for up to how many tables? Could be up to 48 given the zeroed out region seen here beyond the last table up to the next entry.)
023d pointer Pointer to Team Match Table
0241 ?? (227 bytes)

Masterpoint Award Structure

Masterpoint Award Structure
Offset Type Description
0000 intfloat(2) Masterpoints of 1st pigmentation type
0002 uint8 Pigmentation type for previous field
(0 = Not used, 1 = Black, 2 = Silver, 3 = Red, 4 = Gold, 5 = Platinum)
0003 uint8 Ranking type that generated pigmentation for previous field. Ones digit is the strat (1 through 3). Tens digit is the session number (0 → Overall when score is average across all sessions in the event).
0004 intfloat(2) Masterpoints of 2nd pigmentation type
0006 uint8 Pigmentation type for previous field
0007 uint8 Ranking that generated pigmentation for previous field.
0008 intfloat(2) Masterpoints of 3rd pigmentation type
000a uint8 Pigmentation type for previous field
000b uint8 Ranking that generated pigmentation for previous field.

The Masterpoint Award Structure occurs in the Player, Pair, and Team structures.

If only one pigmentation type, e.g. Black, is awarded, the result will always be stored in the first position. If only two pigmentation types are awarded, the results will always be stored in the first two positions.

Mixed pigmentation occurs in several ways. It can occur in a single session when a pair ranks high enough to receive an award in a superior pigmentation (e.g. from an overall ranking) while simultaneously ranking high enough to received a higher award in an inferior pigmentation (e.g. from a section ranking). In this case the pair receives the highest masterpoint award but only the part of it that would have been awarded in the superior pigmentation is given in the superior pigmentation. The most common scenario is a mix of gold and red points at a regional. Or a pair can received gold in one session and red in another of the same event. Also some events, e.g. low bracket Knockouts, pay out a mix of pigments.

Ranking Structure

Ranking Structure
Offset Type Description
0000 uint16 Section rank if masterpoints were won. Zero if masterpoints were not won or pair or individual is not eligible to be ranked in strat. Field is not applicable to team games.
0002 uint16 Zero unless there is a tie for section rank; e.g. if there is a tie for second and third place, the preceding value will be 2 and this value will be 3.
0004 uint16 Overall rank if masterpoints were won. Zero if masterpoints were not won or team, pair, or individual is not eligible to be ranked in strat.
0006 uint16 Zero unless there is a tie for overall rank; e.g. if there is a tie for second and third place, the preceding value will be 2 and this value will be 3.
0008 uint16 Qualification flag. Examples include NAP qualification or qualification to move onto next session, e.g. next day of Blue Ribbon pairs.
000a uint16 Rank regardless of whether ranking is awarded. Zero if team, pair, or individual is not eligible to be ranked in strat. Ties are split up, e.g. for a 2/3 tie, one entity will get a rank of 2 and the other 3.
000c uint16 Index ID of pair or individual with next lowest section rank (value at 0x000a).
Acts like a linked list together with next two fields.
000e uint8 Section ID of pair or individual with next lowest section rank
000f uint8 Direction ID of pair or individual with next lowest section rank
0010 uint16 Index ID of team, pair or individual with next lowest overall rank (value at 0x000a).
Acts like a linked list together with next two fields. Overall ranking links can span multiple sections and all directions in a section.
0012 uint8 Section ID of pair or individual with next lowest overall rank
0013 uint8 Direction ID of pair or individual with next lowest overall rank

The Rank Structure occurs in the Pair and Team structures. This structure stores the section and overall ranking, including ties, for a pair or team in a single strat.

Player Structure

Player Structure
Offset Type Description
0000 string(16) Last name
0011 string(16) First name
0022 string(16) City
0033 string(2) State, e.g. ‘CA’
0036 string(7) ACBL player number. Empty string or ’NM’ (Non-Member) if players does not have an ACBL player number.
003e string(3) DB key (probably for the local ACBLscore Player DB)
0042 intfloat(2) Wins at teams. Need this for individual players because teams can have up to six players.
0044 intfloat(2) Max wins at teams.
0046 ?? (2 bytes)
0048 struct Masterpoints awarded to player from previous session(s) of event.
See Masterpoint Award Structure.
0054 struct Masterpoints awarded to player in this session of event.
See Masterpoint Award Structure.
0060 struct Masterpoints awarded to player from all session(s) of event.
See Masterpoint Award Structure.
006c ?? (3 bytes)
006f boolean DB Link flag
006f uint8 Player’s recent masterpoint total (integer portion only). These are masterpoints not yet sent to the ACBL in a masterpoint report (all masterpoints earned by non-members). This is specific to one ACBLscore installation, typically one club.
0070 uint16 Player’s masterpoint total (integer portion only). This is used for stratification. It can be out of date because it is based on the last time player information has been updated in ACBLscore. Also this field will overflow for Jeff Meckstroth who is over 65535 MP.
0073 char(1) Player’s Rank. See Masterpoint Honor Titles in The Masterpoint Plan. Space (“blank”) → Rookie (0-5 MP), A → Junior Master (5-20 MP), B → Club Master (20-50 MP), …, N → Grand LM. Refer to the Player Ranks table below. These ranks can be out of date because the are based on the last time player information has been updated in ACBLscore.
0074 ?? (1 byte)
0075 string(2) Country code, e.g. ‘US’

The Player Structure occurs once in the twice in the Individual Structure, Pair Structure and six times in the Team Structure. In team events, team members can end up with different masterpoints, for example when a team member is added in a later round of a Knockout event. I am not sure what distinguishes the two fields that seem masterpoint related or whether they are relevant to pairs events.

Player Ranks
Code Title Masterpoint Range
Rookie 0–5
A Junior Master 5+
B Club Master 20+
C Sectional Master 50+
D Regional Master 100+
E NABC Master 200+
F Advanced NABC Master 300+
G Life Master 500+ (was 300+)
H Bronze Life Master 500+
I Silver Life Master 1000+
J Gold Life Master 2500+
K Diamond Life Master 5000+
L Emerald Life Master 7500+
M Platinum Life Master 10000+
N Grand Life Master 10000+

The Sectional Master and all higher ranks, also have pigmented point requirements. Grand Life Master requires a national title.

Pair Structure

Pair Structure
Offset Type Description
0000 int16 Length of rest of structure (should always be 0x0192 = 402 bytes)
0002 uint16 Pair Entry ID (same as table number on first round). This will equal the pair number for a Mitchell movement but not for a Howell movement. This number should probably be viewed as a 1-based index into the Pair Index Table. Most reliable way to find Pair Number seems to be examining the first round of the Pair Match Table.
0004 intfloat(2)
(4 bytes)
Adjustment. Usually negative, the result of a pair being penalized, e.g. for slow play or a Zero Tolerance violation.
0008 intfloat(2)
(4 bytes)
Unscaled score for this session (can be negative for IMP Pairs). For example, consider a pair that gets bumped for one round of 13 rounds in a Mitchell Rover (bump) movement. Their score in the next field will be (13/12) times their unscaled score. Similar if a pair ran out of time to play a single board in the same event, their score will be scaled up by (26/25). See Number of Boards played field at offset 0x002f.
000c intfloat(2)
(4 bytes)
Score for this session (can be negative for IMP Pairs). For pairs, this is the total matchpoints for the partnership and this number divided by the total matchpoint score for a 100% game at offset 0x004e in Section Details Structure gives the partnership percentage. For IMP Pairs, this number is the total IMPs and the value is signed. ACBLscore reports display this value in the ‘Score’ column. For Teams games, it is the total victory points or number of wins depending on the scoring method for the event.
0010 intfloat(2)
(4 bytes)
Carryover Score (multi-session events only, can be negative for IMP Pairs). Value has the same meaning as Score as per the scoring method used for the event.
0014 intfloat(2)
(4 bytes)
Final Score (multi-session events only, can be negative for IMP Pairs). Value has the same meaning as Score as per the scoring method used for the event.
0018 intfloat(2)
(4 bytes)
Handicap (4 bytes). Can be negative if a handicap game is setup to allow negative handicaps.
001c intfloat(2) Partnership percentage. Zero for IMP Pairs.
001e uint16 Partnership strat (1-3)
0020 uint32 Partnership average masterpoints (nearest integer). Used to determine the stratification.
0024 ?? (5 bytes)
0029 char(2) Next session seat assignment: Section (multi-session events only)
(‘98’ → pair resigned)
002b char(1) Next session seat assignment: Direction
(‘E’ → E-W, ‘N’ → N-S, ‘ ’ → pair resigned)
002c uint16 Next session seat assignment: Table Number (0 → pair resigned)
002e uint8 Next session seat assignment related.
1 seems to indicate player stays in the same section.
002f uint16 Number of boards played
0031 ?? (2 bytes)
0033 uint8 Eligibility status. Normally zero (eligible) but will be non-zero (seen value of 10) if an ineligible pair fills in. Examples include a life master playing in an NLM event or a pair where one player’s (or the pair’s average) masterpoint holding exceeds the upper limit of a limited game. Usually the pair is filling in to prevent a half table. For the ranking, ACBLscore reports will show NE (Not Eligible) in the top flight.
0034 struct Masterpoints awarded to each member of the partnership from previous session(s) of event. See Masterpoint Award Structure.
0040 struct Masterpoints awarded to each member of the partnership in this session. See Masterpoint Award Structure.
004c struct Masterpoints awarded to each member of the partnership from all sessions. See Masterpoint Award Structure.
0058 ?? (6 bytes)
005e struct Ranking and qualification in Strat 1 (typically ‘A’). See Ranking Structure.
0072 struct Ranking and qualification in Strat 2 (typically ‘B’). See Ranking Structure.
0086 struct Ranking and qualification in Strat 3 (typically ‘C’). See Ranking Structure.
009a ?? (10 bytes)
00a4 struct Player Structure for first player in partnership (120 bytes)
011c struct Player Structure for second player in partnership (120 bytes)

If there is a phantom pair, the phantom pair will have a Pair Structure associated with it but nothing will be filled in.

Pair Index Table

The Pair Index Table gives the starting addresses of each Pair Structure. Pair Structures are usually laid out consecutively without gaps but this should not be assumed. Use the Pair Index Table to find each entry. For sections belonging to pairs events, the Section Details Structure contains two pointers at offsets 0x0004 and 0x0008 to Pair Index Tables.

Pair Index Table
Offset Type Description
0000 int16 Length of rest of table (18 + 8 × number of Pair Index Entries)
0002 uint16 Pair Index Table ID (always 1 or 2?)
0004 uint16 Always 2. Might be the maximum number of players allowed in a pair.
0006 uint8 Number of Pair Index Entries
0007 ?? (11 bytes)
0014 struct 1st Pair Index Entry
struct Additional Pair Index Entries
Pair Index Entry
Offset Type Description
0000 ?? (2 bytes - always seems to be 0x00 x00)
0002 ?? (2 bytes - always seems to be 0x02 x00)
0004 pointer Pointer to Pair Structure

A pairs sections usually (always?) has two Pair Index Tables with Pair Index ID of 1 or 2. These index tables are for the pairs sitting N-S and E-W at the first round. This means for a Mitchell movement, they are for the N-S and E-W pairs respectively. But for a Howell movement it is an arbitrary division of the pairs based on the movement.

Board2 Result Table

A Board2 Result Table stores all the results on a board in a single section of a pair event. For individual events, see the Board4 Result Table.

Board2 Results Table
Offset Type Description
0000 int16 Length of rest of table (6 + 18 × number of Board2 Result Entries)
0002 uint16 Board number. May technically be a Board ID allowing for a level of indirection but it always seems to match the board number.
0004 uint8 Number of competitive units
(always 2 for Board2 structures since a pair meets a pair)
0005 uint8 Number of results for board. This is not necessarily equal to the number of rounds in the section. For example, if 17 pairs play a Mitchell in one section, some boards will be in play at two tables on the same round.
0006 struct 1st Board2 Result Entry (18 bytes)
Board2 Result Entry
Offset Type Description
0000 uint8 Round number
0001 uint8 Table number
0002 uint16 N-S pair number
0004 int16 Raw score for N-S / 10, e.g. +430 is encoded as 43, i.e. 0x2b 0x00. -50 is encoded as -5, i.e. 0xfb 0xff. Special values: 900 ⇒ Scheduled Late Play, 950 ⇒ Not Played (should have been, but wasn’t), 999 ⇒ Board not in play on this round, 2040 ⇒ Ave-, 2050 ⇒ Ave, 2060 ⇒ Ave+
0006 intfloat(2) Matchpoint score for N-S (IMP gain or loss for N-S for IMP Pairs)
0008 ?? (2 bytes - always seems to be 0x00 0x00)
000a uint16 E-W pair number
000c int16 Raw score for E-W / 10 (as above). Normally the E-W raw score is the opposite of the N-S raw score.
000e intfloat(2) Matchpoint score for E-W (IMP gain or loss for E-W for IMP Pairs)
0010 ?? (2 bytes - always seems to be 0x00 0x00)

The internal storage of raw scores is similar to the ACBLscore user interface. The superfluous final zero is dropped in both during data entry and in the stored value.

ACBLscore has to track separate raw scores and matchpoints for each direction to support director rulings where each side is assigned a different results, possibly based on different assumed contracts, and/or is assigned and Ave-, Ave, or Ave+ score.

Board4 Result Table

A Board4 Result Table stores all the results on a board in a single section of an individual event. For pair events, see the Board2 Result Table.

Board4 Results Table
Offset Type Description
0000 int16 Length of rest of table (6 + 34 × number of Board4 Result Entries)
0002 uint16 Board number. May technically be a Board ID allowing for a level of indirection but it always seems to match the board number.
0004 uint8 Number of competitive units
(always 4 for Board4 structures since four individual are competing at the table)
0005 uint8 Number of results for board. This is not necessarily equal to the number of rounds in the section. For example, if 17 pairs play a Mitchell in one section, some boards will be in play at two tables on the same round.
0006 struct 1st Board4 Result Entry (34 bytes)
Board4 Result Entry
Offset Type Description
0000 uint8 Round number
0001 uint8 Table number
0002 uint16 North pair number
0004 int16 Raw score for South / 10 (same as for Board2 Results Entry)
0006 intfloat(2) Matchpoint score for North (IMP gain or loss for North for IMP Pairs)
0008 ?? (2 bytes - always seems to be 0x00 0x00)
000a uint16 East pair number
000c int16 Raw score for East / 10 (as above). Normally the East raw score is the opposite of the North raw score.
000e intfloat(2) Matchpoint score for East (IMP gain or loss for East for IMP Pairs)
0010 ?? (2 bytes - always seems to be 0x00 0x00)
0012 uint16 South pair number
0014 int16 Raw score for South / 10 (as above). Normally the South raw score is the same as the North raw score.
0016 intfloat(2) Matchpoint score for South (IMP gain or loss for East for IMP Pairs)
0018 ?? (2 bytes - always seems to be 0x00 0x00)
001a uint16 West pair number
001c int16 Raw score for West / 10 (as above). Normally the West raw score is the same as the East raw score.
001e intfloat(2) Matchpoint score for West (IMP gain or loss for East for IMP Pairs)
0020 ?? (2 bytes - always seems to be 0x00 0x00)

ACBLscore has to track separate raw scores and matchpoints for each player to support director rulings where each player is assigned a different results, possibly based on different assumed contracts, and/or is assigned and Ave-, Ave, or Ave+ score.

Board Results Index Table

The Board Result Index Table gives the starting addresses of each Board2 Result Table (pairs) or Board4 Result Table (individual events). Board Result Tables are usually laid out consecutively without gaps but this should not be assumed. Use the Board Result Index Table to find each entry. The Section Summary Structure has a pointer to the Board Result Index Table at offset 0x0008.

Board Results Index Table
Offset Type Description
0000 int16 Length of rest of table (36 + 8 × number of Board Results Table Entries)
0002 uint8 Section number within Event (see Section Details Structure)
0003 ?? (1 byte - always seems to be zero. Perhaps preceding field is really uint16.)
0004 uint8 Number of Board Results Tables
0005 ?? (31 bytes)
0024 struct 1st Board Results Index Entry (8 bytes)
Additional Board Results Index entries
Board Results Index Entry
Offset Type Description
0000 uint16 Board number
0002 uint16 Number of Board Results Entries in corresponding Board Result Table
0004 pointer Pointer to Board2 Results Table or Board4 Results Table

Pair Match Table

The Pair Match Table indicates which pairs are seated at each direction at each round at each table. Use the information about which pairs are seated at each table at round one to determine the pair number for each Pair Structure based on the table number given at offset 0x0002 of the Pair Structure.

Note: The Pair Match Table was formerly called the Movement Structure but a more careful examination of how teams and individual events were stored suggested renaming the table for consistency.

Pair Match Table
Offset Type Description
0000 int16 Length of rest of structure (7 + 75 × number of tables)
0002 uint16 Pair Match Table ID
0004 uint8 Number of tables in the movement
0005 uint8 Number of rounds in the movement
0006 uint8 Match Mode (Always 0 for Pair Movements)
0007 array Array of 25 Pair Match Structures (one per round) for Table 1 (75 bytes)
0052 array Array of 25 Pair Match Structures (one per round) for Table 2 (75 bytes)
Additional arrays of Pair Match Structures (one per table)
Pair Match Structure
Offset Type Description
0000 uint8 N-S pair number
0001 uint8 E-W pair number
0002 uint8 Lowest board number played by the N-S and E-W pairs on this round at this table

The Pair Match Table allocates 75 bytes per table for movement information, enough for 75 / 3 = 25 rounds. This is enough rounds for one board per round. In practice it is much more common to have two or three boards per round. Unused Pair Match Structure array elements contain zeros in all fields.

Individual Structure

The Individual Structure is essentially the same as the Pair Structure but includes only one player. It is used for rarely played individual events where each individual is matched with a new partner on each round.

Individual Structure
Offset Type Description
0000 int16 Length of rest of structure (should always be 0x011a = 282 bytes)
0002 uint16 Pair Entry ID (same as table number on first round). This will equal the pair number for a Mitchell movement but not for a Howell movement. This number should probably be viewed as a 1-based index into the Pair Index Table. Most reliable way to find Pair Number seems to be examining the first round of the Pair Match Table.
0004 intfloat(2)
(4 bytes)
Adjustment. Usually negative, the result of a pair being penalized, e.g. for slow play or a Zero Tolerance violation.
0008 intfloat(2)
(4 bytes)
Unscaled score for this session (can be negative for IMP Pairs). For example, consider a pair that gets bumped for one round of 13 rounds in a Mitchell Rover (bump) movement. Their score in the next field will be (13/12) times their unscaled score. Similar if a pair was ran out of time to play a single board in the same event, their score will be scaled up by (26/25). See Number of Boards played field at offset 0x002f.
000c intfloat(2)
(4 bytes)
Score for this session (can be negative for IMP Pairs). For pairs, this is the total matchpoints for the partnership and this number divided by the total matchpoint score for a 100% game at offset 0x004e in Section Details Structure gives the partnership percentage. For IMP Pairs, this number is the total IMPs and the value is signed. ACBLscore reports display this value in the ‘Score’ column. For Teams games, it is the total victory points or number of wins depending on the scoring method for the event.
0010 intfloat(2)
(4 bytes)
Carryover Score (multi-session events only, can be negative for IMP Pairs). Value has the same meaning as Score as per the scoring method used for the event.
0014 intfloat(2)
(4 bytes)
Final Score (multi-session events only, can be negative for IMP Pairs). Value has the same meaning as Score as per the scoring method used for the event. Probably a four byte field.
0018 intfloat(2)
(4 bytes)
Handicap (4 bytes). Can be negative if a handicap game is setup to allow negative handicaps.
001c intfloat(2) Partnership percentage. Zero for IMP Pairs.
001e uint16 Partnership strat (1-3)
0020 uint32 Partnership average masterpoints (nearest integer). Used to determine the stratification.
0024 ?? (7 bytes)
0029 char(2) Next session seat assignment: Section (multi-session events only)
(‘98’ → pair resigned)
002b char(1) Next session seat assignment: Direction
(‘E’ → E-W, ‘N’ → N-S, ‘ ’ → pair resigned)
002c uint16 Next session seat assignment: Table Number (0 → pair resigned)
002e uint8 Next session seat assignment related.
1 seems to indicate player stays in the same section.
002f uint16 Number of boards played
0031 ?? (2 bytes)
0033 uint8 Eligibility status. Normally zero (eligible) but will be non-zero (seen value of 10) if an ineligible pair fills in. Examples include a life master playing in an NLM event or a pair where one player’s (or the pair’s average) masterpoint holding exceeds the upper limit of a limited game. Usually the pair is filling in to prevent a half table. For the ranking, ACBLscore reports will show NE (Not Eligible) in the top flight.
0034 struct Masterpoints awarded to each member of the partnership from previous session(s) of event. See Masterpoint Award Structure.
0040 struct Masterpoints awarded to each member of the partnership in this session. See Masterpoint Award Structure.
004c struct Masterpoints awarded to each member of the partnership from all sessions. See Masterpoint Award Structure.
0058 ?? (6 bytes)
005e struct Ranking and qualification in Strat 1 (typically ‘A’). See Ranking Structure.
0072 struct Ranking and qualification in Strat 2 (typically ‘B’). See Ranking Structure.
0086 struct Ranking and qualification in Strat 3 (typically ‘C’). See Ranking Structure.
009a ?? (10 bytes)
00a4 struct Player Structure (120 bytes)

Individual Match Table

The Individual Match Table indicates which individuals are seated at each direction at each round at each table for individual events.

Individual Match Table
Offset Type Description
0000 int16 Length of rest of structure (7 + 180 × number of tables)
0002 uint16 Individual Match Table ID
0004 uint8 Number of tables in the movement
0005 uint8 Number of rounds in the movement
0006 uint8 Match Mode (Always 2 for Individual Movements)
0007 array Array of 36 Individual Match Structures (one per round) for Table 1 (180 bytes)
00bb array Array of 36 Individual Match Structures (one per round) for Table 2 (180 bytes)
Additional arrays of Individual Match Structures (one per table)
?? (1 byte - yeah, one lousy byte ??)
Individual Match Structure
Offset Type Description
0000 uint8 North pair number
0001 uint8 East pair number
0002 uint8 South pair number
0003 uint8 West pair number
0004 uint8 Lowest board number played by the individuals on this round at this table

The Individual Match Table allocates 180 bytes per table for movement information, enough for 180 / 5 = 36 rounds. This is enough rounds for one board per round. Unused Individual Match Structure array elements contain zeros in all fields.

Team Structure

Team Structure
Offset Type Description
0000 int16 Length of rest of structure (should always be 0x0372 = 882 bytes)
0002 uint16 Team Entry ID. This is not the Team Number. Find that by examining the appropriate Team Index Entry in the Team Index Table. Often the Team Entry ID will match the Team Number but if multiple team events are being run simultaneously this will definitely not be the case for all but one event. For example, the AX Swiss might have team numbers starting at 1 while the BCD Swiss has team numbers starting at 41.
0004 Adjustment (usually the result of a pair being penalized, e.g. for slow play or a Zero Tolerance violation).
0008 intfloat(2)
(4 bytes)
Number of wins this session. A tie is 0.5 wins (long ago ACBL used to have winning and losing ties valued at 0.75 and 0.25 wins respectively).
000c intfloat(2)
(4 bytes)
Score this session (usually Victory Points, probably Wins if Win/Loss scoring)
0010 intfloat(2)
(4 bytes)
Carryover score from previous session(s)
0014 intfloat(2)
(4 bytes)
Final Score
0018 intfloat(2)
(4 bytes)
Handicap (when there are too few teams to properly bracket a Bracketed K.O., IMP based handicaps can be given.)
001c intfloat(2) Percentage?
001e uint16 Team Strat (1-3)
0020 uint32 Masterpoint average of team members
0024 ?? (15 bytes)
0033 boolean Eligibility flag
0034 struct Masterpoints awarded to each member of the team in previous sessions (except when award is different for different team members).
See Masterpoint Award Structure.
0040 struct Masterpoints awarded to each member of the team this session (except when award is different for different team members).
See Masterpoint Award Structure.
004c struct Masterpoints awarded to each member of the team this session (except when award is different for different team members).
See Masterpoint Award Structure.
0058 infloat(2)? Total number of rounds team played? Have seen 0xbc02 → 700 → 7.00
005a ?? (4 bytes)
005e struct Ranking and qualification in Strat 1 (typically ‘A’). See Ranking Structure.
0072 struct Ranking and qualification in Strat 2 (typically ‘B’). See Ranking Structure.
0086 struct Ranking and qualification in Strat 3 (typically ‘C’). See Ranking Structure.
009a ?? (10 bytes)
00a4 struct Player Structure for team player 1 (120 bytes)
011c struct Player Structure for team player 2 (120 bytes)
0194 struct Player Structure for team player 3 (120 bytes)
020c struct Player Structure for team player 4 (120 bytes)
0284 struct Player Structure for team player 5 (120 bytes)
02fc struct Player Structure for team player 6 (120 bytes)

A team may have up to six members. Team members receive masterpoints if they play at least half the time.

Team Index Table

The Team Index Table gives the starting addresses of each Team Structure. Team Structures are usually laid out consecutively without gaps but this should not be assumed. Use the Team Index Table to find each entry.

Team Index Table
Offset Type Description
0000 int16 Length of rest of table (18 + 8 × number of Team Index Entries)
0002 uint8 Probably Section number within Event (see Section Details Structure)
0003 ?? (1 byte - always seems to be zero. Perhaps the preceding field is really uint16).
0004 ?? (2 bytes)
0006 uint8 Number of Team Index Entries
0007 ?? (1 byte - always seems to be zero. Perhaps the preceding field is really uint16).
0008 ?? (10 bytes)
0012 struct 1st Team Index Entry (8 bytes)
struct Additional Team Index Entries
Team Index Entry
Offset Type Description
0000 uint8 Team number
0001 ?? (1 byte - always seems to be zero. Perhaps the preceding field is really uint16.)
0002 ?? (2 bytes - always seems to be 0x04 0x00)
0004 pointer Pointer to Team Structure

Team Match Table

The Team Match Table indicates which team played each other.

Team Match Table
Offset Type Description
0000 int16 Length of rest of structure (32 + 32 × number of rounds)
0002 uint16 Team Match Entry ID
0004 uint8 Number of Rounds
0005 uint8 Match Mode (Always 1 for Teams)
0006 ?? (28 bytes)
0022 struct Team Match Entry for 1st round (32 bytes)
0032 struct Team Match Entry for 2nd round (32 bytes)
0042 struct etc
Team Match Entry
Offset Type Description
0000 uint8 ?? - Always seems to be 1
0001 uint8 Round Number
0002 uint16 Team ID to play against
0004 uint8 Number of Rounds
0005 ?? (3 bytes)
0008 int16 IMPS won or lost on round
000a intfloat(2) Victory Points won on round
000c ?? (1 byte)
000d uint8 Boards played on round
0011 char(1) Table Letter
0012 uint16 Table Number
0014 ?? (2 bytes)
0016 intfloat(2) Wins on round (should be 0, 0.5, or 1.0 but in the old days the scoring had winning and losing ties of 0.75 and 0.25 wins respectively)
0018 ?? (8 bytes)
Team Match Index Table
Offset Type Description
0000 int16 Length of rest of structure (84 + 4 × number of teams)
0002 uint16 Team Match Index ID
0004 uint16 Number of Teams
0006 uint16 Number of Rounds
0008 ?? (31 bytes - always seem to be zero)
0039 pointer Pointer to Victory Point Structure for VP Scale used for event
003d ?? (25 bytes - always seem to be zero)
0056 pointer Pointer to Team Match Table for Team ID 1
005a pointer Pointer to Team Match Table for Team ID 2
005e pointer etc

Victory Point Structure

Victory Point Structure
Offset Type Description
0000 int16 Length of rest of structure (109 + 5 × number of steps)
0002 uint8 Victory Point Chart ID
0004 uint8 Number of steps
0005 uint8 Minimum number of boards per round that chart applies to
0006 uint8 Maximum number of boards per round that chart applies to
0007 uint8 Maximum Victory Points, e.g. 20 → 0-20 VP Scale
0008 string(13) Filename with chart data, e.g. ‘ VP02008.VP’
0016 ?? (1 byte)
0017 string(85) Description, e.g. ‘20 points ACBL, 5-8 boards’
006d struct 1st IMP to VP Structure (5 bytes)
0072 struct 2nd IMP to VP Structure (5 bytes)
0077 struct etc
IMP to VP Structure
Offset Type Description
0000 uint8 Victory margin in IMPs
0001 intfloat(2) Victory Points for winner
0003 intfloat(2) Victory Points for loser

This scheme allows for fractions of a Victory Point though this never seems to occur in practice.

Memo Structure

Memo Structure
Offset Type Description
0000 int16 Length of rest of structure
0002 Memo ID
0006 string(47) Memo text

Memos can apply to all events, individual events, or individual sections. Memos are printed on the appropriate recap sheets.

Note Structure

Note Structure
Offset Type Description
0000 int16 Length of rest of structure
0002 uint16 Note ID
0004 uint16 Line Count
0006 string(75) Text for 1st line
0052 string(75) Text for 2nd line (etc)