Giter Site home page Giter Site logo

boardgameio / boardgame.io Goto Github PK

View Code? Open in Web Editor NEW
9.9K 9.9K 703.0 13.34 MB

State Management and Multiplayer Networking for Turn-Based Games

Home Page: https://boardgame.io

License: MIT License

CSS 0.24% JavaScript 3.34% Python 1.61% HTML 0.21% TypeScript 89.95% Svelte 4.55% Dockerfile 0.11%
boardgames game-engine javascript multiplayer react react-native tabletop turn-based

boardgame.io's People

Contributors

adngdb avatar amitport avatar arome avatar c-w avatar chrisheninger avatar darthfiddler avatar delucis avatar dependabot[bot] avatar evandroabukamel avatar fladrif avatar francoijs avatar jankir avatar jasonharrison avatar jimu avatar jorbascrumps avatar jstacoder avatar lehasvv2009 avatar nicolodavis avatar p00ya avatar philihp avatar pong420 avatar qsona avatar rgbknights avatar saeidalidadi avatar scally avatar shaoster avatar sladwig avatar stefan-hanke avatar tomasvidhall avatar vdfdev avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

boardgame.io's Issues

Tic-tac-toe demo counts subsequent clicks on filled cells as turns

It appears that either player's turn is skipped if they click on a filled cell. Debug sidebar shows turn increments. Looks like this is checked in https://github.com/google/boardgame.io/blob/master/examples/tic-tac-toe/tic-tac-toe.js#L81 so I'm not sure what's up.

Repro:

Result:

  • 0-0-0 in top row

Expected:

  • 0-1-0 in top row

npm package problem - node v6.10.1

I'm not sure if this is an error but npm package does not works on node v6.10.1. (windows 10)

And thank you for this awesome framework. 👍

11986 error Windows_NT 10.0.15063
11987 error argv "C:\\Program Files\\nodejs\\node.exe" "C:\\Program Files\\nodejs\\node_modules\\npm\\bin\\npm-cli.js" "install" "--save" "boardgame.io"
11988 error node v6.10.1
11989 error npm  v3.10.10
11990 error code ELIFECYCLE
11991 error [email protected] postinstall: `ln -s ../packages/node_modules/boardgame.io`
11991 error Exit status 1
11992 error Failed at the [email protected] postinstall script 'ln -s ../packages/node_modules/boardgame.io'.
11992 error Make sure you have the latest version of node.js and npm installed.
11992 error If you do, this is most likely a problem with the boardgame.io package,
11992 error not with npm itself.
11992 error Tell the author that this fails on your system:
11992 error     ln -s ../packages/node_modules/boardgame.io
11992 error You can get information on how to open an issue for this project with:
11992 error     npm bugs boardgame.io
11992 error Or if that isn't available, you can get their info via:
11992 error     npm owner ls boardgame.io
11992 error There is likely additional logging output above.
11993 verbose exit [ 1, true ]

Allow certain state to be marked as non-replicated

When dealing with multiplayer games, it may be wise to allow a developer to mark certain state as "client-specific". An example of this could be something like a game of Battleship where, while multiplayer, the only party with full knowledge of the state should be the server.

