There are a million clones of Wordle, the guess-a-five-letter-word game. This post describes number a million and one, using, of course - MQTT.
Before I describe how it works, here is how to play. The game is hosted on test.mosquitto.org, and you need an MQTT client that can both publish and subscribe, and that can print emoji characters from the payload.
One client that can do this is mosquitto_rr
, where "rr" is
"request-response". This client subscribes to a topic, then sends a request
message to a second topic and awaits a response and prints it out. In our case
both request and response topics are the same. The request message we send is
our first guess, and the response shows our result:
You see the round number, out of six, your guess with yellow/green highlighted letters indicating whether the letter was present but in the wrong place or in the correct place, plus the alphabet showing what letters you have used.
Play more rounds using the same command with different words until you win or lose:
There is only one game per day per IP address.
How does it work? The code is in a github repo.
This implements a plugin for Mosquitto (for the develop
branch only) which
controls access to the wordle
topic and processes messages for it.
The plugin registers to receive ACL events. In the event handler it returns
MOSQ_ERR_PLUGIN_IGNORE
for topics that are not exactly wordle
, which tells
the broker it is not handling those topics. For the wordle
topic, it allows
all subscribe and unsubscribe events. Publish events going to the client are
all allowed. Publish events coming from the client are word guesses. Using the
remote IP address as a key, we check to see if the client has made previous
guesses for this word, to determine what round they are on or if they have
won/lost already. This is a fairly crude control mechanism, but the game isn't
intended as a serious production ready implementation.
After some data validation the plugin calculates the result, queues the response up to the sending client and crucially denies access to the publish sent from the client. This means we receive the publish it, process its payload and only after we are finished with it do we reject the message so it is not sent to other clients.
There are a few more details, but the ACL handler is the crux of the operation.
The word list was generated with something like:
grep '^[a-z]\{5\}$' /etc/dictionaries-common/words | shuf > words