@playcademy/sdk 0.0.1-beta.27 → 0.0.1-beta.29

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/README.md CHANGED
@@ -1,184 +1,548 @@
1
- # Playcademy SDK
1
+ # @playcademy/sdk
2
2
 
3
- A TypeScript SDK for interacting with the Playcademy platform API.
3
+ **Official TypeScript SDK for the Playcademy platform**
4
+
5
+ The Playcademy SDK provides a comprehensive, type-safe interface for building games on the Playcademy platform. It handles authentication, game sessions, user data, inventory management, and all platform APIs through a unified client interface.
4
6
 
5
7
  ## Overview
6
8
 
7
- This SDK provides a unified client for various interactions with Playcademy.
9
+ The SDK serves as the primary interface between your game and the Playcademy platform, providing:
10
+
11
+ - **Automatic Environment Detection**: Seamlessly works in development and production
12
+ - **Type-Safe API Access**: Full TypeScript support with comprehensive type definitions
13
+ - **Session Management**: Automatic game session handling and state persistence
14
+ - **Event System**: Real-time notifications for inventory changes, level ups, and more
15
+ - **Developer Tools**: Built-in support for game development and testing workflows
16
+
17
+ ### Key Benefits
18
+
19
+ - **Zero Configuration**: Automatic initialization with environment detection
20
+ - **Production Ready**: Battle-tested API patterns with robust error handling
21
+ - **Real-Time Events**: Subscribe to platform events like inventory changes and level ups
22
+ - **Comprehensive Coverage**: Access to all Playcademy platform features
23
+ - **Development Experience**: Integrated with sandbox environment for local development
24
+
25
+ ### Use Cases
8
26
 
9
- ## Install
27
+ - **Game Development**: Primary SDK for building games on Playcademy
28
+ - **Web Applications**: Frontend applications interacting with the platform
29
+ - **Developer Tools**: Scripts and utilities for game management
30
+ - **Server Integration**: Backend services integrating with Playcademy APIs
31
+ - **Testing & Automation**: Automated testing of platform integrations
32
+
33
+ ## Installation
34
+
35
+ Install the SDK using your preferred package manager:
10
36
 
11
37
  ```bash
38
+ # Using Bun (recommended)
12
39
  bun add @playcademy/sdk
13
- # or
40
+
41
+ # Using npm
14
42
  npm install @playcademy/sdk
15
- # or
43
+
44
+ # Using yarn
16
45
  yarn add @playcademy/sdk
17
- # or
46
+
47
+ # Using pnpm
18
48
  pnpm add @playcademy/sdk
19
49
  ```
20
50
 
21
- ## Initialization
51
+ ## Quick Start
52
+
53
+ ### Automatic Initialization (Recommended)
54
+
55
+ For most game development scenarios, use automatic initialization:
56
+
57
+ ```typescript
58
+ import { PlaycademyClient } from '@playcademy/sdk'
59
+
60
+ async function initializeGame() {
61
+ try {
62
+ // Automatic initialization - detects environment and configures appropriately
63
+ const client = await PlaycademyClient.init()
64
+
65
+ // Get current user
66
+ const user = await client.users.me()
67
+ console.log('Welcome,', user.name)
68
+
69
+ // The client is ready for all platform operations
70
+ return client
71
+ } catch (error) {
72
+ console.error('Failed to initialize Playcademy SDK:', error)
73
+ throw error
74
+ }
75
+ }
76
+ ```
77
+
78
+ ### Environment Detection
79
+
80
+ The SDK automatically detects and configures for different environments:
81
+
82
+ - **Development**: Connects to local sandbox (started by `@playcademy/vite-plugin`)
83
+ - **Production**: Receives configuration from Playcademy platform loader
84
+ - **Testing**: Falls back to mock configuration for automated testing
85
+
86
+ ## Core Features
87
+
88
+ ### Game Session Management
89
+
90
+ ```typescript
91
+ // Automatic session management when gameId is available
92
+ const client = await PlaycademyClient.init()
93
+
94
+ // Save transient game state (position, health, temporary data)
95
+ await client.games.saveState({
96
+ currentLevel: 'forest_glade',
97
+ playerPosition: { x: 100, y: 200 },
98
+ health: 85,
99
+ activePowerUps: ['speed_boost'],
100
+ })
101
+
102
+ // Load previously saved state
103
+ const gameState = await client.games.loadState()
104
+ console.log('Loaded state:', gameState)
105
+
106
+ // Exit game (automatically ends session if managed)
107
+ await client.runtime.exit()
108
+ ```
109
+
110
+ ### User & Inventory Management
111
+
112
+ ```typescript
113
+ // Get user information
114
+ const user = await client.users.me()
115
+
116
+ // Inventory operations (accepts UUIDs or slugs)
117
+ const inventory = await client.users.inventory.get()
118
+ await client.users.inventory.add('magic-sword', 1)
119
+ await client.users.inventory.remove('health-potion', 1)
120
+
121
+ // Check item quantities and ownership
122
+ const goldCount = await client.users.inventory.quantity('gold-coin')
123
+ const hasKey = await client.users.inventory.has('dungeon-key')
124
+ const hasEnoughGold = await client.users.inventory.has('gold-coin', 100)
125
+ ```
126
+
127
+ ### Credits & Currency
22
128
 
