Sets up the Step 1 (Project Foundation) and Step 2 (Content Schemas) scaffold from the implementation sequence. Includes Docker Compose stack, Nakama TypeScript module stubs, PostgreSQL migration, Godot 4 project shell with scene stubs and NakamaClient singleton, YAML content schemas for all entity types, and example data for 3 characters, 2 jobs, and all 7 core resources. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
56 lines
1.6 KiB
TypeScript
56 lines
1.6 KiB
TypeScript
// auth.ts — account lifecycle hooks
|
|
//
|
|
// Seeds a new player account with starter resources and one guaranteed
|
|
// starter character pull. Everything here must be idempotent: if called
|
|
// more than once on the same account (e.g. after a reconnect), it must
|
|
// not duplicate grants.
|
|
|
|
const STARTER_RESOURCES: Record<string, number> = {
|
|
gold: 500,
|
|
wood: 200,
|
|
stone: 100,
|
|
knowledge: 50,
|
|
experience: 0,
|
|
mana: 30,
|
|
diamond: 100, // starter diamonds — enough to feel the pull system
|
|
};
|
|
|
|
const STORAGE_KEY_SEEDED = "account_seeded";
|
|
|
|
export function afterAuthenticateDevice(
|
|
ctx: nkruntime.Context,
|
|
logger: nkruntime.Logger,
|
|
nk: nkruntime.Nakama,
|
|
out: nkruntime.Session,
|
|
_in: nkruntime.AuthenticateDeviceRequest
|
|
): void {
|
|
const userId = ctx.userId;
|
|
|
|
// Guard: only seed once
|
|
const existing = nk.storageRead([
|
|
{ collection: "player", key: STORAGE_KEY_SEEDED, userId },
|
|
]);
|
|
if (existing.length > 0) return;
|
|
|
|
logger.info(`Seeding new account: ${userId}`);
|
|
|
|
// Grant starter wallet balances
|
|
const walletChangeset: { [key: string]: number } = STARTER_RESOURCES;
|
|
nk.walletUpdate(userId, walletChangeset, { source: "new_account_seed" });
|
|
|
|
// Mark account as seeded so this block never runs again
|
|
nk.storageWrite([
|
|
{
|
|
collection: "player",
|
|
key: STORAGE_KEY_SEEDED,
|
|
userId,
|
|
value: { seeded_at: Date.now() },
|
|
permissionRead: 1,
|
|
permissionWrite: 0,
|
|
},
|
|
]);
|
|
|
|
// TODO PR 3: write player profile object (display name, server, region)
|
|
// TODO PR 4: create ledger entry for seed grant
|
|
// TODO PR 5: trigger one free starter banner pull
|
|
}
|