I wanted to see if I could create a multi-player game with React and Redux, using some stuff I wanted to try out for a while, like RxJS and Flow.
Any issues or ideas are welcome in the Github issues. I have no clear goal for this, so any improvements are welcome in PRs, also game-play. Feel free to fork and run your own instances, but please note this project is under the GNU General Public License v3.0.
This is still a bit awkward with some .sh files, because we need to copy some client files into the server, etc.
If you run your own server, you can choose to let this server register itself with a www.warx.io. Your server will then appear on all other servers that registered themselves with this 'hub'.
Running ./build.sh
will create a production ready version in the ./dist
folder. This will build both the server and client. To run it, run yarn start
from the ./dist
folder.
When running the server you can set these env vars:
ENV Variable | Description |
---|---|
HUB | The central hub to register your server with, your server will appear on all other servers registered this this hun. Default: http://www.warx.io |
ADDRESS | Your server's http(s) address, this is where players will be redirected to if they choose to join your server |
SERVER_NAME | The name of your game server that will appear on all server lists |
LOCATION | Geographical location, so players can join a server close to them. |
NUM_BOTS | Number of bots to start the server with. |
MAX_PLAYERS | Maximum number of players that can join your server. More than 10 doesn't run smoothly at the moment. |
More env vars will be added related to rules
- Create a heroku app and add the needed env vars to your app
- Build using
./build.sh
from the root project folder - Run
./heroku.sh
from the root project folder - Fill in your app name in the prompt
- Build using
./build.sh
to build to./dist
- Create an .env.production file and fill in the needed env vars
- From the dist folder
now --dotenv=./.env.production
- Set your now alias to the server name you chose in the env vars
Jest is used for unit tests. Run yarn test
in the root dir to run the
server tests or in the client dir to run the client tests.
CircleCI is configured to run the tests in this repository on every branch and master. Tests must pass on PRs before merging.
This project is split up in a Node Express server and a React.js client.
The server lives in the root dir, with the source in the server
dir.
The client lives in the client subdirectory. Shared code can be placed in
the client directory where the server can access it. Note: at the moment
this does not work correctly because of different babel configurations.
Each of these should be replacable with out touching other layers much. Ideally each layer should only touch the one below:
- client (see client architecture in client/README.md)
- www (http server)
- app (express)
- network messages (send and get messages, now socket.io, possibly plain websockets)
- messages-actions (network-state-glue: translates network messages to redux actions vice versa)
- game state (redux + redux-observable, possibly mobx or redux + sagas)
- data sources (not yet implemented)
The state folder is where the business logic lives. This is the largest layer and
is split up in several modules. Each module can export initial state, actions,
reducers, selectors and epics. These modules can be generated by using plop module
.
This application shares redux actions between server and client, actions can be marked as any of these:
- client-to-client actions (i.e. opening a panel)
- client-to-server actions (i.e. connect request, move request)
- server-to-client actions (i.e. new connection, player moved)
- server-to-server actions: update server state without directly sending to client(s)
Actions which are client-to-server or server-to-client will also be dispatched at its origin. This means actions must be unique between client and server. This should be tested somehow, possibly at runtime (todo).
- pro: the type is defined where the action is defined
- con: the types of actions are scattered across modules, it's not easy to see which actions will be sent to the client in one spot
- pro: it's easy to see which client-actions will be sent to the server and which server actions will be sent to the client in one spot
- con: needs a separate list of actions
- pro: separate client and server actions
- con: extra translation between messages and actions needed