@playcademy/sdk
TypeScript icon, indicating that this package has built-in type declarations

0.0.1-beta.36 • Public • Published

@playcademy/sdk

Official TypeScript SDK for the Playcademy platform

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.

Overview

The SDK serves as the primary interface between your game and the Playcademy platform, providing:

  • Automatic Environment Detection: Seamlessly works in development and production
  • Type-Safe API Access: Full TypeScript support with comprehensive type definitions
  • Session Management: Automatic game session handling and state persistence
  • Event System: Real-time notifications for inventory changes, level ups, and more
  • Developer Tools: Built-in support for game development and testing workflows

Key Benefits

  • Zero Configuration: Automatic initialization with environment detection
  • Production Ready: Battle-tested API patterns with robust error handling
  • Real-Time Events: Subscribe to platform events like inventory changes and level ups
  • Comprehensive Coverage: Access to all Playcademy platform features
  • Development Experience: Integrated with sandbox environment for local development

Use Cases

  • Game Development: Primary SDK for building games on Playcademy
  • Web Applications: Frontend applications interacting with the platform
  • Developer Tools: Scripts and utilities for game management
  • Server Integration: Backend services integrating with Playcademy APIs
  • Testing & Automation: Automated testing of platform integrations

Installation

Install the SDK using your preferred package manager:

# Using Bun (recommended)
bun add @playcademy/sdk

# Using npm
npm install @playcademy/sdk

# Using yarn
yarn add @playcademy/sdk

# Using pnpm
pnpm add @playcademy/sdk

Quick Start

Automatic Initialization (Recommended)

For most game development scenarios, use automatic initialization:

import { PlaycademyClient } from '@playcademy/sdk'

async function initializeGame() {
    try {
        // Automatic initialization - detects environment and configures appropriately
        const client = await PlaycademyClient.init()

        // Get current user
        const user = await client.users.me()
        console.log('Welcome,', user.name)

        // The client is ready for all platform operations
        return client
    } catch (error) {
        console.error('Failed to initialize Playcademy SDK:', error)
        throw error
    }
}

Environment Detection

The SDK automatically detects and configures for different environments:

  • Development: Connects to local sandbox (started by @playcademy/vite-plugin)
  • Production: Receives configuration from Playcademy platform loader
  • Testing: Falls back to mock configuration for automated testing

Core Features

Game Session Management

// Automatic session management when gameId is available
const client = await PlaycademyClient.init()

// Save transient game state (position, health, temporary data)
await client.games.saveState({
    currentLevel: 'forest_glade',
    playerPosition: { x: 100, y: 200 },
    health: 85,
    activePowerUps: ['speed_boost'],
})

// Load previously saved state
const gameState = await client.games.loadState()
console.log('Loaded state:', gameState)

// Exit game (automatically ends session if managed)
await client.runtime.exit()

User & Inventory Management

// Get user information
const user = await client.users.me()

// Inventory operations (accepts UUIDs or slugs)
const inventory = await client.users.inventory.get()
await client.users.inventory.add('magic-sword', 1)
await client.users.inventory.remove('health-potion', 1)

// Check item quantities and ownership
const goldCount = await client.users.inventory.quantity('gold-coin')
const hasKey = await client.users.inventory.has('dungeon-key')
const hasEnoughGold = await client.users.inventory.has('gold-coin', 100)

Credits & Currency

// Platform currency management
const balance = await client.credits.balance()
await client.credits.add(100)
await client.credits.spend(50)

// Check affordability
if ((await client.credits.balance()) >= 100) {
    await client.credits.spend(100)
    console.log('Purchase successful!')
}

Experience & Levels

// Level management
const userLevel = await client.levels.get()
const progress = await client.levels.progress()
console.log(`Level ${userLevel.currentLevel}, ${progress.xpToNextLevel} XP to next level`)

// Add experience points
const result = await client.levels.addXP(100)
if (result.leveledUp) {
    console.log(`Level up! ${result.oldLevel}${result.newLevel}`)
    console.log('Credits awarded:', result.creditsAwarded)
}

API Reference

Core Modules

Authentication (client.auth)

  • logout(): Logs out user and clears authentication token

Users (client.users)

  • me(): Get current user information
  • Inventory (client.users.inventory):
    • get(): Get user's inventory
    • add(identifier, quantity): Add items to inventory
    • remove(identifier, quantity): Remove items from inventory
    • quantity(identifier): Get item quantity
    • has(identifier, minQuantity?): Check item ownership

