Skip to main content

Example Games

Cursor Tracking

Simple multiplayer cursor tracking with real-time position updates

Aviator Crash Game

Betting game where players cash out before the plane crashes

Coin Collection

Competitive game where players collect coins for points

Chat Room

Real-time chat with rooms and message history

🎯 Cursor Tracking Game

A simple example showing real-time player positions.
async def on_connect():
    player_name = request.get('player_name', 'Guest')
    room.join(request.get('room_id', 'lobby'), max_players=10)

    if not room.state:
        room.state = {'players': {}}

    room.state['players'][session.player_id] = {
        'name': player_name,
        'x': 400,
        'y': 300,
        'color': '#' + ''.join([hex(random.randint(0, 255))[2:].zfill(2) for _ in range(3)])
    }

    await room.broadcast({
        'type': 'player_joined',
        'player_id': session.player_id,
        'player_name': player_name
    })

    return {
        'type': 'welcome',
        'your_id': session.player_id,
        'players': room.state['players']
    }


async def on_message():
    action = request.get('action')

    if action == 'move':
        x = request.get('x', 0)
        y = request.get('y', 0)

        if session.player_id in room.state['players']:
            room.state['players'][session.player_id]['x'] = x
            room.state['players'][session.player_id]['y'] = y

            await room.broadcast({
                'type': 'player_moved',
                'player_id': session.player_id,
                'x': x,
                'y': y
            }, exclude=[session.player_id])


async def on_disconnect():
    if session.player_id in room.state['players']:
        player_name = room.state['players'][session.player_id]['name']
        del room.state['players'][session.player_id]

        await room.broadcast({
            'type': 'player_left',
            'player_id': session.player_id,
            'player_name': player_name
        })

    if room.get_player_count() == 0:
        room.destroy()

✈️ Aviator Crash Game

A betting game with automatic rounds and multipliers.
async def on_connect():
    if not room.state:
        room.state = {
            'players': {},
            'phase': 'waiting_for_players',
            'multiplier': 1.0,
            'crash_point': 0,
            'round': 1,
            'timer': 5.0,
            'last_update': time.time(),
            'min_players': 2
        }

    room.state['players'][session.player_id] = {
        'name': request.get('player_name', 'Guest'),
        'balance': 1000,
        'bet': 0,
        'has_bet': False,
        'cashed_out': False
    }

    if room.state['phase'] == 'waiting_for_players':
        if len(room.state['players']) >= room.state['min_players']:
            room.state['phase'] = 'waiting'
            await room.broadcast({'type': 'game_starting'})

    if not room.config.get('game_loop_started'):
        room.config['game_loop_started'] = True
        room.config['tick_rate'] = 20
        room.start_game_loop()

    return {
        'type': 'welcome',
        'your_id': session.player_id,
        'players': room.state['players'],
        'phase': room.state['phase']
    }


async def on_message():
    action = request.get('action')
    player = room.state['players'][session.player_id]

    if action == 'place_bet':
        amount = request.get('amount', 0)

        if room.state['phase'] != 'betting':
            return {'error': 'Cannot bet now'}

        if amount > player['balance']:
            return {'error': 'Insufficient balance'}

        player['balance'] -= amount
        player['bet'] = amount
        player['has_bet'] = True

        await room.broadcast({
            'type': 'bet_placed',
            'player_id': session.player_id,
            'amount': amount
        })

        return {'type': 'bet_confirmed', 'balance': player['balance']}

    elif action == 'cashout':
        if room.state['phase'] != 'flying':
            return {'error': 'No active round'}

        if not player['has_bet'] or player['cashed_out']:
            return {'error': 'No active bet'}

        multiplier = room.state['multiplier']
        winnings = int(player['bet'] * multiplier)
        player['balance'] += winnings
        player['cashed_out'] = True

        await room.broadcast({
            'type': 'player_cashed_out',
            'player_id': session.player_id,
            'multiplier': round(multiplier, 2),
            'winnings': winnings
        })

        return {'type': 'cashout_success', 'multiplier': round(multiplier, 2)}


async def on_tick():
    current_time = time.time()
    delta_time = current_time - room.state['last_update']
    room.state['last_update'] = current_time

    phase = room.state['phase']

    if phase == 'waiting_for_players':
        return

    if phase == 'waiting':
        room.state['timer'] -= delta_time
        if room.state['timer'] <= 0:
            room.state['phase'] = 'betting'
            room.state['timer'] = 10.0
            await room.broadcast({'type': 'betting_started'})

    elif phase == 'betting':
        room.state['timer'] -= delta_time
        if room.state['timer'] <= 0:
            room.state['phase'] = 'flying'
            room.state['multiplier'] = 1.0
            rand = random.random()
            room.state['crash_point'] = 1.5 + rand * 8.5
            await room.broadcast({'type': 'round_started'})

    elif phase == 'flying':
        growth = 0.1 * (1 + room.state['multiplier'] * 0.05)
        room.state['multiplier'] += growth * delta_time

        await room.broadcast({
            'type': 'multiplier_update',
            'multiplier': round(room.state['multiplier'], 2)
        })

        if room.state['multiplier'] >= room.state['crash_point']:
            room.state['phase'] = 'crashed'

            for player in room.state['players'].values():
                player['has_bet'] = False
                player['cashed_out'] = False
                player['bet'] = 0

            await room.broadcast({
                'type': 'plane_crashed',
                'crash_multiplier': round(room.state['crash_point'], 2)
            })

            room.state['round'] += 1
            room.state['phase'] = 'waiting'
            room.state['timer'] = 5.0


