Initial scaffold: Nakama backend, Godot client, content schema
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>
This commit is contained in:
commit
fb00954954
37 changed files with 2730 additions and 0 deletions
56
nakama/modules/auth.ts
Normal file
56
nakama/modules/auth.ts
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
// 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
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue