There is currently a proposal to change the signature of moves that could benefit from some feedback from the community:
move: (G, ctx, ...args) => {},
move: ({ G, ctx }, ...args) => {},
The rationale for this change is that it is currently difficult to add new API's without polluting ctx. This causes difficulties in the codebase (resulting in ctx carrying API's like random or events in some contexts, but being a plain object in others).
Under the new proposal, all API's could just be added to the first arg passed to the move, so you would access the random API like this:
move: ({ G, ctx, random }, ...args) => {},
While this is a breaking change, compatibility can be ensured in the short term via a simple plugin that wraps incompatible moves:
fnWrap: (fn) => ({ G, ctx, ...api }, ...args) => {
const ctxWithAPI = { ...ctx, ...api };
return fn(G, ctxWithAPI, ...args);
},
That looks good to me. I like moving plugins outside of ctx, especially now that I had to take a look at how it is implemented under the hood. Having ctx be a plain object with a structure that does not vary seems like a very good thing to do (also, it will make it easier to document).
As for a backward incompatibility, that comes with the "beta" status of the engine, and I hope everyone using it is fine with that. It just needs to be made super clear. As a reference, I really like how create-react-app handles changelogs, it's really easy to see what you have to do when updating dependencies.
Maybe we could ship the compatibility plugin in code, but that might backfire, with people enabling the plugin and never actually doing the migration work, leading to a point where it's even more broken for them and harder to migrate. I think it would be good to show those 4 lines of code in the migration documentation, while enforcing that it should be a temporary solution and folks should migrate their move functions asap.
A few extra thoughts:
We should probably extend this to other values that are not strictly part of ctx — I can think of playerID for now — for consistency with the client.
Should we destructure the plugins or have an interface like { G, ctx, plugins }?
I'm in favor of destructuring plugins. We can add a check to prevent plugins from being named 'G' or 'ctx' if that's a concern.
+1 to also moving playerID out of ctx.
Most helpful comment
That looks good to me. I like moving plugins outside of
ctx, especially now that I had to take a look at how it is implemented under the hood. Havingctxbe a plain object with a structure that does not vary seems like a very good thing to do (also, it will make it easier to document).As for a backward incompatibility, that comes with the "beta" status of the engine, and I hope everyone using it is fine with that. It just needs to be made super clear. As a reference, I really like how create-react-app handles changelogs, it's really easy to see what you have to do when updating dependencies.
Maybe we could ship the compatibility plugin in code, but that might backfire, with people enabling the plugin and never actually doing the migration work, leading to a point where it's even more broken for them and harder to migrate. I think it would be good to show those 4 lines of code in the migration documentation, while enforcing that it should be a temporary solution and folks should migrate their move functions asap.