npm package: @ludustack/sdk
Description: Ludustack SDK for JavaScript/TypeScript
Author: Ludustack Team
Latest version: 0.0.11

# LuduStack SDK

A TypeScript SDK for interacting with the Ludustack API for JavaScript/TypeScript applications.

**🎮 [LuduStack](https://ludustack.com)** - The complete gamification platform for developers.

## Installation

```bash
npm install @ludustack/sdk
```

## Initialization

```typescript
import { LudustackSDK } from "@ludustack/sdk";

// Initialize the SDK - gameId is required
const sdk = new LudustackSDK({
  apiKey: "your-api-key",
  gameId: "your-game-id", // Required - all operations will use this game
});

// Use the SDK to interact with the API
async function getGames() {
  try {
    const games = await sdk.games.getAll();
    console.log(games);
  } catch (error) {
    console.error("Error fetching games:", error);
  }
}

// Set API Key
sdk.setApiKey("new-api-key");

// Clear API Key
sdk.clearApiKey();

// Change game ID for all operations
sdk.setGameId("new-game-id");

// Get current game ID
const currentGameId = sdk.getGameId();
```

## Available Clients

The SDK currently provides the following clients:

- `games` - Manage games and game operations
- `players` - Manage players and their data
- `leaderboards` - Manage leaderboards and entries
- `projects` - Manage projects and API keys
- `operations` - Manage all game operations (points, achievements, badges, titles, etc.)

## Core Features

### Game Management

Create and manage games:

```typescript
// Create a new game
const game = await sdk.games.create({
  name: "My Awesome Game",
  description: "A fun game for everyone",
  type: "casual",
});

// Update game status
await sdk.games.updateStatus(game.id, "active");
```

### Player Management

Create and manage players:

```typescript
// Create a new player
const player = await sdk.players.create({
  username: "player123",
  displayName: "Player One",
  externalId: "external-123", // Optional
});

// Get player by ID
const playerById = await sdk.players.getById("player-123");

// Update player data
await sdk.players.update("player-123", {
  displayName: "Player Master",
});
```

### Game Operations

All game operations use the gameId provided during SDK initialization.
To switch games, use `sdk.setGameId("new-game-id")`.

#### Giving Points to Players

```typescript
// Give points to a player (uses SDK's gameId)
await sdk.operations.givePoints(
  "player-123", // Player ID
  100 // Points to add
);

// With action name for predefined rules
await sdk.operations.givePoints(
  "player-123", // Player ID
  undefined, // Points (let the action determine points)
  "level_completed" // Action name
);

// With rule ID for direct rule reference
await sdk.operations.givePoints(
  "player-123", // Player ID
  100, // Points to add
  undefined, // Action name
  "rule-123" // Rule ID
);
```

#### Processing Achievements

```typescript
// Process achievement progress
await sdk.operations.processAchievement(
  "player-123", // Player ID
  "first_login", // Achievement ID
  {
    progress: 1, // Progress amount (optional)
    forceComplete: false, // Force completion (optional)
    operation: "progress", // Operation type: "progress", "grant", or "revoke"
  }
);

// Force complete an achievement
await sdk.operations.processAchievement("player-123", "achievement-id", {
  forceComplete: true,
});

// Grant an achievement directly
await sdk.operations.processAchievement("player-123", "achievement-id", {
  operation: "grant",
});

// Revoke an achievement
await sdk.operations.processAchievement("player-123", "achievement-id", {
  operation: "revoke",
});
```

#### Processing Badges

```typescript
// Award a badge
await sdk.operations.processBadge(
  "player-123", // Player ID
  "badge-id", // Badge ID
  {
    operation: "award",
    level: 1, // Badge level (optional)
  }
);

// Revoke a badge
await sdk.operations.processBadge("player-123", "badge-id", {
  operation: "revoke",
});
```

#### Processing Titles

```typescript
// Give a title to a player
await sdk.operations.processTitle(
  "player-123", // Player ID
  "title-id", // Title ID
  "give" // Operation: "give", "remove", or "set-active"
);

// Remove a title from a player
await sdk.operations.processTitle("player-123", "title-id", "remove");

// Set a title as active
await sdk.operations.processTitle("player-123", "title-id", "set-active");
```

#### Updating Leaderboards

```typescript
// Update player score in leaderboard
await sdk.operations.updateLeaderboard(
  "player-123", // Player ID
  "leaderboard-id", // Leaderboard ID
  1500 // Score
);
```

### Switching Games

To operate on a different game, simply change the SDK's gameId:

```typescript
// Switch to a different game
sdk.setGameId("another-game-id");

// All subsequent operations will use the new gameId
await sdk.operations.givePoints("player-123", 50);
```

### Leaderboards

Create and manage leaderboards:

```typescript
// Create a leaderboard
const leaderboard = await sdk.leaderboards.create({
  name: "Weekly Tournament",
  gameId: "game-123",
  scope: "weekly",
  type: "points",
});

// Update player score in leaderboard (alternative method)
await sdk.leaderboards.updatePlayerScore(leaderboard.id, "player-123", 1500);

// Reset a leaderboard
await sdk.leaderboards.reset(leaderboard.id);
```

## React Integration

For React applications, we recommend using our React SDK:

```bash
npm install @ludustack/react
```

```jsx
import {
  LudustackProvider,
  useGame,
  usePlayer,
  useLeaderboard,
  useOperations,
} from "@ludustack/react";

function App() {
  return (
    <LudustackProvider apiKey="your-api-key" gameId="your-game-id">
      <YourApp />
    </LudustackProvider>
  );
}

function GameComponent() {
  const { game, startGame } = useGame("game-123");
  const { player } = usePlayer("player-123");
  const { operations } = useOperations();

  const handleLevelComplete = () => {
    // Give points to player - gameId is automatically used from SDK
    operations.givePoints("player-123", 100);

    // Process achievement
    operations.processAchievement("player-123", "level_master", {
      forceComplete: true,
    });
  };

  return (
    <div>
      <h2>Game: {game?.name}</h2>
      <p>Player: {player?.displayName}</p>
      <p>Points: {player?.points}</p>
      <button onClick={handleLevelComplete}>Complete Level</button>
    </div>
  );
}
```

## Error Handling

The SDK provides a standardized way to handle errors:

```typescript
import { ApiError } from "@ludustack/sdk";

try {
  const game = await sdk.games.getById("game-id");
} catch (error) {
  if (error instanceof ApiError) {
    console.error(
      `API Error: ${error.message} (Status: ${error.status}, Code: ${error.code})`
    );
  } else {
    console.error("Unknown error:", error);
  }
}
```

## TypeScript Support

The SDK is written in TypeScript and provides full type definitions:

```typescript
import { LudustackSDK, Game, Player, Leaderboard } from "@ludustack/sdk";

// Creating a new game with proper typing
async function createGame(name: string, description: string): Promise<Game> {
  const sdk = new LudustackSDK({
    apiKey: "your-api-key",
    gameId: "your-game-id", // Optional: Set default for operations
  });

  return await sdk.games.create({
    name,
    description,
  });
}
```

## Best Practices

1. **Security**: Never expose your API key in client-side code. Use the SDK in a server environment or create a backend proxy.

2. **Game Operations**: Always use operations client (like `operations.givePoints`) rather than direct player operations when possible, as this maintains better consistency across the API.

3. **Error Handling**: Always implement proper error handling to provide a smooth user experience.

4. **Rate Limiting**: Be mindful of API rate limits, especially for high-traffic applications.

## Support

For support, please:

- Visit [our main website](https://ludustack.com)
- [Contact us](https://x.com/programad)
- Check [our documentation](https://ludustack.com/docs)

> **Important:** API keys are tied to your account. Protect them and never expose them in client-side code.

## License

MIT