Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add default value to normalized game settings #39

Merged
merged 4 commits into from
Aug 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions games/game1-v2.3.0/game/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,10 @@ const gameSettings: GameSettings = [
key: "setting1",
options: [{ value: "a" }, { value: "b" }],
},
{ key: "setting2", options: [{ value: "x" }, { value: "y" }] },
{
key: "setting2",
options: [{ value: "x" }, { value: "y", isDefault: true }],
},
];

const gamePlayerSettings: GamePlayerSettings = [
Expand All @@ -157,7 +160,7 @@ const gamePlayerSettings: GamePlayerSettings = [
{
key: "dieNumFaces",
type: "string",
options: [{ value: "6" }, { value: "20" }],
options: [{ value: "6", isDefault: true }, { value: "20" }],
},
];

Expand Down
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"$schema": "node_modules/lerna/schemas/lerna-schema.json",
"version": "2.5.1",
"version": "2.5.2",
"npmClient": "pnpm"
}
1 change: 1 addition & 0 deletions packages/core/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Core library to make games at [lefun.fun](https://lefun.fun).
4 changes: 2 additions & 2 deletions packages/core/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@lefun/core",
"version": "2.5.1",
"description": "Core library to make games for https://lefun.fun",
"version": "2.5.2",
"description": "Core library to make games at https://lefun.fun",
"author": "Simon Lemieux",
"repository": {
"type": "git",
Expand Down
12 changes: 10 additions & 2 deletions packages/core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export type GameSetting = {
// * `previousMatchValue`
// * The first option `default: true`
// * The first option
// This logic si defined where we set `defaultValue`.
//
// If your implement this function, don't forget to return `previousMatchValue` when
// it is defined, if you want to keep that behaviour!
Expand All @@ -53,7 +54,14 @@ export type GameSettings = GameSetting[];

export type GameSettings_ = {
allIds: string[];
byId: Record<string, GameSetting>;
byId: Record<
string,
GameSetting & {
// We set this from the `isDefault` option if there is one.
// This avoids the need to loop through all the options to find it.
defaultValue: string;
}
>;
};

/*
Expand Down Expand Up @@ -104,7 +112,7 @@ export type GamePlayerSettings = GamePlayerSetting[];

export type GamePlayerSettings_ = {
allIds: string[];
byId: Record<string, GamePlayerSetting>;
byId: Record<string, GamePlayerSetting & { defaultValue: string }>;
};

export type GameStatType =
Expand Down
1 change: 1 addition & 0 deletions packages/dev-server/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Development server to help while developing games at [lefun.fun](https://lefun.com).
2 changes: 1 addition & 1 deletion packages/dev-server/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@lefun/dev-server",
"version": "2.5.1",
"version": "2.5.2",
"description": "Development server to run games developed for https://lefun.com.",
"author": "Simon Lemieux",
"repository": {
Expand Down
16 changes: 6 additions & 10 deletions packages/dev-server/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -295,9 +295,9 @@ function MatchSetting({
});
}}
>
{options.map(({ value }) => (
{options.map(({ value, isDefault }) => (
<option key={value} value={value}>
{value}
{value} {isDefault ? " (default)" : ""}
</option>
))}
</select>
Expand Down Expand Up @@ -372,9 +372,9 @@ function MatchPlayerSetting({
});
}}
>
{options.map(({ value }) => (
{options.map(({ value, isDefault }) => (
<option key={value} value={value}>
{value}
{value} {isDefault ? " (default)" : ""}
</option>
))}
</select>
Expand Down Expand Up @@ -796,12 +796,8 @@ const initMatch = ({
if (gameSettings) {
matchSettings = Object.fromEntries(
gameSettings.allIds.map((key) => {
for (const { value, isDefault } of gameSettings.byId[key].options) {
if (isDefault) {
return [key, value];
}
}
return [key, gameSettings.byId[key].options[0].value];
const defaultValue = gameSettings.byId[key].defaultValue;
return [key, defaultValue];
}),
);
}
Expand Down
1 change: 1 addition & 0 deletions packages/game/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Main dependency for writing game logic at [lefun.fun](https://lefun.fun).
2 changes: 1 addition & 1 deletion packages/game/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@lefun/game",
"version": "2.5.1",
"version": "2.5.2",
"description": "Main dependency for writing game logic at https://lefun.fun.",
"author": "Simon Lemieux",
"repository": {
Expand Down
36 changes: 34 additions & 2 deletions packages/game/src/gameDef.ts
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,36 @@ function normalizeStats(stats: GameStats | undefined): GameStats_ {
return stats_;
}

function normalizeSettings(settings: GameSettings): GameSettings_;
function normalizeSettings(settings: GamePlayerSettings): GamePlayerSettings_;
function normalizeSettings(settings: GameSettings | GamePlayerSettings) {
const newSettings = normalizeArray(settings, "key");

// Find the default values.
for (const key of newSettings.allIds) {
const gameSetting = newSettings.byId[key];

let defaultValue: string | null = null;
let numDefault = 0;

for (const { value, isDefault } of gameSetting.options) {
if (isDefault) {
defaultValue = value;
numDefault++;
}
}

if (numDefault > 1) {
throw new Error(`multiple default values for game setting ${key}`);
}

(gameSetting as any).defaultValue =
defaultValue ?? gameSetting.options[0].value;
}

return newSettings;
}

/*
* Parse a @lefun/game game definition into our internal game definition.
*/
Expand All @@ -489,8 +519,10 @@ export function parseGame<
>(game: Game<GS, PMT, BMT>): Game_<GS, PMT, BMT> {
const playerStats = normalizeStats(game.playerStats);
const matchStats = normalizeStats(game.matchStats);
const gameSettings = normalizeArray(game.gameSettings, "key");
const gamePlayerSettings = normalizeArray(game.gamePlayerSettings, "key");
const gameSettings =
game.gameSettings && normalizeSettings(game.gameSettings);
const gamePlayerSettings =
game.gamePlayerSettings && normalizeSettings(game.gamePlayerSettings);

return { ...game, playerStats, matchStats, gameSettings, gamePlayerSettings };
}
Expand Down
40 changes: 39 additions & 1 deletion packages/game/src/testing.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,44 @@ describe("turns", () => {
match.makeMove(userId, "go", {});
expect(match.board.expiresAt).toEqual(1000);
});

test("double begin turn: only the latest counts", () => {
type B = {
x: string;
};
type GS = GameState<B>;
const game = {
...gameBase,
initialBoards: () => ({ board: { x: "" } }),
playerMoves: {
add: {
executeNow({ board, payload }) {
board.x += payload.x;
},
} as PlayerMove<GS, { x: string }>,
begin: {
execute({ userId, payload, _ }) {
_.turns.begin(userId, {
expiresIn: 10,
playerMoveOnExpire: ["add", { x: payload.onExpire }],
});
},
} as PlayerMove<GS, { onExpire: string }>,
},
} satisfies Game<GS>;

const match = new MatchTester<GS, typeof game>({ game, numPlayers: 1 });
const userId = match.meta.players.allIds[0];
match.makeMove(userId, "begin", { onExpire: "a" });
expect(match.board.x).toBe("");
match.fastForward(10);
expect(match.board.x).toBe("a");

match.makeMove(userId, "begin", { onExpire: "b" });
match.makeMove(userId, "begin", { onExpire: "c" });
match.fastForward(20);
expect(match.board.x).toBe("ac");
});
});

describe("fastForward", () => {
Expand Down Expand Up @@ -345,7 +383,7 @@ test("end match ends turns", () => {
initialBoards: () => ({ board: { x: 0 } }),
playerMoves: {
go: {
execute({ userId, board, _ }) {
execute({ userId, _ }) {
_.turns.begin(userId);
_.endMatch();
},
Expand Down
3 changes: 2 additions & 1 deletion packages/game/src/testing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,8 @@ export class MatchTester<GS extends GameStateBase, G extends Game<GS>> {
}) {
for (const userId of beginTurnUsers) {
this.meta.players.byId[userId].itsYourTurn = true;
// Clear previous turn player moves for that player.
// Clear previous turn player moves for that player: in other words only the
// lastest `turns.begin` counts for a given player.
this.delayedMoves = this.delayedMoves.filter(
({ userId: otherUserId }) => otherUserId !== userId,
);
Expand Down
1 change: 1 addition & 0 deletions packages/ui-testing/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Utils for testing the UI of games at [lefun.fun](https://lefun.fun).
2 changes: 1 addition & 1 deletion packages/ui-testing/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@lefun/ui-testing",
"version": "2.5.1",
"version": "2.5.2",
"description": "Utils for testing the UI of games at https://lefun.fun.",
"author": "Simon Lemieux",
"repository": {
Expand Down
1 change: 1 addition & 0 deletions packages/ui/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Main dependency for writing the UI of games at [lefun.fun](https://lefun.com).
2 changes: 1 addition & 1 deletion packages/ui/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@lefun/ui",
"version": "2.5.1",
"version": "2.5.2",
"description": "Main dependency for writing the UI of games at https://lefun.com.",
"author": "Simon Lemieux",
"repository": {
Expand Down