Golang and Atari Pong

Golang game development, a DDD oriented approach

A quick description of how I structured a simple Atari Pong game using a DDD approach.

Atari Ping Pong screenshot


A good exercise I always set myself to is to think of the domain as of what the purposes of our system is, technology agnostic-wise.

  • Two Paddles
  • A ScoreBoard
type Game struct { 
PaddleLeft Paddle // Left Paddle
PaddleRight Paddle // Right Paddle
Ball Ball // Ball
ScoreBoard ScoreBoard // ScoreBoard
// Ball Represents the ping pong ball
type Ball struct {
pos Position // X and Y position
radius float32 // Radius
vel Velocity // X and Y velocity
type Paddle struct {
pos Position // X and Y position
size Size // height and width
ySpeed float32 // Y velocity
type ScoreBoard struct{
lPos Position // Left Score X and Y Position
rPos Position // Rigth Score X and Y Position
Left int // Current Left Score
Right int // Current Right Score
MaxScore int // Max Score

Entity Interactions

  • Ball trajectory has to be altered when colliding with a Paddle.
  • Ball has to be repositioned on the center when colliding to any horizontal end of the screen, or so-called Score.
  • ScoreBoard must increment either left or right when Score.
  • The Ball must be recentered when Score.
  • Game must reset when either left or right of ScoreBoard reaches MaxScore, so-called GameOver.
  • Paddle must move vertically when the player presses Up or Down.
type ScoreEvent struct {Left  boolRight bool}type ScoreDispatcher interface {Dispatch(ScoreEvent)AddListener(ScoreListener)}type ScoreListener interface {OnScore(ScoreEvent)}

User Input

For now, we know how the entities will interact amongst themselves, but we are still left with the question of how the Player interacts with its Paddle.

// KeyboardEvent Representation of a user input on a keyboardtype KeyboardEvent struct {Keydown uint8Key     Key}type Key intconst (ArrowUp Key = iota // representation of Arrow Up keyArrowDown // representation of Arrow Down key)type KeyboardDispatcher interface {Dispatch(domain.KeyboardEvent)AddListener(domain.KeyBoardListener)}type KeyBoardListener interface {OnKeyBoard(KeyboardEvent)}

Let it Run!

Now we know how every part will interchange its information to make the game get to an end state, but how does it MOVE?

type GameLoop interface {RunFrame(delta float32)
GetStatus() Status
type Status int
const (Start Status = iotaPlayingGameOver)

Software Developer at BTG Pactual Digital.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store