23
- ### Browser / Mini-Games (Runtime Environment)
129
+ ```typescript
130
+ // Platform currency management
131
+ const balance = await client.credits.balance()
132
+ await client.credits.add(100)
133
+ await client.credits.spend(50)
24
134
 
25
- For code running within the Playcademy game loader environment (e.g., mini-games):
135
+ // Check affordability
136
+ if ((await client.credits.balance()) >= 100) {
137
+ await client.credits.spend(100)
138
+ console.log('Purchase successful!')
139
+ }
140
+ ```
26
141
 
27
- ```ts
28
- import { initFromWindow } from '@playcademy/sdk'
142
+ ### Experience & Levels
29
143
 
30
- // Reads configuration from window.PLAYCADEMY injected by the loader
31
- const client = await initFromWindow() // initFromWindow is async
144
+ ```typescript
145
+ // Level management
146
+ const userLevel = await client.levels.get()
147
+ const progress = await client.levels.progress()
148
+ console.log(`Level ${userLevel.currentLevel}, ${progress.xpToNextLevel} XP to next level`)
149
+
150
+ // Add experience points
151
+ const result = await client.levels.addXP(100)
152
+ if (result.leveledUp) {
153
+ console.log(`Level up! ${result.oldLevel} → ${result.newLevel}`)
154
+ console.log('Credits awarded:', result.creditsAwarded)
155
+ }
32
156
  ```
33
157
 
34
- ### General Use (Node.js, Backend, UI Tooling)
158
+ ## API Reference
159
+
160
+ ### Core Modules
161
+
162
+ #### **Authentication** (`client.auth`)
163
+
164
+ - `logout()`: Logs out user and clears authentication token
165
+
166
+ #### **Users** (`client.users`)
167
+
168
+ - `me()`: Get current user information
169
+ - **Inventory** (`client.users.inventory`):
170
+ - `get()`: Get user's inventory
171
+ - `add(identifier, quantity)`: Add items to inventory
172
+ - `remove(identifier, quantity)`: Remove items from inventory
173
+ - `quantity(identifier)`: Get item quantity
174
+ - `has(identifier, minQuantity?)`: Check item ownership
175
+
176
+ #### **Games** (`client.games`)
177
+
178
+ - `list()`: Get all available games
179
+ - `fetch(gameIdOrSlug)`: Get specific game details
180
+ - `saveState(state)`: Save transient game state
181
+ - `loadState()`: Load saved game state
182
+ - `startSession(gameId?)`: Start game session
183
+ - `endSession(sessionId, gameId?)`: End game session
184
+
185
+ #### **Credits** (`client.credits`)
186
+
187
+ - `balance()`: Get current credits balance
188
+ - `add(amount)`: Add credits to user
189
+ - `spend(amount)`: Spend user credits
190
+
191
+ #### **Levels** (`client.levels`)
192
+
193
+ - `get()`: Get current user level information
194
+ - `progress()`: Get level progress and XP to next level
195
+ - `addXP(amount)`: Add experience points
196
+ - **Config** (`client.levels.config`):
197
+ - `list()`: Get all level configurations
198
+ - `get(level)`: Get specific level configuration
199
+
200
+ #### **Maps** (`client.maps`)
201
+
202
+ - `elements(mapId)`: Get map elements and points of interest
203
+
204
+ #### **Runtime** (`client.runtime`)
205
+
206
+ - `getGameToken(gameId, options?)`: Get game-specific authentication token
207
+ - `exit()`: Signal platform to exit game view
208
+
209
+ #### **Leaderboard** (`client.leaderboard`) - Game-specific
210
+
211
+ - `fetch(options?)`: Get leaderboard for a specific game
212
+ - `options.timeframe`: Filter by time period (`'all_time'`, `'monthly'`, `'weekly'`, `'daily'`)
213
+ - `options.gameId`: Game ID to fetch leaderboard for (required)
214
+ - `options.limit`: Number of entries to return (default: 10)
215
+ - `options.offset`: Pagination offset (default: 0)
216
+
217
+ #### **Scores** (`client.scores`) - Platform-wide
218
+
219
+ - `submit(gameId, score, metadata?)`: Submit a score for any game
220
+ - `getUserScores(userId, options?)`: Get all scores for a user
221
+ - `options.gameId`: Filter by specific game (optional)
222
+ - `options.limit`: Number of scores to return (default: 50)
223
+
224
+ ### Developer Tools
225
+
226
+ #### **Developer Authentication** (`client.dev.auth`)
227
+
228
+ - `applyForDeveloper()`: Apply for developer status
229
+ - `getDeveloperStatus()`: Check current developer status
230
+
231
+ #### **Game Management** (`client.dev.games`)
232
+
233
+ - `upsert(slug, metadata, gameFile)`: Create or update game
234
+ - `update(gameId, updates)`: Update game properties
235
+ - `delete(gameId)`: Delete game
236
+
237
+ #### **API Keys** (`client.dev.keys`)
238
+
239
+ - `createKey(gameId, name)`: Create API key for server authentication
240
+ - `listKeys()`: List all API keys
241
+ - `revokeKey(keyId)`: Revoke API key
242
+
243
+ #### **Item Management** (`client.dev.items`)
244
+
245
+ - `list(gameId)`: List all items for a game
246
+ - `get(gameId, slug)`: Get specific item
247
+ - `create(gameId, slug, data)`: Create new game item
248
+ - `update(gameId, itemId, updates)`: Update existing item
249
+ - `delete(gameId, itemId)`: Delete item
250
+
251
+ ## Event System
252
+
253
+ The SDK provides real-time event notifications for important platform changes:
254
+
255
+ ### Available Events
256
+
257
+ ```typescript
258
+ // Authentication changes
259
+ client.on('authChange', payload => {
260
+ console.log('Authentication changed:', payload.token)
261
+ })
35
262
 