Games (client.games)

  • list(): Get all available games
  • fetch(gameIdOrSlug): Get specific game details
  • saveState(state): Save transient game state
  • loadState(): Load saved game state
  • startSession(gameId?): Start game session
  • endSession(sessionId, gameId?): End game session

Credits (client.credits)

  • balance(): Get current credits balance
  • add(amount): Add credits to user
  • spend(amount): Spend user credits

Levels (client.levels)

  • get(): Get current user level information
  • progress(): Get level progress and XP to next level
  • addXP(amount): Add experience points
  • Config (client.levels.config):
    • list(): Get all level configurations
    • get(level): Get specific level configuration

Maps (client.maps)

  • elements(mapId): Get map elements and points of interest

Runtime (client.runtime)

  • getGameToken(gameId, options?): Get game-specific authentication token
  • exit(): Signal platform to exit game view

Leaderboard (client.leaderboard) - Game-specific

  • fetch(options?): Get leaderboard for a specific game
    • options.timeframe: Filter by time period ('all_time', 'monthly', 'weekly', 'daily')
    • options.gameId: Game ID to fetch leaderboard for (required)
    • options.limit: Number of entries to return (default: 10)
    • options.offset: Pagination offset (default: 0)

Scores (client.scores) - Platform-wide

  • submit(gameId, score, metadata?): Submit a score for any game
  • getUserScores(userId, options?): Get all scores for a user
    • options.gameId: Filter by specific game (optional)
    • options.limit: Number of scores to return (default: 50)

Developer Tools

Developer Authentication (client.dev.auth)

  • applyForDeveloper(): Apply for developer status
  • getDeveloperStatus(): Check current developer status

Game Management (client.dev.games)

  • upsert(slug, metadata, gameFile): Create or update game
  • update(gameId, updates): Update game properties
  • delete(gameId): Delete game

API Keys (client.dev.keys)

  • createKey(gameId, name): Create API key for server authentication
  • listKeys(): List all API keys
  • revokeKey(keyId): Revoke API key

Item Management (client.dev.items)

  • list(gameId): List all items for a game
  • get(gameId, slug): Get specific item
  • create(gameId, slug, data): Create new game item
  • update(gameId, itemId, updates): Update existing item
  • delete(gameId, itemId): Delete item

Event System

The SDK provides real-time event notifications for important platform changes:

Available Events

// Authentication changes
client.on('authChange', payload => {
    console.log('Authentication changed:', payload.token)
})

// Inventory changes
client.on('inventoryChange', payload => {
    console.log(`Item ${payload.itemId}: ${payload.delta} (total: ${payload.newTotal})`)
})

// Experience gained
client.on('xpGained', payload => {
    console.log(`Gained ${payload.amount} XP (total: ${payload.totalXP})`)
})

// Level up notifications
client.on('levelUp', payload => {
    console.log(`Level up! ${payload.oldLevel}${payload.newLevel}`)
    console.log('Credits awarded:', payload.creditsAwarded)
})

Event-Driven UI Updates

// Update UI in response to platform events
client.on('inventoryChange', payload => {
    updateInventoryDisplay(payload.itemId, payload.newTotal)
})

client.on('levelUp', payload => {
    showLevelUpAnimation(payload.newLevel)
    showCreditsAwarded(payload.creditsAwarded)
})

client.on('xpGained', payload => {
    updateXPBar(payload.totalXP, payload.leveledUp)
})

Advanced Usage

Manual Initialization

For server-side applications or custom environments:

import { PlaycademyClient } from '@playcademy/sdk'

import type { LoginResponse } from '@playcademy/sdk'

// Step 1: Authenticate
const loginData: LoginResponse = await PlaycademyClient.login(
    'https://api.playcademy.com',
    'user@example.com',
    'password',
)

// Step 2: Initialize client
const client = new PlaycademyClient({
    baseUrl: 'https://api.playcademy.com',
    token: loginData.token,
    gameId: 'your-game-id', // Optional: enables automatic session management
})

Custom Configuration

const client = new PlaycademyClient({
    baseUrl: 'https://api.playcademy.com',
    token: 'your-auth-token',
    gameId: 'your-game-id',
    // Additional options
    timeout: 10000, // Request timeout in milliseconds
    retries: 3, // Number of retry attempts
})

Error Handling

import { PlaycademyError } from '@playcademy/sdk'

try {
    const user = await client.users.me()
    // Handle success
} catch (error) {
    if (error instanceof PlaycademyError) {
        console.error('Playcademy API Error:', error.message)
        console.error('Status Code:', error.statusCode)
        console.error('Error Code:', error.code)
    } else {
        console.error('Unexpected error:', error)
    }
}

Development Environment

Integration with Playcademy Vite Plugin