While you can just use code on the client to hide certain aspects of the state (such as only showing the client's own board), that leaves the game vulnerable to a knowledgeable player using the dev tools to peek into the state.

Not entirely sure what it might look like. Maybe something other than "G", which implies global state, or maybe a special key within "G" that is specific to the local client and the server (no other clients).

Thanks for making this library!

Add option in Client config to specify socket server

Currently you can only wire it to the same server that serves up the webpage.

An option like:

Client({
   game: TicTacToe,
   multiplayer: { server: 'hostname:port' },
})

would allow serving the page and game logic from different servers. Might also help the create-react-app users.

node-sass?

Noticed node-sass in the package.json file– yet I don't think we're using sass anywhere?

It's a pretty gnarly install– would be nice to chop it out (along with any other unused dependencies).

Storage

Games are currently held in an in-memory object, but should be persisted in either a MongoDB or Firebase instance. Options for other backends should also be possible.

TODO:

  • Mongo support
  • Firebase support
  • Postgres support

Grid system with (Hex) tile

Has anyone started working on the grid system yet? Mind if I give a go?

I am going to make a GridSystem component handling dimensions, coordinations and drag and drop, and also a dump HexTile component.

I haven't started yet so please feel free to let me know if anyone started working on this.

Cheers.

UI toolkit

Just tracking some ideas planned for the UI toolkit in https://github.com/google/boardgame.io/projects/5

PR's are welcome for items not yet claimed. I'll try to keep the items bite sized (implementable in an hour or less), but some may be larger, and will get broken down once they start getting worked on:

  • Generic token (that can be dragged and dropped)
  • Generic placeholder (that can receive draggables and fire events)
  • Cards (with drag-n-drop)
  • Deck (with events to shuffle, draw cards, insert cards etc.)
  • Hex grid, Grid (collections of placeholders with a co-ordinate system).

All components must be have usage examples in the storybook/ directory.

React Native?

This looks awesome! Has this been used in React native?

Feature Request: Define loser

Some games have both of winning condition and losing condition, but boardgame.io support winning condition only.

If game have only losing condition, developer can use victory condition to define loser.
Otherwise, may need implementation of new feature.

Random API

Dice, shuffling etc. all require randomness, but having impure reducers (using Math.random(), for example) breaks the ability to view earlier game states (and is an anti-pattern in Redux). We should use a seed in ctx (that's stripped away before sending it to the client) that is used to predictably generate random numbers.

Plan:

  • API to generate random numbers.
  • API for various die rolls.
  • API to shuffle an array.
  • Allow calling the Random API in flow code (only really supported in moves at the moment).

socket isolation

The current multiplayer code only works fine for a single 2-player game. Small improvements necessary to scale to more players and games:

  • More socket metadata - The multiplayer code must stop broadcasting state updates, but send individual updates to various connected sockets that must advertise whether they belong to a particular player.

  • Rooms / namespaces - State updates for a particular game must only go to clients connected to that particular game.

Visual Interactive Test Generator

Will be cool to have the following ability (when the Debug UI is enabled):

  • Play the game to a certain point.
  • Press a button (say r) to start capture (this snapshots G and ctx at this point).
  • Play a move (or a sequence of moves).
  • Press r again to stop (this captures the end state of G and ctx).

This generates a Jest test file that records exactly what happened that the game author can save to run the test again from the commandline (non-visually).

Phases

A declarative way to define different phases in a game:

  • Define which moves are permitted in the current phase.
  • Provide a function to customize how the turn gets passed around between players in each phase.
  • Option to specify if a phase is asynchronous (players may play out of turn).
  • Allow certain moves to happen automatically in a phase (executed by the board).
  • Option to end phase when all players have passed.
  • Add endTurnIf hook to allow a turn to automatically end when a condition is met.
  • Rename boardgame.io/game to boardgame.io/core, and expose TurnOrder etc. through it.
  • Remove init event and make it a Flow option.
  • Update documentation.
  • Code is being developed in the phases branch.
  • Checked items are completed.

Secret state?

I'm curious if you've thought about how to handle secret state like a deck to draw from and players hands? Perhaps using key pairs to encrypt/decrypt the state? For a deck, this would require a trusted server component that can decrypt, deal, and re-encrypt the deck state, but feels like an approach that works.

I planned on using such an approach for a game I wanted to make using Firebase but never got around to building the backend (though I have an old iOS Swift 2 code base for the prototype client using Game Centers old pass and play system). it was basically Leterpress with Poker hands, perhaps I'll try porting it to this time permitting (but it needs secret state, hence my question).

localStorages in multiplayer mode are in complete sync. How do I save different identity info?

I try to make the demo tic-tac-toe truly multiplayer, that is, you can only clickCell on your turn.
So I tried to save playerId in localStorage, only when currentPlayer equals playerId can you make a move.
But then I find the localStorage in different open tabs are in complete sync. So I wander what do I do, when I need localStorage to save unique information in different tabs.

BTW, node.js has no localStorage, but likely localStorage is part of game rules information, so does it matter if I pass a null function as localStorage into backend code?

Multiple actions in handler not receiving updated state

I have a click handler that conditionally executes multiple game moves since several may be triggered by a player action. However, I see that the component props are not updated until after my callback returns even though the game state is changed. Any way to work around this?

Example Not Synced

I pulled the latest version today, and it seems that the example tic-tac-toe is not synced across multiple tabs open on local host. I don't think I had this issue with the version last week.

Edit: Seems to work sometimes and other times not. I cannot find the reason or how to reproduce this issue.

Option to Setup initial state (G) as a function

Feature request that G takes into account meta data like numPlayer.

Currently it seems no way to initialize G with ctx as argument.

How about allowing G accept function that returns an object.

// so instead of
G: {  numberOfPieces:  20 }
// we can do
G: (ctx) => ({ numberOfPieces: ctx.numPlayer * 10 })

A "board/dealer" player

Some moves need to be executed by the board itself (either for clean up or setting up state). This should work seamlessly across single player and multiplayer modes.

In multiplayer mode, the board logic should execute only on the server.

Prettier

Curious if you would accept a PR implementing prettier in the project. If you haven't heard of it, you can learn more here: https://prettier.io/docs/en/why-prettier.html

I use it on every project I set up– it's nice because once configured it stays out of your way completely and ensures consistency throughout the codebase. One of the biggest perks is that it helps resolve merge conflicts much easier– you'll never have conflicts over things like people's editors changing trailing commas, whitespace, etc.

Error when installing package

I got this installation error.

command

npm install --save boardgame.io

log

npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] postinstall: `ln -s ../packages node_modules/boardgame.io`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the [email protected] postinstall script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

Env

node.js 8.9.3
Linux Ubuntu 16.0.4

turn based with a timer (maybe take into account in "phases")

Not sure if games like roguelikes & stretagy-rpg are part of this library's target cases.
If so, there are a key concept that made turn-based game a little bit real time:
there is a universal timer, and every action takes time, which result in:

  1. an action may take less or more than "a standard turn", so
  2. player gets to his/her turn faster or take multiple actions if "speed" is high.

The basic model is: there's actually no concept of "a turn" but only your turn. For example, attacking takes you 3 seconds, then your next turn will be reached after 3 seconds. If nobody gets their turn by that time, you get to take another turn right after.

The way I think: you endTurn after every action, but which one is the next player depends a "timer". Notice you are working on "phases", so just pop this idea.

btw, I wrote a Chinese checkers, maybe it can help with showcase or demo. (but the winner condition seems not working, not sure if "vitory" is a feature beyond 0.14)

btw, can there be example for using boardgame.io with react-redux? Only the top level component receive G,moves,ctx as props. It is inevitable when project gets bigger, we'd love to get access to G,moves,ctx for every component.

Ideas Thread

Didn't see an "Ideas" thread for those of us who are not contributors to the project, so perhaps this can be a place for people to drop in ideas not currently on the Ideas Project Roadmap, and then someone could add them to the Roadmap if they think it's a good idea? I'll start off with a couple of ideas in comments.

State changes that require secret data

Hi there!

First, let me just say that this project is really exciting - love the activity and where this is heading. Great work!

I'm working on a variation of the "battleship" game type - choose a secret layout, then guess the opponent's layout. This is working nicely for multiplayer: false with the 'phases' feature, and a move reducer that checks the opponents secret layout.

Today, I implemented the new PlayerView.STRIP_SECRETS player view, but I'm running into some issues:

  • The active player cannot compute the next state without secrets
  • The socket server does not inform the "moving player" of the "official" state change.

This seems somewhat similar to the 'randomness' work being done (storing a secret RNG seed for dice rolls, etc). For a simple "roll and advance [DICE] spaces" move, the outcome of a roll must be shared with the clients. Similarly, a battleship (x, y) guess must be reported as a HIT or MISS.

Just wanted to start the discussion. Let me know if this belongs somewhere else, or if I'm missing something.

Option brainstorm:

  • 2-stage move: e.g. Request 3 dice rolls from server, record in a gameEvent, then use outcome in next action
  • incomplete move: If we are a multiplayer client, submit move arguments, and then sync real state from server
  • transformed arguments: client performs moveSpaces(Secret.DICE_ROLL), server transforms special argument into real value. Maybe this is the same as previous option..

Last turn not captured in log

Suggestions:

  • Also end the turn when endGameIf returns true.
    OR
  • Make GameLog add an entry on gameover in addition to the turn end.

Solitaire game with others watching over websockets?

Hi, I'm designing a board game for single-player.

I was wondering if it's possible with boardgame.io to create a proper game with number of players to equal 1? (right now I'm automatically skipping a turn of other players)