36
- For server-side code, UI applications, or other environments where you manage configuration manually:
263
+ // Inventory changes
264
+ client.on('inventoryChange', payload => {
265
+ console.log(`Item ${payload.itemId}: ${payload.delta} (total: ${payload.newTotal})`)
266
+ })
37
267
 
38
- ```ts
268
+ // Experience gained
269
+ client.on('xpGained', payload => {
270
+ console.log(`Gained ${payload.amount} XP (total: ${payload.totalXP})`)
271
+ })
272
+
273
+ // Level up notifications
274
+ client.on('levelUp', payload => {
275
+ console.log(`Level up! ${payload.oldLevel} → ${payload.newLevel}`)
276
+ console.log('Credits awarded:', payload.creditsAwarded)
277
+ })
278
+ ```
279
+
280
+ ### Event-Driven UI Updates
281
+
282
+ ```typescript
283
+ // Update UI in response to platform events
284
+ client.on('inventoryChange', payload => {
285
+ updateInventoryDisplay(payload.itemId, payload.newTotal)
286
+ })
287
+
288
+ client.on('levelUp', payload => {
289
+ showLevelUpAnimation(payload.newLevel)
290
+ showCreditsAwarded(payload.creditsAwarded)
291
+ })
292
+
293
+ client.on('xpGained', payload => {
294
+ updateXPBar(payload.totalXP, payload.leveledUp)
295
+ })
296
+ ```
297
+
298
+ ## Advanced Usage
299
+
300
+ ### Manual Initialization
301
+
302
+ For server-side applications or custom environments:
303
+
304
+ ```typescript
39
305
  import { PlaycademyClient } from '@playcademy/sdk'
40
306
 
41
307
  import type { LoginResponse } from '@playcademy/sdk'
42
308
 
43
- async function initializeAndUseClient() {
44
- const baseUrl = 'https://api.playcademy.com' // Or your local /api endpoint
45
- let loginResponse: LoginResponse
309
+ // Step 1: Authenticate
310
+ const loginData: LoginResponse = await PlaycademyClient.login(
311
+ 'https://api.playcademy.com',
312
+ 'user@example.com',
313
+ 'password',
314
+ )
315
+
316
+ // Step 2: Initialize client
317
+ const client = new PlaycademyClient({
318
+ baseUrl: 'https://api.playcademy.com',
319
+ token: loginData.token,
320
+ gameId: 'your-game-id', // Optional: enables automatic session management
321
+ })
322
+ ```
46
323
 
