INFO 441 Final Project
Amelia Shull & Kateka Seth
API: https://snakeapi.katekaseth.me
Client: https://retrosnake.me
Welcome to Retro Snake! You can play single, or two-person snake games. Our game is a positive distraction for college students who need short breaks from long study hours. Our target audience is mainly students, though anyone who experiences boredom can benefit from our game. This game is a positive distraction and not a hindrance because of its simple nature. Users must be actively engaged to succeed in snake, but it’s not interesting enough for long gameplay.
Sign in or create an account to play multi-player and save scores. You don't need an account to play single player. When you start the game, your snake is red, opponent's is black, and the food is periwinkle. Use the arrow keys to move, and eat the food to increase your score. But don't run into the walls, your opponent, or even yourself! Losing and winning isn't dependent on score, but rather if you or your opponent dies. Check the leaderboard on the scores tab to see the top scores. You can log out of your account on the profile tab. Have fun!
-
POST /scores
: adds user's score to database-
Request body:
{ score: (score), userID: (userID) }
-
Responses:
200
: score added successfully400
: Can't insert to store401
: User not authenticated, User not authorized, Origin not authorized405
: Method must be POST415
: Request body must be in JSON, Request is nil500
: Error adding score, Decoding failed
-
-
GET /scores/
: gets top 10 (default) scores of all players- Parameters:
?top=n
: encodes the top n scores
- Responses:
200
: (Successfully returns scores)400
: Bad url, Bad number405
: Method must be GET500
: Error getting scores
- Request origin:
- Must be from https://retrosnake.me
- Request body:
[ { score: (score), userID: (userID), created: (datetime) }, ]
- Parameters:
-
GET /scores/{userID}
: gets all scores of specific player- Parameters:
?top=n
: encodes the top n scores?recent=n
: encodes n most recent scores
- Responses:
200
: (Successfully returns scores)400
: Bad url, Bad number, Bad user id405
: Method must be GET500
: Error getting scores
- Request body:
[ { score: (score), userID: (userID), created: (datetime) }, ]
- Parameters:
-
POST /users
: creates new user accounts and begins a new session- Request body:
{ userName: (userName), password: (password), passwordConf: (password typed again) }
- Response body:
{ userID: (userID), userName: (userName) }
- Response headers:
Authorization
: bearer token for the session
- Responses:
201
: (Successfully creates user and begins new session)400
: Invalid new user405
: Method must be POST409
: Can't insert to store, Error beginning a session415
: Request body must be in JSON, Request is nil500
: Decoding failed, Internal server error
- Request body:
-
POST /sessions
: begins a new session for user- Request body:
{ password: (password), userName: (userName) }
- Response body:
{ userID: (userID), userName: (userName) }
- Response headers:
Authorization
: bearer token for the session
- Responses:
201
: (Session successfully started)401
: Invalid credentials405
: Method must be POST409
: Error beginning a session415
: Request body not in JSON, Request is nil500
: Decoding failed, Internal server error
- Request body:
-
DELETE /sessions/
: deletes the session- Request headers:
Authorization
: bearer token for the session
- Responses:
200
: signed out403
: User not authenticated405
: Method must be DELETE409
: Error ending session
- Request headers:
-
/
: upgrades connection to websocket- Request origin:
- Must be from https://retrosnake.me
- Responses:
500
: Cannot upgrade to websocket, Cannot read json
- Request origin:
Websocket will connect when the client joins the waiting room (game tab). The client sends the auth
token recieved from the /session
endpoint.
The client can then send the following data to the server through the websocket connection:
// Lets the server know to start the game or add the player
// to the waiting room
{
action: "startGame",
data: "single" | "multi",
userID: (userID)
}
// Lets the server know when the player makes a move
{
action: "sendMove",
data: "left" | "right" | "up" | "down"
}
The server sends the following data to the client:
{
status: "active" | "over",
players: [
{
body: [{(xCoord), (yCoord)}],
direction: "left" | "right" | "up" | "down",
score: (score)
userID: (userID)
}
],
food: {(xCoord), (yCoord)},
size: (size of pixels)
finalStatus: (userID of loser) | "tie" | ""
}
For a single player game, the players
array will only contain one element, for multi-player it would contain two. The body
array contains points representing the location of the player's snake, the 0 element being the head. The food
field contains a single point representing where the food is located.
The users
table stores all registered users. We chose to only store username and not email because we would never contact the user.
users |
---|
id int |
username varchar(255), unique |
passhash varchar(128) |
The scores
table stores all scores of a registered user. The scores.userID
links to users.id
of the users table.
scores |
---|
id int |
userId int, foreign key |
score int |
-
snake-server
- Port: 443
- Docker Network: server-net
- Description: This container is the main gateway for our API server.
-
user-store
- Port: 3306 (not published)
- Docker Network: server-net
- Description: This container is the SQL database which stores registered users and scores.
-
redisServer
- Port: 6379 (not published)
- Docker Network: server-net
- Description: This container is the redis store which contains user sessions.
-
client
- Port: 80, 443
- Docker Network: N/A
- Description: This container is our client-side react app.