async def on_disconnect():
    if session.player_id in room.state['players']:
        del room.state['players'][session.player_id]

        await room.broadcast({
            'type': 'player_left',
            'player_id': session.player_id
        })

    if room.get_player_count() == 0:
        room.destroy()

🪙 Coin Collection Game

Competitive game where players collect coins for points.
async def on_connect():
    room.join(request.get('room_id', 'lobby'), max_players=10)

    if not room.state:
        room.state = {
            'players': {},
            'coins': [],
            'last_update': time.time()
        }

        # Spawn initial coins
        for _ in range(10):
            room.state['coins'].append({
                'id': str(uuid.uuid4()),
                'x': random.randint(50, 750),
                'y': random.randint(50, 550)
            })

    room.state['players'][session.player_id] = {
        'name': request.get('player_name', 'Guest'),
        'x': 400,
        'y': 300,
        'score': 0,
        'color': '#' + ''.join([hex(random.randint(0, 255))[2:].zfill(2) for _ in range(3)])
    }

    if not room.config.get('game_loop_started'):
        room.config['game_loop_started'] = True
        room.config['tick_rate'] = 20
        room.start_game_loop()

    await room.broadcast({
        'type': 'player_joined',
        'player_id': session.player_id
    })

    return {
        'type': 'welcome',
        'your_id': session.player_id,
        'players': room.state['players'],
        'coins': room.state['coins']
    }


async def on_message():
    action = request.get('action')

    if action == 'move':
        x = request.get('x', 0)
        y = request.get('y', 0)

        player = room.state['players'][session.player_id]
        player['x'] = x
        player['y'] = y

        # Check coin collisions
        for coin in room.state['coins'][:]:
            dx = coin['x'] - x
            dy = coin['y'] - y
            distance = (dx * dx + dy * dy) ** 0.5

            if distance < 20:  # Collision
                room.state['coins'].remove(coin)
                player['score'] += 10

                # Spawn new coin
                room.state['coins'].append({
                    'id': str(uuid.uuid4()),
                    'x': random.randint(50, 750),
                    'y': random.randint(50, 550)
                })

                await room.broadcast({
                    'type': 'coin_collected',
                    'player_id': session.player_id,
                    'coin_id': coin['id'],
                    'new_coin': room.state['coins'][-1],
                    'score': player['score']
                })

        await room.broadcast({
            'type': 'player_moved',
            'player_id': session.player_id,
            'x': x,
            'y': y
        }, exclude=[session.player_id])


async def on_tick():
    # Optional: Add power-ups or time-limited events
    pass


async def on_disconnect():
    if session.player_id in room.state['players']:
        del room.state['players'][session.player_id]

        await room.broadcast({
            'type': 'player_left',
            'player_id': session.player_id
        })

    if room.get_player_count() == 0:
        room.destroy()

💬 Chat Room

Real-time chat with room support.
async def on_connect():
    room.join(request.get('room_id', 'general'), max_players=50)

    if not room.state:
        room.state = {
            'users': {},
            'messages': []
        }

    username = request.get('username', 'Guest')
    room.state['users'][session.player_id] = {
        'username': username,
        'joined_at': time.time()
    }

    await room.broadcast({
        'type': 'user_joined',
        'user_id': session.player_id,
        'username': username
    })

    return {
        'type': 'welcome',
        'your_id': session.player_id,
        'users': room.state['users'],
        'messages': room.state['messages'][-50:]  # Last 50 messages
    }


async def on_message():
    action = request.get('action')

    if action == 'send_message':
        text = request.get('text', '')

        if len(text) > 0 and len(text) <= 500:
            message = {
                'id': str(uuid.uuid4()),
                'user_id': session.player_id,
                'username': room.state['users'][session.player_id]['username'],
                'text': text,
                'timestamp': time.time()
            }

            room.state['messages'].append(message)

            # Keep only last 100 messages
            if len(room.state['messages']) > 100:
                room.state['messages'] = room.state['messages'][-100:]

            await room.broadcast({
                'type': 'new_message',
                'message': message
            })

            return {'status': 'sent'}

        return {'error': 'Invalid message'}


async def on_disconnect():
    if session.player_id in room.state['users']:
        username = room.state['users'][session.player_id]['username']
        del room.state['users'][session.player_id]

        await room.broadcast({
            'type': 'user_left',
            'user_id': session.player_id,
            'username': username
        })

    if room.get_player_count() == 0:
        room.destroy()

Next Steps