boardgame.io icon indicating copy to clipboard operation
boardgame.io copied to clipboard

POST 413 Error when creating a new match and passing in large amounts of setupData

Open mxgordon opened this issue 3 years ago • 3 comments

My game creates a huge amount of data to make the board (lots of points and shapes for different tiles and such) and passes it in as setupData when creating the game, I'm 99% sure this is a bug with boardgame.io that it's not able to accept such large POST requests. Is there a way to fix it? Is it an integral part of the system? It only takes 1.75 MB to make it fail. This makes it fail.

mxgordon avatar Dec 06 '20 04:12 mxgordon

We use koa-body to parse the body of POST requests, which defaults to a 1MB JSON size limit (source). Currently we use koa-body with no configuration in the Lobby API. For example, when creating a game:

https://github.com/boardgameio/boardgame.io/blob/43ade96d93f91dc70cbb4104b1cded21be13c200/src/server/api.ts#L114

In theory, we could add an option allowing some customisation there if you’d be interested in making a PR?

Also, bear in mind that your game state gets sent to clients for every game action, so if it is this large, you may see a performance hit. Is there any of this data that is static across game instances? For example, say a player chooses from a number of fixed maps, instead of passing the full map data to setupData, you could pass a mapID and have the full map data as part of your bundle. Of course that’s not possible if every bit of this data is dynamic, but seeing colours etc. in your example data it might be worth seeing if you can separate out static from dynamic data to reduce the state size.

Here’s a small illustration:

// Static game data. Imagine the values are much larger.
const staticData = {
  a: { colour: 'blue', n: 4 },
  b: { colour: 'red', n: 122 },
  c: { colour: 'yellow', n: -5 },
};

const game = {
  setup: (ctx, setupData = {}) => {
    const dataID = setupData.dataID || 'a';
    const data = staticData[dataID];
    // Use static data without sending it all over the network.
    // ...
    return { dataID };
  },
  
  // Same applies in moves potentially.
  moves: {
    A: (G, ctx) => {
      const data = staticData[G.dataID];
      // Use static data by just storing a reference ID in G.
    }
  },
};

On the client you can do the same:

import { staticData } from './static-data';

const Board = ({ G }) => {
  const data = staticData[G.dataID];
  return data.colour;
}

delucis avatar Dec 06 '20 11:12 delucis

Yeah, so static game data could definitely work, although wouldn't be ideal. On the other hand, customization for the POST body limit would be nice and other people might appreciate it too. Although it will take me a bit to get a PR ready as I'm fairly busy, but I think I'll definitely look into it!

mxgordon avatar Dec 06 '20 23:12 mxgordon

If your really need dynamic map, please also give a look at this issue. https://github.com/boardgameio/boardgame.io/issues/757

larry801 avatar Dec 07 '20 11:12 larry801