1
0
Fork 0

feat(chips): credit chip bank from non-card minigame XP

Each minigame action credits chipBank with chipsForXp on profile update, feeding the card-game buy-in pool.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
Jason Fraley 2026-09-14 15:38:26 -04:00
parent be1e120727
commit 4d9edb3dbe
5 changed files with 25 additions and 0 deletions

View file

@ -5,6 +5,7 @@ import { getPayload } from "payload";
import { emitGameEvent } from "@/utils/event-log/emit"; import { emitGameEvent } from "@/utils/event-log/emit";
import { EventTypes } from "@/utils/event-log/eventTypes"; import { EventTypes } from "@/utils/event-log/eventTypes";
import { broadcastToUser } from "@/lib/realtime/bus"; import { broadcastToUser } from "@/lib/realtime/bus";
import { chipsForXp } from "@/lib/minigames/chips";
interface ActionResult<T = undefined> { interface ActionResult<T = undefined> {
success: boolean; success: boolean;
@ -133,6 +134,7 @@ export async function submitEodResult(input: {
const progression = (profile.progression ?? {}) as { const progression = (profile.progression ?? {}) as {
xp?: unknown; xp?: unknown;
chipBank?: number | null;
minigames?: { minigames?: {
eodMinesweeper?: { eodMinesweeper?: {
gamesPlayed?: number; gamesPlayed?: number;
@ -172,6 +174,7 @@ export async function submitEodResult(input: {
const bestFlags = isBestRun ? input.flags : previousBestFlags; const bestFlags = isBestRun ? input.flags : previousBestFlags;
const { xp: _xp, ...progressionRest } = progression; const { xp: _xp, ...progressionRest } = progression;
const chipBank = Math.max(0, (progression.chipBank ?? 0) + chipsForXp(runXp));
await payload.update({ await payload.update({
collection: "profiles", collection: "profiles",
@ -179,6 +182,7 @@ export async function submitEodResult(input: {
data: { data: {
progression: { progression: {
...progressionRest, ...progressionRest,
chipBank,
minigames: { minigames: {
...(progressionRest.minigames ?? {}), ...(progressionRest.minigames ?? {}),
eodMinesweeper: { eodMinesweeper: {
@ -205,6 +209,7 @@ export async function submitEodResult(input: {
broadcastToUser("profile-update", Number(user.id), { broadcastToUser("profile-update", Number(user.id), {
reason: "xp", reason: "xp",
xpGained: runXp, xpGained: runXp,
chipBank,
profileId: profile.id, profileId: profile.id,
}); });

View file

@ -5,6 +5,7 @@ import { getPayload } from "payload";
import { emitGameEvent } from "@/utils/event-log/emit"; import { emitGameEvent } from "@/utils/event-log/emit";
import { EventTypes } from "@/utils/event-log/eventTypes"; import { EventTypes } from "@/utils/event-log/eventTypes";
import { broadcastToUser } from "@/lib/realtime/bus"; import { broadcastToUser } from "@/lib/realtime/bus";
import { chipsForXp } from "@/lib/minigames/chips";
interface ActionResult<T = undefined> { interface ActionResult<T = undefined> {
success: boolean; success: boolean;
@ -68,6 +69,7 @@ export async function submitFlappyScore(input: {
const progression = (profile.progression ?? {}) as { const progression = (profile.progression ?? {}) as {
xp?: unknown; xp?: unknown;
chipBank?: number | null;
minigames?: { minigames?: {
flappyBird?: { flappyBird?: {
gamesPlayed?: number; gamesPlayed?: number;
@ -85,6 +87,7 @@ export async function submitFlappyScore(input: {
const flappyXp = (current.xpEarned ?? 0) + runXp; const flappyXp = (current.xpEarned ?? 0) + runXp;
const { xp: _xp, ...progressionRest } = progression; const { xp: _xp, ...progressionRest } = progression;
const chipBank = Math.max(0, (progression.chipBank ?? 0) + chipsForXp(runXp));
await payload.update({ await payload.update({
collection: "profiles", collection: "profiles",
@ -92,6 +95,7 @@ export async function submitFlappyScore(input: {
data: { data: {
progression: { progression: {
...progressionRest, ...progressionRest,
chipBank,
minigames: { minigames: {
...(progressionRest.minigames ?? {}), ...(progressionRest.minigames ?? {}),
flappyBird: { gamesPlayed, totalPasses, bestScore, xpEarned: flappyXp }, flappyBird: { gamesPlayed, totalPasses, bestScore, xpEarned: flappyXp },
@ -104,6 +108,7 @@ export async function submitFlappyScore(input: {
broadcastToUser("profile-update", Number(user.id), { broadcastToUser("profile-update", Number(user.id), {
reason: "xp", reason: "xp",
xpGained: runXp, xpGained: runXp,
chipBank,
profileId: profile.id, profileId: profile.id,
}); });

View file

@ -2,6 +2,7 @@
import config from "@payload-config"; import config from "@payload-config";
import { getPayload } from "payload"; import { getPayload } from "payload";
import { chipsForXp } from "@/lib/minigames/chips";
import { import {
OPORD_DIFFICULTIES, OPORD_DIFFICULTIES,
@ -99,6 +100,7 @@ export async function submitOpordRecallResult(
const progression = (profile.progression ?? {}) as { const progression = (profile.progression ?? {}) as {
xp?: unknown; xp?: unknown;
chipBank?: number | null;
minigames?: { minigames?: {
opordRecall?: { opordRecall?: {
gamesPlayed?: number; gamesPlayed?: number;
@ -153,6 +155,7 @@ export async function submitOpordRecallResult(
input.difficulty === "elite" ? tierBestTimeMs : (current.eliteBestTimeMs ?? null); input.difficulty === "elite" ? tierBestTimeMs : (current.eliteBestTimeMs ?? null);
const { xp: _xp, ...progressionRest } = progression; const { xp: _xp, ...progressionRest } = progression;
const chipBank = Math.max(0, (progression.chipBank ?? 0) + chipsForXp(xp));
await payload.update({ await payload.update({
collection: "profiles", collection: "profiles",
@ -160,6 +163,7 @@ export async function submitOpordRecallResult(
data: { data: {
progression: { progression: {
...progressionRest, ...progressionRest,
chipBank,
minigames: { minigames: {
...(progressionRest.minigames ?? {}), ...(progressionRest.minigames ?? {}),
opordRecall: { opordRecall: {
@ -183,6 +187,7 @@ export async function submitOpordRecallResult(
broadcastToUser("profile-update", Number(user.id), { broadcastToUser("profile-update", Number(user.id), {
reason: "xp", reason: "xp",
xpGained: xp, xpGained: xp,
chipBank,
profileId: profile.id, profileId: profile.id,
}); });

View file

@ -5,6 +5,7 @@ import { getPayload } from "payload";
import { emitGameEvent } from "@/utils/event-log/emit"; import { emitGameEvent } from "@/utils/event-log/emit";
import { EventTypes } from "@/utils/event-log/eventTypes"; import { EventTypes } from "@/utils/event-log/eventTypes";
import { broadcastToUser } from "@/lib/realtime/bus"; import { broadcastToUser } from "@/lib/realtime/bus";
import { chipsForXp } from "@/lib/minigames/chips";
import { import {
isAimTrainerDifficulty, isAimTrainerDifficulty,
calculateAimTrainerAccuracy, calculateAimTrainerAccuracy,
@ -119,6 +120,7 @@ export async function submitAimTrainerResult(
const progression = (profile.progression ?? {}) as { const progression = (profile.progression ?? {}) as {
xp?: unknown; xp?: unknown;
chipBank?: number | null;
minigames?: { minigames?: {
aimTrainer?: { aimTrainer?: {
gamesPlayed?: number; gamesPlayed?: number;
@ -163,6 +165,7 @@ export async function submitAimTrainerResult(
const aimTrainerXp = (current.xpEarned ?? 0) + xp; const aimTrainerXp = (current.xpEarned ?? 0) + xp;
const { xp: _xp, ...progressionRest } = progression; const { xp: _xp, ...progressionRest } = progression;
const chipBank = Math.max(0, (progression.chipBank ?? 0) + chipsForXp(xp));
const recruitBestScore = input.difficulty === "recruit" ? difficultyBestScore : (current.recruitBestScore ?? 0); const recruitBestScore = input.difficulty === "recruit" ? difficultyBestScore : (current.recruitBestScore ?? 0);
const veteranBestScore = input.difficulty === "veteran" ? difficultyBestScore : (current.veteranBestScore ?? 0); const veteranBestScore = input.difficulty === "veteran" ? difficultyBestScore : (current.veteranBestScore ?? 0);
@ -180,6 +183,7 @@ export async function submitAimTrainerResult(
data: { data: {
progression: { progression: {
...progressionRest, ...progressionRest,
chipBank,
minigames: { minigames: {
...(progressionRest.minigames ?? {}), ...(progressionRest.minigames ?? {}),
aimTrainer: { aimTrainer: {
@ -202,6 +206,7 @@ export async function submitAimTrainerResult(
broadcastToUser("profile-update", Number(user.id), { broadcastToUser("profile-update", Number(user.id), {
reason: "xp", reason: "xp",
xpGained: xp, xpGained: xp,
chipBank,
profileId: profile.id, profileId: profile.id,
}); });

View file

@ -5,6 +5,7 @@ import { getPayload } from "payload";
import { emitGameEvent } from "@/utils/event-log/emit"; import { emitGameEvent } from "@/utils/event-log/emit";
import { EventTypes } from "@/utils/event-log/eventTypes"; import { EventTypes } from "@/utils/event-log/eventTypes";
import { broadcastToUser } from "@/lib/realtime/bus"; import { broadcastToUser } from "@/lib/realtime/bus";
import { chipsForXp } from "@/lib/minigames/chips";
interface ActionResult<T = undefined> { interface ActionResult<T = undefined> {
success: boolean; success: boolean;
@ -126,6 +127,7 @@ export async function submitRadioResult(input: {
const progression = (profile.progression ?? {}) as { const progression = (profile.progression ?? {}) as {
xp?: unknown; xp?: unknown;
chipBank?: number | null;
minigames?: { minigames?: {
radioTraffic?: { radioTraffic?: {
gamesPlayed?: number; gamesPlayed?: number;
@ -185,6 +187,7 @@ export async function submitRadioResult(input: {
const radioTrafficXp = Math.round(((current.xpEarned ?? 0) + runXp) * 10) / 10; const radioTrafficXp = Math.round(((current.xpEarned ?? 0) + runXp) * 10) / 10;
const { xp: _xp, ...progressionRest } = progression; const { xp: _xp, ...progressionRest } = progression;
const chipBank = Math.max(0, (progression.chipBank ?? 0) + chipsForXp(runXp));
await payload.update({ await payload.update({
collection: "profiles", collection: "profiles",
@ -192,6 +195,7 @@ export async function submitRadioResult(input: {
data: { data: {
progression: { progression: {
...progressionRest, ...progressionRest,
chipBank,
minigames: { minigames: {
...(progressionRest.minigames ?? {}), ...(progressionRest.minigames ?? {}),
radioTraffic: { radioTraffic: {
@ -222,6 +226,7 @@ export async function submitRadioResult(input: {
broadcastToUser("profile-update", Number(user.id), { broadcastToUser("profile-update", Number(user.id), {
reason: "xp", reason: "xp",
xpGained: runXp, xpGained: runXp,
chipBank,
profileId: profile.id, profileId: profile.id,
}); });