47
- try {
48
- // 1. Authenticate to get a token
49
- loginResponse = await PlaycademyClient.login(baseUrl, 'user@example.com', 'password')
50
- } catch (error) {
51
- console.error('Login failed:', error)
52
- return
324
+ ### Custom Configuration
325
+
326
+ ```typescript
327
+ const client = new PlaycademyClient({
328
+ baseUrl: 'https://api.playcademy.com',
329
+ token: 'your-auth-token',
330
+ gameId: 'your-game-id',
331
+ // Additional options
332
+ timeout: 10000, // Request timeout in milliseconds
333
+ retries: 3, // Number of retry attempts
334
+ })
335
+ ```
336
+
337
+ ### Error Handling
338
+
339
+ ```typescript
340
+ import { PlaycademyError } from '@playcademy/sdk'
341
+
342
+ try {
343
+ const user = await client.users.me()
344
+ // Handle success
345
+ } catch (error) {
346
+ if (error instanceof PlaycademyError) {
347
+ console.error('Playcademy API Error:', error.message)
348
+ console.error('Status Code:', error.statusCode)
349
+ console.error('Error Code:', error.code)
350
+ } else {
351
+ console.error('Unexpected error:', error)
53
352
  }
353
+ }
354
+ ```
54
355
 
55
- // 2. Instantiate the client with the token
56
- // Optionally provide a gameId to enable automatic session management for that game.
57
- const client = new PlaycademyClient({
58
- baseUrl: baseUrl,
59
- token: loginResponse.token,
60
- // gameId: 'your-game-id' // Optional: if provided, client attempts to auto-start/end session
61
- })
356
+ ## Development Environment
62
357
 
63
- // If the token has appropriate permissions, you can access all namespaces:
64
- // client.dev.games.upsert(...)
65
- // client.admin.items.createItem(...)
66
- // Calling a method without sufficient token permissions will result in a server error.
358
+ ### Integration with Playcademy Vite Plugin
67
359
 
68
- // Example: Listen for auth changes (e.g., if token is refreshed or cleared by logout)
69
- client.onAuthChange(token => {
70
- console.log('Authentication token changed:', token)
71
- // You might want to update stored token here
72
- })
360
+ When using the official Playcademy Vite templates, the development environment is automatically configured:
73
361
 
74
- // Example: Logout
75
- // await client.auth.logout();
76
- }
362
+ ```typescript
363
+ // In your game's main file
364
+ import { PlaycademyClient } from '@playcademy/sdk'
77
365
 
78
- initializeAndUseClient()
366
+ // The vite plugin automatically starts the sandbox
367
+ const client = await PlaycademyClient.init()
368
+ // SDK automatically connects to local sandbox at http://localhost:4321
79
369
  ```