I'm also interested if I can use boardgame.io 's multiplayer mechanism for other players to join watching the solitaire game in real-time?

hook for endTurn

would be cool to be able to define a hook for when endTurn is called to clean up some state in between turns.

maybe im not approaching it correctly so feel free to tell if thats the case. A simple example would be having dice. if i store the current value of the dice in the game state, when the turn is over id like to be able to null out the current dice numbers so the UI knows its time to re-roll.

for now a workaround is to define my own move called endturn which updates the state and in the UI code calling both simultaneously

AI framework

It's almost possible to write a generic AI using the existing framework, but there are two problems:

  1. There's no way to enumerate legal moves. The ability to pass arbitrary arguments to the moves functions makes for some trouble here. Also the Tic Tac Toe example handles illegal moves by doing nothing, which is ergonomic, but the framework doesn't know it happened.
  2. The framework doesn't know when a turn ends. The separate move + end turn calls are nice to make it easy to create games where one player's turn is composed of multiple logical moves, but "can I end turn" and "do I have to end turn" are questions only the caller can answer right now.

SSR: Server-Side Rendering

Hello,

I'm currently trying to use boardgame.io together with next.js.
Because the Server part exports a Koa server, I went with this example to create a basic project:
https://github.com/zeit/next.js/tree/canary/examples/custom-server-koa

