Traditionally, AI characters in games are fairly “boring”. They usually say the same sentences repeatedly, because they are driven by predefined “scripts” written by the game developers.
That problem can now be fixed using ChatGPT. ChatGPT can help our game characters to talk to users in natural languages, which will make the games much more interesting and unpredictable.
In this tutorial, we will build a simple game called “Who’s the Spy?”. The player will talk to a few AI characters to guess who is the spy, and we will use ChatGPT to generate answers for these characters.
Please start by remixing the following project, which contains 4 sprites that we will use: a doctor and 3 animal agents (a dog, a reindeer and a monkey).
When the player starts the game, we first need to explain the game to ChatGPT. The description should include a few parts:
Here is an example game description:
You are the “game master” running a game named “Who’s the Spy”.
There is a secret lab run by the “doctor”, and the doctor works with 3 smart assistants (dog, reindeer and monkey). Recently, the blueprint of a revolutionary, world-changing robot was stolen from the lab. Rumors suggest that one of the animal agents has gone rogue and is the spy who stole the design. The doctor has invited the player to help find out who’s the spy. Somehow the security cameras were not working, so we can not rely on that.
Randomly pick one of the three animal assistants as the spy. Only you and the spy know who is the spy. The player can ask the doctor or any assistant any question. You will come up with the answer on behalf of them. Note that the spy might lie. When you answer, always use this format:
dog: it is not me.
The game ends when the player makes a guess, and you will reveal who’s the spy after that.
Note that we are giving ChatGPT a specific format for answering our questions: “dog: it is not me.”. The reason is that ChatGPT may give us answers from any of the characters, so to make it easier to process its response, we need the response to be well-formatted.
Now let’s send the game description to ChatGPT. We can add the following code in the “Doctor” sprite:
We are using a “system” request, which carries a stronger weight than a normal request. We will store the response from ChatGPT in the “response” variable.
Now please copy the game description into the system request block. Recall that you can use a comment box to help if you would like to edit the description.
To review ChatGPT’s responses while developing the project, we can simply print the response in the console panel like this:
When you run the project, it will take a while, and you may see a response like this (try a few times if you don’t):
This is happening because ChatGPT is trying to give a very long response and reached the token limit. For example, it might be repeating the game description to show that it gets it, or it might even start to generate some example conversations between the player and the characters.
We should try to avoid it for 2 reasons:We don’t need ChatGPT to generate any responses yet since we won’t show it to the player; The longer the response, the longer we have to make the player wait.
To avoid this issue, the solution is very simple. We just need to modify our prompt to tell ChatGPT how to respond. For example, we can append this sentence at the end of the system request message:
Now you say the word “Ready” and wait for the player to ask a question.
This is a commonly used technique to make ChatGPT say as little as possible. If you run the project again, it should get the full response very quickly:
Now that ChatGPT is ready, we also need to tell the player about the game. We can ask the “Doctor” to greet the player and explain how to play the game. For example, we can add a “say” block with the following words:
Thanks for coming, Detective! As we discussed on the phone, a blueprint of a highly secretive robot has been stolen, and I believe one of my three assistants is the spy who took it. You can click on any of us to ask a question.
This is what you would get:
Now let’s allow the player to click on the Doctor to ask a question. Specifically, when the player clicks the Doctor sprite, it asks the player to input the question. We can use the “print to console” block again to review the answer. Note that it may be a bit confusing that the “answer” is the player’s input, not the answer from ChatGPT.
This is what the console panel looks like afterward:
As shown, if the user did not input anything, then the “answer” block will just be empty.
Now let’s send the user input to ChatGPT, so it will generate an answer for the Doctor character. We should only do it if the user input is not empty:
Now our doctor is talking to us, and the conversation is completely natural and unscripted. In fact, as the game developer, we don’t even know the answer at this point, since we have asked ChatGPT to secretly pick an animal as the spy.
Currently, ChatGPT’s answer starts with “Doctor:”. That’s good to know for us (the game developer), but we should not show that to the player. We can remove it this way: we split the response into 2 parts using the “:” as the separator, then we only show the second part to the player:
Now the doctor’s answer will not contain the “Doctor:” prefix:
Since the game is played by clicking on the characters, it is common to highlight a character when the mouse pointer is over that character, so the player knows what is clickable. We can trigger this using the “when touching mouse pointer” block. To highlight a sprite, we just need to set its “brightness” to a positive number. We can also play a sound when the doctor is highlighted:
This is the result:
When the mouse pointer is no longer touching the doctor, we should remove the highlight. We can use a “wait until” block that keeps on checking if the sprite is no longer touching the mouse pointer. After that, we reset the brightness to 0.
Here is the result:
By this time, we are done with changing the Doctor. We can reuse a big chunk of the code in the other sprites by “copy” and “paste”. Let’s start with the dog first. The only thing we need to change is the name of the sprite when we send the question to ChatGPT. We also need to add the “Hit 5” sound to the dog sprite.
Now the dog sprite has both highlighting and question answering:
Now please make similar changes to the Reindeer and Monkey sprites. Don’t forget to change the character name when you send the request to ChatGPT.
There is a new issue: when the player switches to talk to a different sprite, the previous sprite may still be showing the speech bubble.
To fix this issue, we need to ask all sprites to hide their speech bubbles whenever any sprite is clicked. This can be done by broadcasting a message to all sprites when a sprite is clicked, and waiting for the message to be handled. When receiving this message, the sprite just needs to say “nothing” to hide the speech bubble. In case the sprite is asking for user input, we should also make it hide the question by “stop asking”.
Note that this change needs to be done to all 4 sprites.
At this point, the player can keep chatting with all the characters to investigate the case. We just need to provide a way for the player to submit the final answer.
First, let’s switch to the Stage, and add a new button when the project starts:
Don’t forget you can use the “Widget Position” tool to help you adjust the button position and size.
This is what the button looks like:
When the player clicks the “Answer” button, we need to show a few radio buttons for the player to select. Besides the 3 animals, we should give the user an option to take a step back and think about it more:
Here is the output:
To handle the player’s selection, we can watch for the “click” event of the radio buttons. The player’s selection can be retrieved using the “value of widget” block. If the player has chosen to think about it more, we should simply remove the radio button group.
If the player has picked one of the three animals, then we will submit it as the answer to ChatGPT, and ask it to tell us whether that’s correct.
Note that we are addressing the “Game Master” since only it can make the final call on the game result.
Now for the last step, we will use a textbox to display the response from ChatGPT. We will make sure the textbox is big enough to show the entire response. We will also remove the other widgets so the player can not re-submit the answer.
Here is the final demo of the game:
Here are some ideas worth exploring based on the project:The doctor sometimes refers to himself as “Dcotor”, not “me”. Think about how to improve the prompt to avoid that. If the player asks a question to more than one character, such as “Everyone, where were you at that time?”, we need to show all the answers. You can use one of the text-to-speech blocks to make the characters speak to the player. You can change the characters and the background stories of the game, such as a stolen book from the library, or a gift box sent from a secret friend. You can even use historical figures to play the game.