When using the official Playcademy Vite templates, the development environment is automatically configured:

// In your game's main file
import { PlaycademyClient } from '@playcademy/sdk'

// The vite plugin automatically starts the sandbox
const client = await PlaycademyClient.init()
// SDK automatically connects to local sandbox at http://localhost:4321

Manual Sandbox Setup

If not using the Vite plugin, start the sandbox manually:

# Start sandbox server
bunx @playcademy/sandbox --port 4321 --verbose

# In your application
const client = new PlaycademyClient({
    baseUrl: 'http://localhost:4321/api',
    token: 'dev-token' // Sandbox provides mock authentication
})

Best Practices

Initialization & Setup

  • Always use automatic initialization for game development with PlaycademyClient.init()
  • Handle initialization errors gracefully with proper try-catch blocks
  • Store the client instance for reuse throughout your application lifecycle

State Management

  • Use games.saveState() for transient data (current level, position, temporary status)
  • Use users.inventory for persistent items and resources that carry between sessions
  • Save state periodically, not on every frame or minor change
  • Load state once at game start, then manage locally

Performance Optimization

  • Cache frequently accessed data like user information and inventory
  • Batch inventory operations when possible instead of individual API calls
  • Use event listeners to update UI reactively rather than polling
  • Implement proper loading states for better user experience

Error Handling

  • Wrap all SDK calls in appropriate try-catch blocks
  • Provide fallback behavior for network errors and API failures
  • Show meaningful error messages to users when operations fail
  • Implement retry logic for non-critical operations

Development Workflow

  • Use the sandbox environment for all local development
  • Test both online and offline scenarios to ensure robust error handling
  • Enable verbose logging during development for debugging
  • Validate API responses and handle edge cases appropriately

Testing

Unit Testing

// Mock the SDK for unit tests
import { jest } from '@jest/globals'

// Mock the entire SDK module
jest.mock('@playcademy/sdk', () => ({
    PlaycademyClient: {
        init: jest.fn().mockResolvedValue({
            users: {
                me: jest.fn().mockResolvedValue({ id: 'test-user', name: 'Test User' }),
                inventory: {
                    get: jest.fn().mockResolvedValue([]),
                    add: jest.fn().mockResolvedValue(undefined),
                },
            },
        }),
    },
}))

Integration Testing

// Test with real sandbox
import { PlaycademyClient } from '@playcademy/sdk'

describe('Playcademy Integration', () => {
    let client: PlaycademyClient

    beforeAll(async () => {
        // Initialize with sandbox
        client = new PlaycademyClient({
            baseUrl: 'http://localhost:4321/api',
            token: 'test-token',
        })
    })

    test('should fetch user data', async () => {
        const user = await client.users.me()
        expect(user).toBeDefined()
        expect(user.name).toEqual(expect.any(String))
    })
})

Troubleshooting

Common Issues

SDK Initialization Timeout

Error: PLAYCADEMY_INIT not received within 5000ms
  • Ensure you're running in the correct environment (development with sandbox, or production with platform)
  • Check that the Vite plugin is properly configured
  • Verify the sandbox is running on the expected port

Authentication Errors

Error: Unauthorized (401)
  • Check that your authentication token is valid
  • Ensure you have the necessary permissions for the operation
  • Try re-authenticating with PlaycademyClient.login()

Network Connection Issues

Error: Failed to fetch
  • Verify the API endpoint is accessible
  • Check network connectivity
  • Ensure CORS is properly configured for cross-origin requests

Debugging

Use these debugging techniques for troubleshooting SDK issues:

// Check initialization process
try {
    const client = await PlaycademyClient.init()
    console.log('SDK initialized successfully')
} catch (error) {
    console.error('SDK initialization failed:', error)
}

// Monitor network requests in browser dev tools (Network tab)
// Check console for SDK error messages
// Verify API responses and error details

Getting Help

Contributing

The SDK is a critical component of the Playcademy platform ecosystem. When contributing:

  1. Maintain Type Safety: Ensure all new APIs are fully typed
  2. Update Documentation: Keep this README and JSDoc comments current
  3. Add Tests: Include both unit and integration tests for new features
  4. Follow Patterns: Use consistent patterns with existing SDK methods
  5. Handle Errors: Implement proper error handling and user feedback

For general contribution guidelines, see the monorepo CONTRIBUTING.md.

Related Packages

Readme

Keywords

none

Package Sidebar

Install

npm i @playcademy/sdk

Weekly Downloads

457

Version

0.0.1-beta.36

License

none

Unpacked Size

228 kB

Total Files

31

Last publish

Collaborators

  • hbauer