logo
Menu
Building a game with Amazon Q Developer: First steps, and a Vue 3 Window Component

Building a game with Amazon Q Developer: First steps, and a Vue 3 Window Component

My journey learning more about frontend HTML and JavaScript development, with the help of generative AI.

Nathan Peck
Amazon Employee
Published Apr 19, 2024
Last Modified Apr 20, 2024
As some of you may know I've been building server side infrastructure for a long time. I know way too much about CloudFormation and containers and all things having to do with backend infrastructure on AWS, but building client side applications is a completely different thing!
Recently I decided to challenge myself to build a non trivial client side application that runs in the web browser. I chose this challenge for two reasons. First, I want to broaden my own skills and stay up to date with modern technologies. Second, I want to try out what it's like to learn new things when there is generative AI tooling to help.
I picked two technologies that will help me achieve both of those goals:
  • Vue.js - To me, this frontend framework feels like it captures some of the magic of the early jQuery I used 15 years ago, without being too magical.
  • Amazon Q Developer - The AI assistant that is going to guide me as I build my application

The idea

My goal for this project is to build a browser hosted game around generative AI. The game will implement many of it’s features using generative AI, and the game will be built with the assistance of generative AI. The idea for the game is fairly simple, but I think it can develop to have a lot of depth to it.
As LLM’s have grown more and more advanced, they are demonstrating a decent understanding of real world objects. You can give an LLM an item and ask it to describe the components that make up the item. You can also ask it to “assemble” a new item out of components. As a super simple prototype you can try out a PartyRock application I put together. The great thing about PartyRock is that it lets me experiment with the capabilities of generative AI without ever writing a line of code.
I want to turn this basic PartyRock prototype into it’s own real game. The general concept is that you are in charge of an interstellar junkyard full of infinite randomly generated junk items. You can “disassemble” any item into components, and “invent” novel items out of the components. Basically, it’s a crafting game with infinite potential and variation. Around this core concept I want to add other traditional game concepts such as a progression system where your character gets experience and improves skills, equipment system where your character could “equip” items that they make, and last but not least a shop system where you can “sell” items to AI backed personas who will need to be convinced by your sales pitch for why they should buy your items.

Designing the interface

The easiest possible interface for a game like this would be a chat based text interface. But I feel that generative AI is too constrained by chat interfaces. I want to build an interface that feels more like a game. In specific I want to build something that feels like the legendary games Transport Tycoon Deluxe and Rollercoaster Tycoon Classic. If you have played these games you probably remember how much information you could bring up on screen by opening up windows. Pretty much every entity in the game has a detail window and you can leave as many windows up on screen as needed to monitor things. If you haven’t played these games just check out the screenshot here as an example. As a junior programmer I was always amazed by the complexity of these two games and how detailed they felt.
Drawing inspiration from these classic games, I can envision my own informationally dense game with lots of small window widgets. I’ve never built a window manager before so this also makes the perfect challenge for my skills and the perfect opportunity for me to use Amazon Q Developer to teach me something new.

Research time

Mocking up a window in the browser is a fairly easy job with HTML and CSS, but for it to feel like a window it needs to be draggable. I turned to Amazon Q Developer to research options. In the following screenshots you can see where I learned about the HTML drag and drop API.

I’ve found that when interacting with LLM’s it is best to not be too prescriptive too early. For example, if I had just told it to show me how to make a <div> draggable, then Amazon Q would only show me one code example for the most common way to do drag and drop, based on sample code trained in. The most common way to do it is not necessarily the best way to do it. In this case the HTML drag and drop API is a better, more modern way to achieve drag and drop.

Implementing and ironing out the bugs

I chose to implement a window component by just adding the draggable="true" attribute to my window element. Here is what happened:
So far with just a tiny change to the code I am already able to grab and drag a ghost version of the window. However, this leaves the original window still visible in it’s original place. There are two copies of the window during the drag and drop. How to solve this? Once again I turned to Amazon Q to ask questions:
So I tried it out to see what the results were:
Uh oh, now both the original window and the dragged version of the window disappear on drag! Looking back at my ask I think that my question was very ambiguous. I did not specify that I only wanted to hide one version of the div, but not the other. This is a typical example of how it can be tricky to ask an AI the right question to get the answer you wanted.
So I asked the question a different way:

This time, I got an answer that implemented a CSS hack I’d never seen before, but it worked! It appears that the clone that the browser drags along on your cursor will take on the appearance of the source element, so if I hid the source element during the drag, that would hide the clone too. I can't change the appearance of the source window element without breaking the appearance of the dragged clone.
However, I can move the source window element off screen so that it is hidden during the drag operation. This leaves the clone visible, while the source element is somewhere way off the screen at -9999px.
The results:
Okay we are getting closer. There is only one window on screen at a time. The source element is properly hidden whenever I drag the window. During the drag I only see the dragged version of the window. However, there is still a problem. Each time I drop the window in a new location there is a “ghost” copy of the window that animates back to the window's original location. Initially I was stumped about how to even describe this problem.
Unfortunately, this answer did not help me that much, although it did contain a seed of the correct answer. I eventually figured out that this problem must be solved on the background element that the window is being dropped on. Because that element was not handling the drag and drop events properly the browser assumed that the drop had failed, and decided to animate the “ghost” flying back to the window’s original location.
I solved it by attaching a basic dragover handler:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<script setup>
import Window from './components/Window.vue'

// This allows windows to be moved without animating a "ghost"
// that slides back to the window's original location
function noGhosts(e) {
e.preventDefault();
}

</script>

<template>
<div id="wrapper" @dragover="noGhosts" @drop="dropped">
<Window />
</div>
</template>
In retrospect there was probably a better way to describe my problem that would have yielded the right answer. This illustrates one of the challenges of working with AI models for answering your questions. If you don’t know the right terminology for asking the question, it likely won’t give you the right answer either. In this case I asked for a solution from the perspective of the dragged item, when the real problem was with the element that I was dropping dragged item onto. Generative models tend to attempt to be helpful and adhere to what you asked for even if what you asked for was completely wrong.
Once I had put all the pieces together here are the results:
If you’d like to try out this demo code yourself check my demo repository here: https://github.com/nathanpeck/vue-window-component

Conclusion

This concludes part one of sharing my journey of building a complex application with the assistance of Amazon Q Developer. I had a few key learnings in this process:
  • It is important to hit the right balance between specific asks and general asks. Being too specific can cause the AI to limit the latent space of it's answers too much in an attempt to be "excessively helpful". Sometimes it's better to be less specific and let the AI tell you the actual right way to do something rather than forcing it to try to answer a question that was asked in the wrong way. But you also have to be specific enough to get an answer that is helpful.
  • Overall Amazon Q Developer was an incredibly useful tool that solved problems and taught me a few new frontend tricks that I would have needed to spend a long time researching to figure out!
In the coming months I plan to share more highlights of my journey developing a generative AI game while using generative AI to help me write the code. Let me know if you have any questions, tips, or general comments!
 

Any opinions in this post are those of the individual author and may not reflect the opinions of AWS.

Comments