go-man api

32
go-man API Learning go-lang & writing a game

Upload: rob-baines

Post on 01-Jul-2015

2.951 views

Category:

Technology


0 download

DESCRIPTION

Learning go-lang and writing a multi player API based game

TRANSCRIPT

Page 1: go-man API

go-man APILearning go-lang & writing a game

Page 2: go-man API

Why?

By day: I am architect/developer hacking

at Java based api’s

By night: Still harboring a passion for

video games and regularly write small

games to try out new tech on my daily

commute (rarely finish them…)

Page 3: go-man API

Fusion

Why not combine both pursuits to retain a

level of interest?

Goals:-

Better understanding of go-lang

Maybe and actual finished skunkworks

project?

Page 4: go-man API

Dissecting the game

Broke the idea of “pac-man” down to a

series of API calls.

Create game

Add player(s)

Move players

Repeat to fade

Page 5: go-man API

Concurrency

Lightbulb moment!

Multiple players in same game =

concurrency

Page 6: go-man API

Parallelism

Multiple games in single server =

parallelism

Page 7: go-man API

Caveats

Probably not the best way to do this

First golang code I’ve developed

Highly inefficient

Websockets would’ve been MUCH better

BUT, it’s fun to try it

Page 8: go-man API

Starting the game

HTTP POST request to create a new game with following parms:-

Game name

Max number of GoMen

Max number of GoGhosts

Time to wait for players

What happens?

Creates new game on server

Creates golang process waiting for timeout to start game.

Creates a single channel to listen for player updates

Page 9: go-man API

Add players to game

HTTP PUT request to add a player to a

game with parms:-

Game id

Player name

Player type (GoMan/GoGhost)

If total players reached game will begin

otherwise game waits for players

Page 10: go-man API

Time up

If wait time expires, game server adds remaining players as CPU controlled players.

Creates new golang process for each missing player

Dumb AI:

Wait for ¼ second.

Pick random number between 0-3

Send move request to game channel

repeat…

Page 11: go-man API

Game States

“new” – just created

“waiting” – waiting for players to join

“playing” – game active

“over” – all GoMan players have died

“won” – all pills eaten

Page 12: go-man API

Power Pills

If a player eats a power pill a separate

golang process is submitted that waits for

duration of pill. At end of timer game reverts

to normal.

Page 13: go-man API

Game Client

Originally I started developing a separate

client in go-lang.

Stopped development of this because I

wanted people to try the game easily on the

web.

Switched to JavaScript based client as this

was the most likely client to consume the

API.

Page 14: go-man API

Game Client - technology

HTML5 + JavaScript

Twitter bootstrap

HTML5 canvas

Ajax calls to RESTful API

Page 15: go-man API

Game Client - features

List games

Create new game

Join existing game

Play game

Page 16: go-man API

Game Server

Server implements MVC pattern:

Models = game board + players

View = JSON representation of game state

Controller = RESTful API calls to perform

CRUD on a game instance.

Page 17: go-man API

Game Server - technology

Standalone golang executable or

Google app engine app

Uses:

Gorillamux (for http routing)

Game state stored in memory

Page 18: go-man API

Game Server – lessons learned

Things I learned during development:-

Started using filesystem as simple datastore for games. Got tired of serialisation / deserialisation and realised it was unnecessary for my simple demo.

Originally modeled board cells as a 2d byte array. But these force client to have to deal with Base64 encoded binary data (nasty). Changed definition to a 2d array of “runes” for an easier life.

BoardCells [][]rune

Page 19: go-man API

Game Server – logic

All game logic resides on server. Game state / player state etc.

Game clients are completely dumb.

Weakness in API is that players are not authenticated so they could easily fake each others moves by using the other player’s GUID.

Page 20: go-man API

Game Server – concurrency

Game controller writes PlayerMoverequests to a single channel (one per game)

This prevents concurrent updates to same board (two players eaten same pill etc.)

PlayerMove request includes a unique response channel, to return response back to original requester

Page 21: go-man API

Game Server – concurrent requests

move me

Game

request

channel

Players can be either remote web players

or local CPU controlled players on server

Page 22: go-man API

Game Server – concurrent responses

Players receive a new instance of the

Game board after their move

Bad move

Page 23: go-man API

Game Server – stats

golang is FAST!

Normal game 1 goman & 4 goghosts runs in browser @ 60fps

5 x 60 (300) requests per second. Average 3k per response. 1MB per sec traffic.

Running locally it is handled with ease 80+ players in a single game

DO NOT PLAY ON MOBILE PHONE WITH DATA CONTRACT!!!

Page 24: go-man API

Game Models - GameBoardtype GameBoard struct {

Id string

Name string

PillsRemaining int

Players map[string]*Player

MaxGoMenAllowed int

MaxGoGhostsAllowed int

WaitForPlayersSeconds int

State GameState

PowerPillsActive int

CreatedTime time.Time

LastUpdatedTime time.Time

GameStartTime time.Time

BoardCells [][]rune

}

Page 25: go-man API

Game Models - Player

type Player struct {

Location Point

Id string

Type PlayerType

State PlayerState

Name string

cpuControlled bool

Score int

Lives int

}

Page 26: go-man API

Game Models - GameState

const (

NewGame GameState = "new"

WaitingForPlayers = "waiting"

PlayingGame = "playing"

GameWon = "won"

GameOver = "over"

)

Page 27: go-man API

Game Models - PlayerState

const (

Alive PlayerState = "alive"

Dying = "dying"

Dead = "dead"

Spawning = "spawning"

)

Page 28: go-man API

Game Models - PlayerMove

Request interfacetype PlayerMove struct {

GameId string

PlayerToMove Player

ResponseChannel chan (PlayerMoveResponse)

}

Response interfacetype PlayerMoveResponse struct {

Board GameBoard

Error error

}

Response written back to channel passed in request

Page 29: go-man API

ASCII Client

Page 30: go-man API

HTML5 Canvas Client

Page 31: go-man API

Demo

Client: http://go-man-client.herokuapp.com/

(Hosted as simple static site)

Source: https://github.com/telecoda/go-man-javascript-client

API: http://go-man-app.appspot.com

(Hosted on single GAE instance)

Source: https://github.com/telecoda/go-man-app

Wiki: https://github.com/telecoda/go-man-app/wiki