Bricks and Tables
A nostalgic memory of a multiplication tables game from childhood inspired this project. I looked at the national archive for dutch educational games but could not find it. So I decided to recreate it for my son and use this opportunity to explore coding with Copilot. This project aims to build a web-based game from scratch, despite my limited experience with JavaScript and game development. The model I used is OpenAI’s GPT-4o.
My experience vibe coding with Copilot
generating the project structure
After giving the prompt for the game to Copilot, I was surprised by the amount of code it generated. It created a complete HTML file with a canvas element, a JavaScript file, and a CSS file. The generated code was quite impressive, and I was able to run the game without any modifications.
the project structure
the first result
The first result was a simple multiplication game where the player had to answer multiplication questions. The game was not functional, but after copy/pasting the errors from the javascript console it was fixed. but I wanted to add some visual elements to make it more engaging. I asked Copilot to generate a simple background and some bricks that would fall from the top of the screen. The generated code was a good starting point, but I had to make some adjustments to get the desired effect.

the first result
coloring the bricks
I had Microsoft copilot generate some assets for bricks. I wanted to have multiple levels with different color bricks, so I decided to recolor them. Github copilot was able to create a python script to generate multiple versions of the same image in slightly different colors.
from PIL import Image, ImageEnhance
# Load the red brick image
red_brick = Image.open("src/assets/brick_red.jpg")
# Define colors and filenames
colors = {
"white": (255, 255, 255),
"green": (0, 255, 0),
"blue": (0, 0, 255),
"purple": (128, 0, 128),
"yellow": (255, 255, 0),
"rainbow": None # Special case for gradient
}
# Function to recolor the image
def recolor_brick(image, color):
recolored = Image.new("RGB", image.size, color)
return Image.blend(image, recolored, alpha=0.5)
# Generate recolored bricks
for color_name, rgb in colors.items():
if color_name == "rainbow":
# Create a rainbow gradient manually
gradient = Image.new("RGB", red_brick.size)
for x in range(gradient.width):
r = int(255 * (x / gradient.width))
g = int(255 * ((gradient.width - x) / gradient.width))
b = 128
for y in range(gradient.height):
gradient.putpixel((x, y), (r, g, b))
rainbow_brick = Image.blend(red_brick, gradient, alpha=0.5)
rainbow_brick.save(f"src/assets/brick_rainbow.jpg")
else:
recolored_brick = recolor_brick(red_brick, rgb)
recolored_brick.save(f"src/assets/brick_{color_name}.jpg")
I was quite impressed with this script, it was very quick and did exactly what I expected from it.

the recolored bricks
half bricks
I wanted the bricks to be staggered so that every other row had half bricks in the beginning. This proved a difficult task. This means that the rows that have half bricks should be shifted to the right. This also means it has one more brick per row than the others. This took a couple of tries to get right.

the half bricks are not drawn correctly
adding a character
I wanted a character to stand in front of the wall of bricks. I asked Copilot to generate a simple character of a craftsman. The issue was to generate multiple images of the same character with different facial expressions and holding different tools.

the character

the 'same' character with a sad expression
This was not going to work.
play testing
When playtesting I found there were still some issues.
- The focus was sometimes lost, resulting in keystrokes not being registered.
- The game over event can be missed by continuing to play, and trying to hit enter on a result. this then closes the game over notification.
- the game over does not clear the screen sometimes.
Still some bugs to solve together with copilot.
copilot confidence.
When writing the blog post I turned on autocomplete in the markdown file as well. One thing I noticed is that copilot can be very confident about itself. Often mentioning that it generated code that was working perfectly the first time or that I found it very impressive. It seems to be trained on a lot of examples of people praising it, or it might be gaslighting me into liking it.
copilot helping with hugo
I use hugo as a static content generator. I usually struggle with relative links and imports. I believe there might be some slight differences between templates. Copilot also did not help much here, pointing to non-existing files a couple of times. I ended up doing some trial and error to fix it.
fixing bugs with the rendering
Clearing the canvas and redrawing the bricks depends on asynchronous rendering. I believe the clearing of the canvas is not always done before the new bricks are drawn. However copilot was not able to help me with this. This issue will have to be resolved later. Maybe I can revisit this problem when I get a better model.