Rails is an authoritative server running chipmunk physics in one thread. Regular updates about state are delivered on another. SuckerPunch gem used for background processing of the physics.
bundle install
rails db:create
cd client
npm install
npm run build
cd ..
rails s
There are 3 threads going on
- Regular rails handling players joining and leaving and delivering the front end assets. Also Rails ActionCable(fancy name for websockets) with five messages currently:
- subscribed (the client has successfully websocket handshaked)
- join (now that they are subscribed, the client wishes to join the game)
- unsubscribed ( the client closed their connection, remove them from the game )
- inputUpdate ( the client changed their inputs )
- event (wip the client initiated an event )
- SuckerPunch job running every 0.045 seconds updating the client over the websocket connection about the state of themselves and all other players Think about not broadcasting to everyone and only sending state information to each client about things that are close enough to them to see or affect them.
- SuckerPunch job running every 0.03 seconds stepping the Chipmunk physics simulation forward the same amount of time.
Players input state is sent through the socket, causing their representation on the server to have the same input state. Thread number three above constantly looking at the state of their server representation's inputs which equates to some force(impulse) being applied to them in the next simulation step. Thread two constantly just sending out the latest simulation state for each player. {position, id, lastInputState} right now
Each player has both a Ghost and Player representation on the frontend. (Player's sprite/position is what draws) Ghosts are updated to the absolute position of what the server says their new position is. The Player object interpolates to the Ghost to smooth things out.
Maps are created using Tiled.
- Collision areas Draw a poly shape anywhere you want there to be a collision area for players such as walls or floors. Maps are loaded on the frontend for the visual as well as the backend which itterates through the poly shapes and makes static objects in Chipmunk for collision.
TODO: ( Cover player animations to start )
-
Events - In Progress (will allow effects and sounds and stuff and users doing 'actions' like picking up a potion or consuming it)
-
Client side prediction The Ghost/Player interpolation now is nice to smooth out time and network randomness between socket updates but ideally the player should begin moving (or whatever) the instant the input is pressed and when the server responds, rectify the difference with the player's Ghost smoothly, over time. The other players Ghost's should continue moving according to their last known inputs and rectify in the same way. This requires running (very nearly) the same physics simulation on both the frontend and backend, which I am not sure how to do.
- Consider ditching rails and use node backend with https://github.com/liabru/matter-js for frontend as well so physics match ?
-
Stress test with Thor
-
Investigate communicating with binary instead of utf-8
-
Persist the backend state through restarts and client reconnects.
- Players being able to load in different places/state depending on their last state before disconnecting(see #3 below).
- Players Inventory/Items in ActiveRecord/Postgres tied to a User Model and maybe has many Characters.
- Game state ('physical' state of all the players meaning position and things like health) recorded in a separate service/database that is also listening to all game updates ? Maybe saves every 30 seconds or so. This being able to recover where things left off from a hard crash. To point one above, when a player logs back in, look at their old state if it still applies to the current game and determine where and in what state to spawn them.
- I have a feeling using and obtaining items will need to be syncronized between both.
-
Come up with a name for this
If you find a bug or would like to request a new feature, open an issue. Your contributions are always welcome! Fork the project and Submit a pull request.