However, when I run the code, I get a window is not defined error.
So I did some research and it's of course because Next.js is SSR and the Client component requires window to be present. So I made it like this:

const App = Client({
    game: Game,
    multiplayer: true,
});

export default class Index extends React.Component {
    state = {
        isClient: false,
    };

    componentDidMount() {
        this.setState({
            isClient: true,
        });
    }

    render() {
        if (this.state.isClient) {
            return <App />;
        }

        return 'Loading...';
    }
}

According to next.js, the client side code only runs, after componentDidMount has been triggered, so obviously window should be available, but somehow it isn't. Something inside Client seems to run before that happens.

domain name

Hello! I'm the current registrant of the boardgame.io domain. I had grand plans of doing something vaguely similar to this a couple years ago, but it went the way most ideas do... 🚮

The domain is yours, if you want.

--mark

Automatic Secret State

Would be nice to have some conventions that tell the framework to automatically strip out data from G before sending data to a particular client. The current mechanism involves having to implement playerView as documented here.

We could bundle in an (opt-in) implementation of playerView that does the following:

  • Drop fields with a key secret.
  • When there exists an object called players, drop all the keys from it that aren't playerID (i.e. each player only receives their slice of that object).
players: {
  '0': ...
  '1': ...
  '2': ...
}

becomes

players: {
  '1': ...
}

for player 1.

Demo without game logic

Any thoughts about creating a demo which doesn't enforce any game logic? I'm essentially imagining a playground-style app which provides non-programmers the tools to create custom assets (cards, tokens, background images for boards) to form a library for a game. The app then is only responsible for synchronizing gamestate, both public and private (as per #16), as well as a few generic actions (token placement/movement, stacking cards to form a deck, shuffling of deck, dice rolls, etc.). Clearly without enforcing game logic there is nothing to prevent cheating. The hope is to model playing board games in real life, where the players themselves are the enforcers of game logic.

Google is using react HAHA

HAHAHAHAAHAHAHAAHAHAHAHAHAHAAHAHAHAAHAHAHAHAHAHAAHAHAHAAHAHAHAHAHAHAAHAHAHAAHAHAHAHAHAHAAHAHAHAAHAHAHAHAHAHAAHAHAHAAHAHAHAHAHAHAAHAHAHAAHAHAHAHAHAHAAHAHAHAAHAHAHAHAHAHAAHAHAHAAHAHAHAHAHAHAAHAHAHAAHAHAHAHAHAHAAHAHAHAAHAHAHAHAHAHAAHAHAHAAHAHAHAHAHAHAAHAHAHAAHAHAHAHAHAHAAHAHAHAAHAHAHAHAHAHAAHAHAHAAHAHAHAHAHAHAAHAHAHAAHAHAHAHAHAHAAHAHAHAAHAHA :) :D

Proper way to sort out the next `currentPlayer` when turn ended?

the current player should be a function of ctx and game so it opens up the flexibility to sort out the next current player for different game.

For example:
UNO: reverse card, skip card
Poker: cards have been folded

const getCurrentPlayer = (ctx, game) => {
  let nextPlayerIndex = (+ctx.currentPlayer + 1) % ctx.numPlayers + "";

  while (nextPlayerIndex !== ctx.currentPlayer) {
    const { status } = game.players[nextPlayerIndex];

    // to check next player state
    // it implies all related player state changes should be done
    // in the previous action move
    if (!status.skipped && !status.banned && !status.folded) {
      return nextPlayerIndex;
    }

    nextPlayerIndex = (+nextPlayerIndex + 1) % ctx.numPlayers + "";
  }

  return nextPlayerIndex;
};
// src/core/reduce.js
export function createGameReducer({game, numPlayers, getCurrentPlayer}) {
...
...
    // Update current player.
    const currentPlayer = getCurrentPlayer ? getCurrentPlayer(ctx, game) :
      (+ctx.currentPlayer + 1) % ctx.numPlayers + "";
...
...

This is the brief idea about the getCurrentPlayer function.

It will be even better to integrate with reselect that allows to provide getters/selectors from store.

Any feedback is welcome! Thank you for your time to read through.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.