80
370
 
81
- ## Quickstart: Mini-Game Example
371
+ ### Manual Sandbox Setup
82
372
 
83
- ```ts
84
- import { initFromWindow } from '@playcademy/sdk'
373
+ If not using the Vite plugin, start the sandbox manually:
85
374
 
86
- async function runGame() {
87
- const client = await initFromWindow()
375
+ ```bash
376
+ # Start sandbox server
377
+ bunx @playcademy/sandbox --port 4321 --verbose
378
+
379
+ # In your application
380
+ const client = new PlaycademyClient({
381
+ baseUrl: 'http://localhost:4321/api',
382
+ token: 'dev-token' // Sandbox provides mock authentication
383
+ })
384
+ ```
88
385
 
89
- try {
90
- // 1) Start a game session (gameId is optional, defaults to client.gameId)
91
- const { sessionId } = await client.games.startSession()
92
- console.log('Session started:', sessionId)
93
-
94
- // 2) Fetch player's inventory/items
95
- const items = await client.users.inventory.get()
96
- console.log('Player inventory:', items)
97
-
98
- // 3) Save game state (uses client.gameId implicitly)
99
- await client.games.saveState({
100
- currentLevel: 'level_2', // This is separate from progress, often more transient
101
- health: 95,
386
+ ## Best Practices
387
+
388
+ ### Initialization & Setup
389
+
390
+ - **Always use automatic initialization** for game development with `PlaycademyClient.init()`
391
+ - **Handle initialization errors gracefully** with proper try-catch blocks
392
+ - **Store the client instance** for reuse throughout your application lifecycle
393
+
394
+ ### State Management
395
+
396
+ - **Use `games.saveState()`** for transient data (current level, position, temporary status)
397
+ - **Use `users.inventory`** for persistent items and resources that carry between sessions
398
+ - **Save state periodically**, not on every frame or minor change
399
+ - **Load state once** at game start, then manage locally
400
+
401
+ ### Performance Optimization
402
+
403
+ - **Cache frequently accessed data** like user information and inventory
404
+ - **Batch inventory operations** when possible instead of individual API calls
405
+ - **Use event listeners** to update UI reactively rather than polling
406
+ - **Implement proper loading states** for better user experience
407
+
408
+ ### Error Handling
409
+
410
+ - **Wrap all SDK calls** in appropriate try-catch blocks
411
+ - **Provide fallback behavior** for network errors and API failures
412
+ - **Show meaningful error messages** to users when operations fail
413
+ - **Implement retry logic** for non-critical operations
414
+
415
+ ### Development Workflow
416
+
417
+ - **Use the sandbox environment** for all local development
418
+ - **Test both online and offline scenarios** to ensure robust error handling
419
+ - **Enable verbose logging** during development for debugging
420
+ - **Validate API responses** and handle edge cases appropriately
421
+
422
+ ## Testing
423
+
424
+ ### Unit Testing
425
+
426
+ ```typescript
427
+ // Mock the SDK for unit tests
428
+ import { jest } from '@jest/globals'
429
+
430
+ // Mock the entire SDK module
431
+ jest.mock('@playcademy/sdk', () => ({
432
+ PlaycademyClient: {
433
+ init: jest.fn().mockResolvedValue({
434
+ users: {
435
+ me: jest.fn().mockResolvedValue({ id: 'test-user', name: 'Test User' }),
436
+ inventory: {
437
+ get: jest.fn().mockResolvedValue([]),
438
+ add: jest.fn().mockResolvedValue(undefined),
439
+ },
440
+ },
441
+ }),
442
+ },
443
+ }))
444
+ ```
445
+
446
+ ### Integration Testing
447
+
448
+ ```typescript
449
+ // Test with real sandbox
450
+ import { PlaycademyClient } from '@playcademy/sdk'
451
+
452
+ describe('Playcademy Integration', () => {
453
+ let client: PlaycademyClient
454
+
455
+ beforeAll(async () => {
456
+ // Initialize with sandbox
457
+ client = new PlaycademyClient({
458
+ baseUrl: 'http://localhost:4321/api',
459
+ token: 'test-token',
102
460
  })
103
- console.log('Game state saved')
461
+ })
104
462
 
105
- // 4) Load game state (uses client.gameId implicitly)
106
- const loadedState = await client.games.loadState()
107
- console.log('Game state loaded:', loadedState)
463
+ test('should fetch user data', async () => {
464
+ const user = await client.users.me()
465
+ expect(user).toBeDefined()
466
+ expect(user.name).toEqual(expect.any(String))
467
+ })
468
+ })
469
+ ```
108
470
 
109
- // 5) End the session when finished (gameId is optional)
110
- await client.games.endSession(sessionId)
111
- console.log('Session ended')
471
+ ## Troubleshooting
112
472
 
113
- // 6) Exit the game view (if embedded)
114
- client.runtime.exit()
115
- } catch (error) {
116
- console.error('An error occurred:', error)
117
- }
473
+ ### Common Issues
474
+
475
+ **SDK Initialization Timeout**
476
+
477
+ ```
478
+ Error: PLAYCADEMY_INIT not received within 5000ms
479
+ ```
480
+
481
+ - Ensure you're running in the correct environment (development with sandbox, or production with platform)
482
+ - Check that the Vite plugin is properly configured
483
+ - Verify the sandbox is running on the expected port
484
+
485
+ **Authentication Errors**
486
+
487
+ ```
488
+ Error: Unauthorized (401)
489
+ ```
490
+
491
+ - Check that your authentication token is valid
492
+ - Ensure you have the necessary permissions for the operation
493
+ - Try re-authenticating with `PlaycademyClient.login()`
494
+
495
+ **Network Connection Issues**
496
+
497
+ ```
498
+ Error: Failed to fetch
499
+ ```
500
+
501
+ - Verify the API endpoint is accessible
502
+ - Check network connectivity
503
+ - Ensure CORS is properly configured for cross-origin requests
504
+
505
+ ### Debugging
506
+
507
+ Use these debugging techniques for troubleshooting SDK issues:
508
+
509
+ ```typescript
510
+ // Check initialization process
511
+ try {
512
+ const client = await PlaycademyClient.init()
513
+ console.log('SDK initialized successfully')
514
+ } catch (error) {
515
+ console.error('SDK initialization failed:', error)
118
516
  }
