While most puzzles were tested at a desk, the GPS challenge demanded real-world conditions, and quickly became the most technically unpredictable part of the system.
Early implementations relied on blocking serial reads to capture a full NMEA sentence (e.g., “$GPRMC,…\r\n”). This led to severe bugs: the system would freeze waiting for a message, or display corrupted/incomplete coordinate data if a partial sentence was parsed.
To fix this, I rewrote the serial handling using an interrupt-driven ring buffer. Each character from the GPS module was read non-blocking via UART and stored until a full sentence was detected (\r\n). A gps_ready flag marked when a complete message was available. This allowed the game loop to remain responsive while waiting for valid GPS data in the background.
Parsing the GPS stream was also trickier than expected. Multiple sentence types ($GPGGA, $GPRMC) arrived in unpredictable order. Fields could shift depending on the sentence type, and many fields (like coordinates) would be left blank until a satellite fix was acquired.
To handle this, I wrote a robust parser that accepted both sentence types, extracted latitude and longitude fields based on sentence format, and ignored invalid or zeroed-out coordinates until a fix was confirmed.
Because GPS reception was unreliable indoors, I often had to test outside. The most reliable results came from standing on top of a parking garage, holding the project box like a handheld scanner while watching the LCD slowly update with raw GPS data.
