Local Testing
The LocalTransport enables testing multiplayer functionality on a single machine without any server setup.
Setup
pnpm add @martini-kit/transport-local import { LocalTransport } from '@martini-kit/transport-local';
import { GameRuntime } from '@martini-kit/core';
import { game } from './game';
// Create local transport
const transport = new LocalTransport({
roomId: 'test-room',
isHost: true // First tab is host
});
const runtime = new GameRuntime(game, transport, {
isHost: transport.isHost(),
playerIds: [transport.getPlayerId()]
}); Multi-Tab Testing
Open your game in multiple browser tabs to simulate multiplayer:
- Tab 1 (Host): Opens first, becomes the host
- Tab 2 (Client): Opens second, connects as client
- Tab 3 (Client): Opens third, connects as client
All tabs share the same roomId and communicate via BroadcastChannel API.
Room Management
// Use URL parameter for room ID
const params = new URLSearchParams(window.location.search);
const roomId = params.get('room') || 'default-room';
const transport = new LocalTransport({
roomId,
isHost: !params.has('room') // First to create room is host
});
// Share URL with room parameter
console.log(`Open in another tab: ${window.location.origin}?room=${roomId}`); Testing Workflow
1. Development Server
npm run dev 2. Open Multiple Tabs
- Tab 1:
http://localhost:5173(host) - Tab 2:
http://localhost:5173(client) - Tab 3:
http://localhost:5173(client)
3. Test Scenarios
- Player join/leave
- State synchronization
- Action submission
- Lag simulation (optional)
Debugging
Enable Debug Logging
import { Logger } from '@martini-kit/core';
Logger.setLevel('debug');
const transport = new LocalTransport({
roomId: 'test',
isHost: true
});
// See detailed transport logs Inspect State
// Log state changes
runtime.onChange((state) => {
console.log('State updated:', state);
});
// Check if host
console.log('Is host:', runtime.isHost());
// Get current state
console.log('Current state:', runtime.getState()); Limitations
- ❌ Only works on same machine
- ❌ Doesn’t test real network conditions
- ❌ No latency simulation
- ❌ Not for production use
CI/CD Testing
LocalTransport is perfect for automated tests:
// test.spec.ts
import { describe, it, expect } from 'vitest';
import { LocalTransport } from '@martini-kit/transport-local';
import { GameRuntime } from '@martini-kit/core';
import { game } from '../game';
describe('Multiplayer game', () => {
it('should sync state between host and client', async () => {
// Create host
const hostTransport = new LocalTransport({
roomId: 'test',
isHost: true
});
const hostRuntime = new GameRuntime(game, hostTransport, {
isHost: true,
playerIds: ['host']
});
// Create client
const clientTransport = new LocalTransport({
roomId: 'test',
isHost: false
});
const clientRuntime = new GameRuntime(game, clientTransport, {
isHost: false,
playerIds: ['host', 'client']
});
// Submit action on host
hostRuntime.submitAction('move', { x: 100, y: 200 });
// Wait for sync
await new Promise(resolve => setTimeout(resolve, 100));
// Verify client received update
const clientState = clientRuntime.getState();
expect(clientState.players.host.x).toBe(100);
});
}); Next Steps
- Choosing a Transport → - Production options
- Testing Guide → - Comprehensive testing strategies