119
517
 
120
- runGame()
121
- ```
122
-
123
- ## API Modules
124
-
125
- The `PlaycademyClient` instance provides access to all API modules.
126
- The server will determine if the provided token has sufficient permissions for each operation.
127
- Internal event handling uses a `BusEvents` enum for type safety.
128
- All methods returning data are strongly typed.
129
-
130
- - **`auth`**: User logout. For login, use the static `PlaycademyClient.login()` method.
131
- - `logout()`: Logs out the current user and clears the token from the client instance.
132
- - **`onAuthChange(callback)`**: A top-level client method to subscribe to authentication token changes (login, logout, explicit `setToken`).
133
- - **`users`**:
134
- - `me()`: Fetch current user details.
135
- - **`inventory`**:
136
- - `get()`: Get player inventory.
137
- - `add(identifier, qty)`: Add item to player inventory (accepts UUID or internal name).
138
- - `remove(identifier, qty)`: Remove item from player inventory (accepts UUID or internal name).
139
- - `quantity(identifier)`: Get current quantity of an item (accepts UUID or internal name).
140
- - `has(identifier, minQuantity?)`: Check if user has enough of an item (accepts UUID or internal name).
141
- - **`progress`**: Manages persistent progress data for a game (e.g., levels completed, scores, collectibles).
142
- - `get(gameId?)`: Get the entire progress state for a game. `gameId` is optional and defaults to the client's current game context.
143
- - `update(data, gameId?)`: Update the progress state for a game. `gameId` is optional. The `data` object can be structured to hold progress for various internal nodes or aspects of the game.
144
- - **`credits`**: Convenient methods for working with Playcademy Credits (primary platform currency).
145
- - `balance()`: Get current credits balance.
146
- - `add(amount)`: Add credits to user.
147
- - `spend(amount)`: Spend credits from user.
148
- - **`games`**: Manages game sessions and transient game state.
149
- - `fetch(gameIdOrSlug)`: Fetch game details with manifest.
150
- - `list()`: List all games.
151
- - `saveState(state)`: Save transient game state (e.g., current position, temporary buffs) for the current game context.
152
- - `loadState()`: Load transient game state for the current game context.
153
- - `startSession(gameId?)`: Start a game session. `gameId` is optional and defaults to `client.gameId` if set. If the client is managing an automatic session, this can be used to start additional, distinct sessions.
154
- - `endSession(sessionId, gameId?)`: End a game session. `gameId` is optional. If this ends an automatically managed session, the client will no longer attempt to auto-end it.
155
- - **`runtime`**:
156
- - `getGameToken(gameId, options?: { apply?: boolean })`: Fetches a game-specific token. If `options.apply` is true, it sets this token as the active token on the client instance (default is false).
157
- - `exit()`: Signals the hosting environment to close the game view. If the client is managing an automatic session (because `gameId` was provided at construction), this method will attempt to end that session before signaling exit.
158
- - **`maps`**:
159
- - `elements(mapId)`: Fetch elements (like nodes, points of interest) for a specific map.
160
- - **`dev.auth`**: Apply for developer status, get status.
161
- - **`dev.games`**: Upsert, update, delete games.
162
- - **`dev.keys`**: Create, list, revoke API keys for games.
163
- - **`admin.games`**: Pause/resume games.
164
- - **`admin.items`**: CRUD operations for items.
165
- - **`admin.currencies`**: CRUD operations for currencies.
166
- - **`admin.shopListings`**: CRUD operations for shop listings.
167
- - **`shop`**: Player-facing shop operations.
168
- - `view()`: Get shop items and currency information.
169
- - **`levels`**: Player level and experience point management.
170
- - `get()`: Get current user level information.
171
- - `progress()`: Get level progress with XP to next level.
172
- - `addXP(amount)`: Add XP to user.
173
- - **`config`**:
174
- - `list()`: Get all level configurations (full XP curve).
175
- - `get(level)`: Get configuration for a specific level.
176
- - **`telemetry`**: Push metrics.
518
+ // Monitor network requests in browser dev tools (Network tab)
519
+ // Check console for SDK error messages
520
+ // Verify API responses and error details
521
+ ```
522
+
523
+ ### Getting Help
524
+
525
+ - Check the [platform documentation](../../apps/docs/) for detailed guides
526
+ - Review the [Vite plugin configuration](../vite-plugin/) for development setup
527
+ - Examine the [game templates](../../templates/) for working examples
528
+ - Use browser dev tools to inspect network requests and responses
177
529
 
178
530
  ## Contributing
179
531
 
180
- PRs welcome. Fork, build, test, send a PR.
532
+ The SDK is a critical component of the Playcademy platform ecosystem. When contributing:
533
+
534
+ 1. **Maintain Type Safety**: Ensure all new APIs are fully typed
535
+ 2. **Update Documentation**: Keep this README and JSDoc comments current
536
+ 3. **Add Tests**: Include both unit and integration tests for new features
537
+ 4. **Follow Patterns**: Use consistent patterns with existing SDK methods
538
+ 5. **Handle Errors**: Implement proper error handling and user feedback
539
+
540
+ For general contribution guidelines, see the [monorepo CONTRIBUTING.md](../../CONTRIBUTING.md).
181
541
 
182
- ## License
542
+ ## Related Packages
183
543
 
184
- MIT
544
+ - [`@playcademy/api-core`](../api-core/): API handlers used by the SDK
545
+ - [`@playcademy/data`](../data/): Database schema and type definitions
546
+ - [`@playcademy/vite-plugin`](../vite-plugin/): Development environment integration
547
+ - [`@playcademy/sandbox`](../sandbox/): Local development server
548
+ - **Game Templates**: See `/templates` for example integrations