circuitpython_1280px-Duel_between_Aaron_Burr_and_Alexander_Hamilton.jpg
Duel between Vice President Aaron Burr and Alexander Hamilton in 1804. Engraving from the book "Our Greater Country being a Standard History of the United States".

The design of the game is very similar to the original with a few additions below marked with the † symbol. The additions are needed to synchronise the two CPB boards and exchange reaction times between them. There are also ten rounds to make this more fun although this doesn't strictly make sense for a duelling game!

The communication protocol between the two boards requires a different role is assigned to each board. This is set using the two-position switch on the board, i.e. the two boards must have the switch in different positions. The player's "draw" button is set to the button on the side the switch is set to.

Game Logic

  1. Turn off all of the NeoPixels.
  2. Determine the communication delay between the boards.
  3. Synchronise the boards.†
  4. Wait the determined (random) countdown time.
  5. If a player presses a button during this time, they drew too soon (misdraw).
  6. Once the countdown time has elapsed, turn on all of the NeoPixels (white).
  7. Wait for the button presses and exchange reaction time data between boards.†
  8. Look for the first (quickest) button press.
  9. Whichever button was pressed first is the Quick Draw winner.
  10. Repeat to step 3 until ten rounds have been completed.†
  11. Display a personalised summary of wins/misdraws on the NeoPixels.†

The exchange of data at step 7 can cause a delay compared to the original single board game. The winner cannot be determined until each board has received the data from the other board.

The winner at step 9 introduces a new colour (amber) to represent the unlikely outcome of both players simultaneously pressing their buttons.

Delay Calculation and Synchronisation Protocol

Sending data from one board to another takes a certain amount of time. If one board sends a "go now" command to another then the sender does not know when the receiver has received and processed that command. The receiver could send a reply but the same problem exists whereby the sender of the reply does not know when it has been received and processed. Measuring the transmission time including the time to receive and parse the data facilitates good synchronisation between the boards. This is one element of the Network Time Protocol (NTP) which can be used to distribute accurate time from reference clocks to computers and devices across the globe.

The send time on its own cannot be measured by the sender but the time to send and receive an immediate reply can be measured by the sender. If the network propagation and processing are symmetric then exactly half of this round-trip time (rtt) represents the time for the sender's data to propagate and be processed with the the other half representing the time for the receiver's reply to propagate and be processed.

The diagram below shows how the rtt measurement operates. Time progresses downwards in the diagram.

circuitpython_cpx-quick-draw-ping_for_rtt-protocol-v3.png
Sequence diagram showing how round-trip time is measured between CPBs.

For comparison, the approach is the similar to how ping works using the ICMP echo service. The traditional TCP/UDP echo service is another similar, higher-level service.

The asymmetric roles for the two boards in the measuring process are commonly referred to in computing and electronics as main and secondary. In this example only the main is measuring the rtt but it then passes the value to the secondary in subsequent packets. A simple way to set the role (or any boolean quantity) is to use the two-position switch on the CPB board.

In Bluetooth LE terminology, the two devices are a central device which connects to a peripheral device. This also gives the boards different roles in terms of a client/server model.

An approximate, but reasonably accurate, send time can be calculated from the measured round-trip times. This duration can then be used by one board to compensate for the send time and this allows the two boards to be synchronised, enabling the game to start on each board at the same time.

circuitpython_cpx-quick-draw-barrier-protocol-v2.png
Sequence diagram showing how CPBs are synchronised before each game round.

The procedure name used in the design is barrier, a reference to a type of synchronisation used for multi-threaded applications. This procedure aims to complete at the same time on each CPB board causing the subsequent code on each to execute near simultaneously. In this case, the aim is to be within a few milliseconds of each other. If the player is reacting to their own white NeoPixel flash then they do not have to be perfectly synchronised.

The staccato nature of Bluetooth LE communication (see diagram in GATT Transactions) is not accounted for in the synchronisation technique and this is one factor reducing its accuracy.

In this design, the same type of messages are used by the request and the response for simplicity.

A message which always elicits a reply message is often referred to as a request and response. This style of interaction in this protocol could also be regarded as a remote procedure call (RPC).

This guide was first published on Jan 20, 2020. It was last updated on Apr 18, 2024.

This page (Game Design) was last updated on Mar 08, 2024.

Text editor powered by tinymce.