Game Engine written in Go and Phaser.js to support MMORTS-like games
go get -u github.com/nsf/termbox-go
go get github.com/go-redis/redis
go get -u github.com/tinylib/msgp
go run new_world/new_world.go
- flushes the db and regenerate the map
go run spawn_coins/spawn_coins.go
- spawns coin (optional)
to run the debugger backend / terminal client:
go run terminal_client/terminal_client.go
- set the Id of player then run this
or run the websockets server to communicate with the front-end
go run websocket_server/websocket_server.go
Tests in back-end are intended to be run individually for the time being. For now, we are only using tests to debug and print
usages of functions as we 'test-drive' the development of them. In the future, as things become more solidified, we may add actual tests assertions.
For now they are just debugging / printing results of functions. Tests within their respective packages are intended to be more white-box / unit like whereas
tests under tests under tests/
are black-box integration-like tests. https://stackoverflow.com/questions/19998250/proper-package-naming-for-testing-with-the-go-language
Eg.
go test cell/cell_test.go -v
or
go test tests/loader_and_saver_test.go -v
or for the entire test suite:
go test ./...
Game client using Phaser.js
install yarn
yarn install
yarn run assets
mmo 'rts-like'
grid / cell based ('infinitely' scales)
interact and build
persistent
sandbox
pvp
pve
exploration
generative world
emphasis for the origin on the world, 0,0
a player has their origin
each player is given an origin that is further out from 0,0 (spiral-like)
a player can change their origin (but only further out)
players can collect resources
player can use resource to build
players can build things to defend, attack, and gain more resources
the game encourage collaborating but their is no built in collabortive features
the player can die and respawn
some buildings can be destroy by player or npc (maybe some don't)
some buildings must be safely disconnect or to be protected
more costly in resources, can be better protected (walls)
- macro control / no micro control
- players buildings can spawn npcs to go and collect resources for them
- players buildings can spawn npcs to attack other players and npcs
- defence has the advantage in terms of protecting your base
- packing everything up into 'you box'
- unpack, and pack timeouts
- logging out puts everything into an undestroyable box, with you gamertag on it
- handle lossed connection during packing out phase
- Web sockets
- open source rendering library possible web based / browser based (not)
what happens to your stuff (resources building etc) when you die or log off: see logging out section
- minecraft
- starcraft
- warcraft 2
- osrs
- factorio
- logging advantages / consistent action consumption advantages
- lock the minimal resources and most granual
- lock and unlock in deterministic order (implicit game logic)
- later on: timeout locking
- needs to have a failure state (client as well)
- Should the player be on a vector / floating point and not an integer grid?
- Use redis cluster over redis server. How do we handle event consistency with redis cluster? And handle 'dropped events'?
- How do we handle distributed locking?
- Use kubernetes to deploy backend services. Where there is a service for different aspects of the game, spawnCoins.go, spawnSnakes.go, variousNpcs.go, websocketServer.go etc.
- Object Design - Player
- cell w/ mutex not subworld
- coin, building wall (2x1)
- HP
- player limited view
- storing state in redis DB
- remove subworlds and grids
- convert data store to json
- create rocks on board
- collision detection from rocks
- Accept state from stubbed websockets
- Override state from stubbed websockets
- move camera and get new state
- add in coin
- send player move over stubbed websockets
- receive state from websockets
- emit event for movement over websockets
- websockets
Architecutre diagram: https://docs.google.com/drawings/d/1KoQpRLkz38vh3UNjf-xKUZWU0z8rbUOcvMJSpSRLSiQ/edit?usp=sharing
- Gracefully handle websockets disconnect
- Use uuid for ids
- Separate objects and paint
- introduce struct like 'cell' which contains objects and paint
- Add loader and saver services
- Add items layer for items on the ground
- Implement player as object remove coin as object
- Add event system: player object id based event channels in redis pub/sub when event happens, propagates to all player channels around the event
- Fix event system bug where emitter and receiver are not being de-serialized correctly. Fixed, now we use objectId instead
- move things from el into obj. remove old els. rename el package to factory or something
- Can we remove setting type in the loaders? investigate this, run tests etc.
- break apart basic.go into various files / packages for spawn coin and player interactions / actor movement
- Re-work movement system, introduce velocity.
- Backend velocity regulator
- Velocity config
- Parse velocity config to backend velocity package
- Parse velocity config on front end
- Use velocities on front end
- Fix issue where move events are not sent as vectors and player 'skips / jumps over' coins
- Add in terrain, grass, sand, mud
- Backend
- Front end
- Dynamically generated map
- Store what portions of the world have been generated
- Detect 'world generation' within generate world detection vision distance, kick off generate world job via redis channel
- generate world executable listening to redis-channel
- generate world job
- shuffle all coords
- loop through coords and assign 'fill' based on probability of neighbors
- Re-spawn, and setting origin
- Attacking / defending
- Picking up items / resources
- Building / spending resources
- Multi player
- Logging out, boxing up all your buildings