← Back to home

Flutter / Dart SDK

Integrate Asobi into Flutter, Flame, or standalone Dart apps. Async/await API with stream-based real-time events.

View on GitHub

Installation

Add to your pubspec.yaml:

dependencies:
  asobi:
    git:
      url: https://github.com/widgrensit/asobi-dart.git
      ref: main

Setup

import 'package:asobi/asobi.dart';

final client = AsobiClient('localhost', port: 8080);

// With SSL
final client = AsobiClient('api.mygame.com', port: 443, useSsl: true);

Authentication

// Register
await client.auth.register('player1', 'secret123',
    displayName: 'Player One');

// Login
await client.auth.login('player1', 'secret123');

// Session is stored automatically
print('Logged in as: ${client.playerId}');

Real-Time Connection

Connect via WebSocket and listen using Dart streams:

// Connect
await client.realtime.connect();

// Listen for match state (broadcast stream)
client.realtime.onMatchState.stream.listen((state) {
  // Update game state from server
});

// Listen for matchmaker results
client.realtime.onMatchmakerMatched.stream.listen((data) {
  print('Match found: ${data["match_id"]}');
});

// Chat messages
client.realtime.onChatMessage.stream.listen((msg) {
  print(msg['content']);
});

Matchmaking

// Queue via WebSocket (recommended)
await client.realtime.addToMatchmaker(mode: 'arena');

// Or via REST
final ticket = await client.matchmaker.add('arena');
final status = await client.matchmaker.status(ticket.id);

Match Input

// Join a match
await client.realtime.joinMatch(matchId);

// Send input (fire-and-forget for low latency)
client.realtime.sendMatchInput({'action': 'move', 'x': 1, 'y': 0});

// Leave match
await client.realtime.leaveMatch();

Leaderboards

// Submit a score
await client.leaderboards.submitScore('weekly', 1500);

// Get top scores
final top = await client.leaderboards.getTop('weekly', limit: 10);

// Get scores around current player
final around = await client.leaderboards.getAroundSelf('weekly');

Flame Engine

Flame is built on Flutter, so this SDK works out of the box. No separate Flame-specific package needed.

import 'package:flame/game.dart';
import 'package:asobi/asobi.dart';

class MyGame extends FlameGame {
  late final AsobiClient client;

  @override
  Future onLoad() async {
    client = AsobiClient('localhost', port: 8080);
    await client.auth.login('player1', 'secret123');
    await client.realtime.connect();

    client.realtime.onMatchState.stream.listen((state) {
      // Sync game components from server state
    });
  }

  @override
  void update(double dt) {
    super.update(dt);
    // Send player input each frame
    client.realtime.sendMatchInput({
      'action': 'move',
      'x': joystick.delta.x,
      'y': joystick.delta.y,
    });
  }
}

Cleanup in your dispose method:

@override
void onRemove() {
  client.dispose();
  super.onRemove();
}