
Build an arcade scrolling game in a day with generative AI
See how you can use AI coding assistants like Amazon Q Developer to build and deploy a simple online arcade scroller
This post was inspired by the AWS Game Builder Challenge. Create a game with AWS services of your choosing: all skill levels welcome!
>Generate a sprite sheet that has retro looking space asteroids of different designs on a white background. Use pixel art style when generating.
>Generate a sprite sheet that has retro looking space rocket of different designs on a white background. Use pixel art style when generating.
>Generate a lunar landscape background image for a scrolling game. Use pixel art style when generating.
>Generate a sprite sheet that has fuel cells, cute alien creatures, and jewels. Use pixel art style when generating.
Amazon Q Chat > I want to create some mp3 sound effects for a video game. What is the easiest way of doing this?
Amazon Q Chat > How can I generate sound effects using Polly that covert the words "ouch" and "nice" into mp3 files. Can you make the voice sounds fast.
Tip!! At this early stage of the design, tools like Amazon Q Developer are great for generating divergent ideas - things that you might not have thought about, tools or frameworks for example. You can then introduce convergent prompts to narrow down the information you have learned, and get a more specific and opinionated direction. This is the kind of prompt you might use:
Amazon Q Chat > I want to build an online arcade game that will be played in the browser. I want this to store high scores in a leaderboard that is hosted in the cloud. Can you suggest a good architecture and frameworks that might be a good starting point
1
2
3
├── audio - <audio files>
└── images
└── sprites - <game sprites in PNG format>
Amazon Q Chat /dev can you build a simple sideways scrolling game in NodeJS using the images in the images/sprites directory as sprites. The background scrolling graphic to be used is titan-lunar-background.png. The player should control the rocket ship which is the file titan-sprite-rockets.png. Hazards should randomly appear and be a selection of the sprites in the other image files.
Amazon Q Chat Can we update the code so that the longer the play is playing, the harder it gets. Start off easy and then slowly but gradually get harder - does not produce great guidance
Amazon Q Chat @workspace Can we update the code so that the longer the play is playing, the harder it gets. Start off easy and then slowly but gradually get harder -is much better
1
2
3
4
5
gameTime += 1/60; // Assuming 60 FPS
if (gameTime - lastDifficultyIncrease >= 5) { // Increase difficulty every 30 seconds
difficultyMultiplier += 0.1;
lastDifficultyIncrease = gameTime;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
// Generate hazards
if (Math.random() < 0.02 * difficultyMultiplier) {
let hazardType = Math.floor(Math.random() * 3);
let hazard = {
x: canvas.width,
y: Math.random() * (canvas.height - 50),
width: 50,
height: 50,
speed: (Math.random() * 3 + 1) * difficultyMultiplier,
type: hazardType
};
hazards.push(hazard);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function resetGame() {
player.x = 50;
player.y = 300;
player.vx = 0;
player.vy = 0;
hazards = [];
backgroundX = 0;
gameOver = false;
score = 0;
gameTime = 0;
difficultyMultiplier = 1;
lastDifficultyIncrease = 0;
keys = {};
hasPromptedForName = false;
}
Amazon Q Chat @workspace the current game logic in game.js allows the space ship to disappear at the bottom of the screen. update the code so that it if touches the bottom it counts as a collision
1
2
3
4
5
6
7
8
// Check for bottom collision
if (player.y + player.height > canvas.height) {
player.y = canvas.height - player.height;
if (!player.invulnerable) {
gameOver = true;
collisionSound.play();
}
}
Amazon Q Chat @workspace Can i update the code so that it keeps track of high scores. It should list the top 15 scores and list them on the screen before and after a game
Amazon Q Chat this code does not work properly. the second time you play the game, you are prompted many times to enter your name. can you fix
Amazon Q Chat This code never triggers the player to enter their name for their high score
Amazon Q Chat @workspace can you update the code so that you can only enter alpha numeric characters if you get on the leaderboard
Amazon Q Chat I want to build an online arcade game that will be played in the browser. I want to store high scores in a leaderboard that is hosted in the cloud. Can you suggest a good architecture and frameworks that might be a good starting point.
- creating a new backend service called app.js that will be used to manage the leaderboard
- updating the game code to use this service
- provide sample code to persist the leaderboard data (to Redis)
1
2
3
4
5
6
7
8
index.html
game.js
server.js
├── leaderboard (where the backend app.js code lives)
├── audio (audio files)
└── images
└── sprites (game sprites in PNG format)
Amazon Q Chat @workspace I want to use Valkey to store the leaderboard for this game (game.py) that runs in the browser. I do not want to run the code to store and read the leaderboard in the browser as I want to keep the credentials safe. How can i use Valkey ?
Running Valkey locally I am running a local Valkey instance locally using a docker file that Amazon Q generated for me and that I blogged about previously here. Once I have the code running locally it should be simple enough to move it to the Cloud.
Amazon Q Chat @workspace how do i configure CORS in app.js so that it only accepts requests from the domain game.sueiras.dev
1
2
3
4
5
// CORS configuration
const corsOptions = {
origin: 'https://game.sueiras.dev',
optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204
};
1
2
3
4
5
// CORS configuration
const corsOptions = {
origin: '*',
optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204
};
Amazon Q Chat If I want to also check for obscene or rude words entered for the leaderboard, what are my options?
Amazon Q Chat @workspace can you update app.js to add a new route that takes in an input of a name and then either passess or fails it agains profanity. Please use the @2toad/profanity library
Amazon Q Chat how would I use this function to catch inappropriate names in the following function
Amazon Q Chat can you update the game.js to remove the hard coded reference to the remote api and change it for an environment variable for the uri. I need this to work for a browser based javascript file
1
2
3
const CONFIG = {
API_URL: 'http://127.0.0.1:3001'
};
1
const API_URL = CONFIG.API_URL;
Amazon Q Chat @workspace is the best way of hosting this application on aws. I want to host the front end game on AWS Amplify, but want to know the best option for deploying the backend. The backend needs to connect to a Valkey cache, so I need options that work well with VPC connectivity. and what would be the best option for hosting the front end?
Amazon Q Chat Can you tell me how to provision a Valkey cache cluster using the aws cli. Provide me with the simplest setup as this is only a demo, using serverless if available
1
2
3
4
5
aws elasticache create-serverless-cache \
--serverless-cache-name demo-leaderboard \
--engine valkey \
--region eu-west-1 \
--subnet-ids "subnet-1, subnet-2"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{
"ServerlessCache": {
"ServerlessCacheName": "demo-leaderboard",
"Description": " ",
"CreateTime": "2024-10-25T20:57:19.622000+00:00",
"Status": "creating",
"Engine": "valkey",
"MajorEngineVersion": "7",
"SecurityGroupIds": [
"sg-0cdd21561dee418a7"
],
"ARN": "arn:aws:elasticache:eu-west-1:xxxxxxx:serverlesscache:my-valkey-serverless",
"SubnetIds": [
"subnet-1",
"subnet-2"
],
"SnapshotRetentionLimit": 0,
"DailySnapshotTime": "23:30"
}
}
Amazon Q Chat @workspace if I wanted to use app.js to connect to an ElastiCache Redis instance on AWS, how would I need to update the code
1
2
3
4
5
6
const client = new Valkey({
port: 6379,
host: 127.0.0.1,
username: 'default',
tls: true
});
Amazon Q Chat @workspace in the app.js can you add a health check route that always returns OK
1
2
3
4
// Add this new route for the health check
app.get('/health', (req, res) => {
res.status(200).send('OK');
});
Amazon Q Chat @workspace update app.js so that instead of using a hardcoded IP address to connect to a Valkey cache it uses an env variable
1
2
3
4
// Get Valkey server address from environment variable
const VALKEY_SERVER = process.env.VALKEY_SERVER || 'localhost:6379';
const [host, port] = VALKEY_SERVER.split(':');
const client = new Valkey(parseInt(port), host);
Amazon Q Chat @workspace can you update app.js so that it grabs the CORS origin from an environment variable
1
2
3
4
5
6
7
// Get CORS origin from environment variable, default to '*' if not set
const CORS_ORIGIN = process.env.CORS_ORIGIN || '*';
const corsOptions = {
origin: CORS_ORIGIN,
methods: ['GET', 'POST'],
optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204
};
Amazon Q Chat can you update the code so that both the username and tls are set via environment variables
1
2
3
4
5
6
7
8
9
// Get username and TLS setting from environment variables
const VALKEY_USERNAME = process.env.VALKEY_USERNAME || 'default';
const VALKEY_TLS = process.env.VALKEY_TLS === 'true';
const client = new Valkey({
port: parseInt(port),
host: host,
username: VALKEY_USERNAME,
tls: VALKEY_TLS
});
Amazon Q Chat @workspace I want to deploy the leaderboard directory (app.js and supporting files) to Amazon ECS. Can you guide me through the steps. I am using Node version v20.10.0
1
2
finch run -e VALKEY_SERVER=192.168.5.2:6379 -e CORS_ORIGIN="*" \
-e VALKEY_TLS=false -p 3001:3001 leaderboard-app
1
2
3
4
5
6
7
{"name":"ric","score":165},{"name":"hello","score":51},
{"name":"qwer","score":23},{"name":"help","score":23},
{"name":"pot","score":18},{"name":"qqqqqq","score":17},
{"name":"zaqwsx","score":13},{"name":"qqq","score":13},
{"name":"fff","score":10},{"name":"eee","score":10},
{"name":"qwe","score":8},{"name":"Anonymous","score":5},
{"name":"xxx","score":2}]
Amazon Q Chat I want to push this container image to Amazon ECR. Can you guide me through the steps.
1
2
3
4
5
6
aws ecr get-login-password --region eu-west-1 | finch login --username AWS \
--password-stdin 704533066374.dkr.ecr.eu-west-1.amazonaws.com
finch tag leaderboard-app:latest 704533066374.dkr.ecr.eu-west-1.amazonaws.com/leaderboard-app:1.0.0
finch push 704533066374.dkr.ecr.eu-west-1.amazonaws.com/leaderboard-app:1.0.0
Amazon Q Chat @workspace I want to deploy the leaderboard directory (app.js and supporting files) to Amazon ECS. Can you guide me through the steps.
1
2
3
4
5
6
7
2024-10-25T22:27:57.800Z [ioredis] Unhandled error event: Error: connect ETIMEDOUT
2024-10-25T22:27:57.800Z at Socket.<anonymous> (/usr/src/app/node_modules/iovalkey/built/Redis.js:170:41)
2024-10-25T22:27:57.800Z at Object.onceWrapper (node:events:628:28)
2024-10-25T22:27:57.800Z at Socket.emit (node:events:514:28)
2024-10-25T22:27:57.800Z at Socket._onTimeout (node:net:589:8)
2024-10-25T22:27:57.800Z at listOnTimeout (node:internal/timers:573:17)
2024-10-25T22:27:57.800Z at process.processTimers (node:internal/timers:514:7)
Amazon Q Chat when I try and access Elasticache Valkey from my ECS app.js I get timeouts - what might be the problem
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
async function addHighScore(name, score) {
try {
//const response = await fetch('http://127.0.0.1:3001/api/scores', {
const response = await fetch('http://54.170.151.17:3001/api/scores', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ name, score }),
});
if (!response.ok) {
throw new Error('Failed to add score');
}
console.log('Score added successfully');
} catch (error) {
console.error('Error adding high score:', error);
}
}
async function getTopScores() {
try {
//const response = await fetch('http://127.0.0.1:3001/api/scores');
const response = await fetch('http://54.170.151.17:3001/api/scores');
if (!response.ok) {
throw new Error('Failed to get scores');
}
const scores = await response.json();
//console.log('Top scores:', scores);
return scores;
} catch (error) {
console.error('Error getting top scores:', error);
return [];
}
}
Setting up Amazon Route 53 is something I have done many times so I did not need any help from Amazon Q this time. If you are new to setting up a hosted domain, and want to use this to make vending certificates easy, then Amazon Q can help walk you through the steps.
Amazon Q Chat I want to deploy the front end of this application via AWS Amplify - can you provide a step by step guide on how to do this
1
2
3
4
5
6
7
8
9
10
tree -d -L 2
├── ecs-deployment
├── game
│ ├── audio
│ ├── images
│ └── node_modules
├── leaderboard
│ └── node_modules
└── valkey
└── conf
Amazon Q Chat @workspace I want to deploy the game directory to AWS Amplify. The game file is game.js and there are supporting resources (audio, images, and config.js)
- create a new GitHub repo for the front end code (so everything under game)
- follow the guide that Amazon Q provided
- update the AWS Amplify configuration file which it tries to automatically create, but was not right. I ended up using a very simple one
1
2
3
4
5
6
7
8
9
10
version: 1
frontend:
phases:
build:
commands:
- echo "No build required"
artifacts:
baseDirectory: /
files:
- '**/*'
Amazon Q Chat @workspace how do i minify and obfuscate the game.js and config.js in the demo-game-amplify directory
Any opinions in this post are those of the individual author and may not reflect the opinions of AWS.