# Events - Emitting Game Information
Make sure you have everything you need before proceeding:
- You understand the concepts of events.
- Go is installed.
- You have the checkers blockchain codebase with
MsgPlayMove
and its handling. If not, follow the previous steps or check out the relevant version (opens new window).
In this section, you will:
- Define event types.
- Emit events.
- Extend unit tests.
Now that you have added the possible actions, including their return values, use events to notify players. Your blockchain can now create and play games. However, it does not inform the outside world about this in a convenient way. That is where events come in - but what do you need to emit them?
Imagine a potential or current player waiting for their turn. It is not practical to look at all the transactions and search for the ones signifying the player's turn. It is better to listen to known events that let clients determine which player's turn it is.
Adding events to your application is as simple as:
- Defining the events you want to use.
- Emitting corresponding events as actions unfold.
# Some initial thoughts
Before you dive into the specifics of the exercise, ask yourself:
- Why do actions warrant a detailed event?
- What level of detail goes into each event?
- How do you make it easy for external parties to understand your events?
- At what stage do you emit events?
# Code needs
Now start by thinking about the following:
- How do you adjust your code to do all this?
- How would you unit-test these new elements?
- How would you use Ignite CLI to locally run a one-node blockchain and interact with it via the CLI to see what you get?
Only focus on the narrow issue of event emission.
# Game-created event
Start with the event that announces the creation of a new game. The goal is to:
- Inform the players about the game.
- Make it easy for the players to find the relevant game.
Define new keys in x/checkers/types/keys.go
:
Emit the event in your handler file x/checkers/keeper/msg_server_create_game.go
:
Now you must implement this correspondingly in the GUI, or include a server to listen for such events.
# Player-moved event
The created transaction to play a move informs the opponent about:
- Which player is relevant.
- Which game the move relates to.
- When the move happened.
- The move's outcome.
- Whether the game was won.
Contrary to the create game event, which alerted the players about a new game, the players now know which game IDs to watch for. There is no need to repeat the players' addresses, the game ID is information enough.
You define new keys in x/checkers/types/keys.go
similarly:
Emit the event in your file x/checkers/keeper/msg_server_play_move.go
:
# Unit tests
The unit tests you have created so far still pass. However you also want to confirm that the events have been emitted in both situations. The events are recorded in the context, so the test is a little bit different. In msg_server_create_game_test.go
, add this test:
How can you guess the order of elements? Easily, as you created them in this order. Alternatively, you can peek by using Visual Studio Code:
- Put a breakpoint after
event := events[0]
. - Run this test in debug mode: right-click the green arrow next to the test name.
- Observe the live values on the left.
The event emitted during a move may seem unexpected. In a move unit test, two actions occur: a create, and a move. However, in the setup of this test you do not create blocks but only hit your keeper. Therefore the context collects events but does not flush them. This is why you need to test only for the latter attributes, and verify an array slice that discards events that originate from the create action: event.Attributes[6:]
. This gives the following test:
# Interact with the CLI
Bob made a move. Will Alice's move emit an event?
The log is longer and not very readable, but the expected elements are present:
To parse the events and display them in a more user-friendly way, take the txhash
again:
This returns something like:
As you can see, no pieces were captured. However, it turns out that Alice placed her piece ready to be captured by Bob:
Which prints:
The rules of the game included in this project mandate that the player captures a piece when possible. So Bob captures the piece:
This returns:
When formatted for clarity, you see the following::
Correct: Bob captured a piece and the board now looks like this:
This confirms that the play event is emitted as expected. You can do the same for the game created event.
# Next up
Time to add a third message to make it possible for a player to reject a game and to make your checkers blockchain more resistant to spam.