@flayerlabs/gamemode-cli 0.4.3 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/AGENTS.md CHANGED
@@ -103,6 +103,13 @@ await room.economy.buy(maxSpendWei)
103
103
  The trusted parent validates the gate authorisation, builds the transaction and asks the player to
104
104
  approve it. Game code never handles `hookData`.
105
105
 
106
+ Every amount the economy reports is in base units of the round's spend token: the coin's paired
107
+ token. That is wei on an ETH-paired coin and, for example, millionths on a six-decimal stablecoin.
108
+ Read the token off the terms — `spendTokenOf(room.terms.current())` gives its `symbol` and
109
+ `decimals` — and format with those. Never divide by 1e18 by hand: that is only correct for ETH.
110
+ For dollars, divide by 10 to the token's decimals and multiply by `terms.usdPerSpendToken`, which
111
+ is the token's own market price.
112
+
106
113
  ## Declare the maximum score
107
114
 
108
115
  `rewardBounds(config)` must return the highest score one player can earn.
@@ -58,11 +58,11 @@ const app = createGameServerGate({
58
58
  },
59
59
  signer: SIGNER_ADDRESS, // the address of your gate's signing key
60
60
  settler: SIGNER_ADDRESS,
61
- walletCapWei: '25000000000000000',
61
+ walletCap: '25000000000000000',
62
62
  roundDurationMs: 90_000,
63
63
  minLobbyLeadMs: 60_000,
64
64
  gateEndsAtGraceS: 10,
65
- flaunchVariant: 'legacy11',
65
+ flaunchVariant: 'v1_2',
66
66
  requiresEoa: false,
67
67
  accepting: true,
68
68
  publicLaunchesOpen: true,
@@ -73,7 +73,7 @@ const app = createGameServerGate({
73
73
 
74
74
  The addresses above are Base Sepolia (chain 84532), read back from the chain. `signer` is what a
75
75
  launch writes into its pool as the trusted signer — announce an address you do not hold and every
76
- coin launched through your game is unplayable. `walletCapWei` must cover a flawless round
76
+ coin launched through your game is unplayable. `walletCap` must cover a flawless round
77
77
  (`maxPointsPerPlayer` times the wei value of a point) or boot refuses.
78
78
 
79
79
  Check: `curl https://<your-gate>/config` returns JSON with your `chainId` and `signer`, and
package/dist/scaffold.js CHANGED
@@ -399,17 +399,38 @@ GATE_ORIGIN=
399
399
  # error at launch. Add a staging/preview launch page's origin while you test against one.
400
400
  # One * may span a single DNS label.
401
401
  ALLOWED_ORIGINS=https://*.games.moongate.com,https://flaunch.gg
402
+
403
+ # Your round's economy. Boot refuses numbers a flawless round cannot honour, and names the fix.
404
+ # How many points a dollar is worth.
405
+ POINTS_PER_DOLLAR=100
406
+ # The ETH price rounds on an ETH-paired coin are fixed at. Fractions are fine.
407
+ USD_PER_ETH=3000
408
+ # Per-wallet cap for ETH-paired launches, in wei. Default 0.025 ETH.
409
+ WALLET_CAP_WEI=25000000000000000
410
+ # Paired-token rounds: coins paired with something other than ETH spend in THAT token's base
411
+ # units. List each token you will host with its dollar price and the per-wallet cap a launch on
412
+ # it should write (base units — 50000000 is 50 MUSD at six decimals). Symbol and decimals are
413
+ # read from the chain. A token not listed here is refused at adoption; the gate never guesses a
414
+ # price. Hosting them also needs the paired stack: POSITION_MANAGER=<the V1_3 paired manager>.
415
+ # SPEND_TOKENS=[{"address":"0xd0B4398976572515a269C6331A143e08a70E9ccC","usdPerToken":1,"walletCap":"50000000"}]
402
416
  `,
403
417
  'railpack.json': `${JSON.stringify({
404
418
  $schema: 'https://schema.railpack.com',
405
419
  build: { builder: 'RAILPACK', buildCommand: 'pnpm install' },
406
420
  deploy: { startCommand: 'pnpm gate' },
407
421
  }, null, 2)}\n`,
408
- 'src/play.ts': `import { connectHost, createMockRoom, joinRoom, type Snapshot } from '@flayerlabs/gamemode-client';
422
+ 'src/play.ts': `import { connectHost, createMockRoom, joinRoom, spendTokenOf, type Snapshot } from '@flayerlabs/gamemode-client';
409
423
  import { rules, type Action, type Config, type PlayerView, type PublicView } from './game/rules.js';
410
424
 
411
425
  const config: Config = { rounds: 3, ceiling: 10, points: 500, roundMs: 10_000 };
412
426
 
427
+ /** Base units to a whole-token string, at the token's own decimals. */
428
+ function formatUnits(units: bigint, decimals: number): string {
429
+ const whole = units / 10n ** BigInt(decimals);
430
+ const fraction = (units % 10n ** BigInt(decimals)).toString().padStart(decimals, '0').replace(/0+$/, '');
431
+ return fraction ? \`\${whole}.\${fraction}\` : whole.toString();
432
+ }
433
+
413
434
  // Embedded on flaunch.gg, the page tells this game which gate and round to join and services its
414
435
  // wallet calls over the frame bridge. Standing alone (pnpm dev), there is no page to ask — null is
415
436
  // that answer, and the mock room runs the same rules with the chain and wallet faked.
@@ -434,6 +455,10 @@ function render(snapshot = latest): void {
434
455
  const { publicView, playerView } = snapshot;
435
456
  const seconds = Math.max(0, Math.ceil((publicView.endsAt - room.now()) / 1_000));
436
457
  const balance = room.economy.current();
458
+ // Amounts are base units of the round's spend token — wei on an ETH round, 10^-6 on a
459
+ // six-decimal stablecoin. Never divide by 1e18 by hand: read the decimals off the terms.
460
+ const spend = spendTokenOf(room.terms.current());
461
+ const available = \`\${formatUnits(balance.available, spend.decimals)} \${spend.symbol}\`;
437
462
 
438
463
  gameRoot.innerHTML = \`
439
464
  <main>
@@ -456,7 +481,7 @@ function render(snapshot = latest): void {
456
481
  : 'Pick once before the round ends.'}</p>
457
482
  <dl>
458
483
  <div><dt>Score</dt><dd>\${playerView?.score ?? 0}</dd></div>
459
- <div><dt>Available</dt><dd>\${balance.availableWei} wei</dd></div>
484
+ <div><dt>Available</dt><dd>\${available}</dd></div>
460
485
  </dl>
461
486
  </main>
462
487
  \`;
@@ -1 +1 @@
1
- {"version":3,"file":"scaffold.js","sourceRoot":"","sources":["../src/scaffold.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scaffold.js","sourceRoot":"","sources":["../src/scaffold.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flayerlabs/gamemode-cli",
3
- "version": "0.4.3",
3
+ "version": "0.5.1",
4
4
  "description": "Create and validate Flaunch Game Modes",
5
5
  "license": "MIT",
6
6
  "author": "Flayer Labs",
package/src/scaffold.ts CHANGED
@@ -432,6 +432,20 @@ GATE_ORIGIN=
432
432
  # error at launch. Add a staging/preview launch page's origin while you test against one.
433
433
  # One * may span a single DNS label.
434
434
  ALLOWED_ORIGINS=https://*.games.moongate.com,https://flaunch.gg
435
+
436
+ # Your round's economy. Boot refuses numbers a flawless round cannot honour, and names the fix.
437
+ # How many points a dollar is worth.
438
+ POINTS_PER_DOLLAR=100
439
+ # The ETH price rounds on an ETH-paired coin are fixed at. Fractions are fine.
440
+ USD_PER_ETH=3000
441
+ # Per-wallet cap for ETH-paired launches, in wei. Default 0.025 ETH.
442
+ WALLET_CAP_WEI=25000000000000000
443
+ # Paired-token rounds: coins paired with something other than ETH spend in THAT token's base
444
+ # units. List each token you will host with its dollar price and the per-wallet cap a launch on
445
+ # it should write (base units — 50000000 is 50 MUSD at six decimals). Symbol and decimals are
446
+ # read from the chain. A token not listed here is refused at adoption; the gate never guesses a
447
+ # price. Hosting them also needs the paired stack: POSITION_MANAGER=<the V1_3 paired manager>.
448
+ # SPEND_TOKENS=[{"address":"0xd0B4398976572515a269C6331A143e08a70E9ccC","usdPerToken":1,"walletCap":"50000000"}]
435
449
  `,
436
450
 
437
451
  'railpack.json': `${JSON.stringify(
@@ -444,11 +458,18 @@ ALLOWED_ORIGINS=https://*.games.moongate.com,https://flaunch.gg
444
458
  2,
445
459
  )}\n`,
446
460
 
447
- 'src/play.ts': `import { connectHost, createMockRoom, joinRoom, type Snapshot } from '@flayerlabs/gamemode-client';
461
+ 'src/play.ts': `import { connectHost, createMockRoom, joinRoom, spendTokenOf, type Snapshot } from '@flayerlabs/gamemode-client';
448
462
  import { rules, type Action, type Config, type PlayerView, type PublicView } from './game/rules.js';
449
463
 
450
464
  const config: Config = { rounds: 3, ceiling: 10, points: 500, roundMs: 10_000 };
451
465
 
466
+ /** Base units to a whole-token string, at the token's own decimals. */
467
+ function formatUnits(units: bigint, decimals: number): string {
468
+ const whole = units / 10n ** BigInt(decimals);
469
+ const fraction = (units % 10n ** BigInt(decimals)).toString().padStart(decimals, '0').replace(/0+$/, '');
470
+ return fraction ? \`\${whole}.\${fraction}\` : whole.toString();
471
+ }
472
+
452
473
  // Embedded on flaunch.gg, the page tells this game which gate and round to join and services its
453
474
  // wallet calls over the frame bridge. Standing alone (pnpm dev), there is no page to ask — null is
454
475
  // that answer, and the mock room runs the same rules with the chain and wallet faked.
@@ -473,6 +494,10 @@ function render(snapshot = latest): void {
473
494
  const { publicView, playerView } = snapshot;
474
495
  const seconds = Math.max(0, Math.ceil((publicView.endsAt - room.now()) / 1_000));
475
496
  const balance = room.economy.current();
497
+ // Amounts are base units of the round's spend token — wei on an ETH round, 10^-6 on a
498
+ // six-decimal stablecoin. Never divide by 1e18 by hand: read the decimals off the terms.
499
+ const spend = spendTokenOf(room.terms.current());
500
+ const available = \`\${formatUnits(balance.available, spend.decimals)} \${spend.symbol}\`;
476
501
 
477
502
  gameRoot.innerHTML = \`
478
503
  <main>
@@ -495,7 +520,7 @@ function render(snapshot = latest): void {
495
520
  : 'Pick once before the round ends.'}</p>
496
521
  <dl>
497
522
  <div><dt>Score</dt><dd>\${playerView?.score ?? 0}</dd></div>
498
- <div><dt>Available</dt><dd>\${balance.availableWei} wei</dd></div>
523
+ <div><dt>Available</dt><dd>\${available}</dd></div>
499
524
  </dl>
500
525
  </main>
501
526
  \`;