@beta-gamer/react-native
v0.1.39
Published
React Native SDK for Beta Gamer GaaS — composable game components
Downloads
532
Readme
@beta-gamer/react-native
React Native SDK for Beta Gamer — embed multiplayer games into your mobile app as native components.
You control the layout; we handle matchmaking, game logic, and real-time sync.
🚀 Quick Start • 📖 Documentation • 🎮 Games • 🔧 API Reference • 💡 Examples
✨ Features
- 📱 Native Mobile Components — Fully native game components, no WebViews
- 🔄 Real-time Sync — Automatic state synchronization across players
- 🤖 Bot Support — Built-in AI opponents with configurable difficulty
- 🎨 Customizable Styling — Full control over colors, fonts, and layouts
- 📐 Responsive Design — Adapts to all screen sizes and orientations
- 🔐 Secure Sessions — JWT-based authentication with your backend
- ⚡ TypeScript Ready — Full type safety and IntelliSense support
- 📦 Expo Compatible — Works with both Expo and bare React Native
📦 Installation
npm install @beta-gamer/react-nativeOptional Dependencies
# Only required for Subway Runner game (uses WebView)
npx expo install react-native-webview # Expo projects
npm install react-native-webview && cd ios && pod install # Bare React NativeRequirements
- React Native 0.73+ or Expo SDK 50+
- A Beta Gamer account → Sign up at beta-gamer.com
🚀 Quick Start
1. Create a Session (Backend)
Never call the Beta Gamer API directly from your mobile app. Create sessions from your backend:
// Your server — Express, Next.js API route, Cloudflare Worker, etc.
app.post('/api/game/start', async (req, res) => {
const { userId, userName, game, matchType } = req.body;
const response = await fetch('https://api.beta-gamer.com/v1/sessions', {
method: 'POST',
headers: {
'Authorization': 'Bearer bg_live_your_api_key_here',
'Content-Type': 'application/json',
},
body: JSON.stringify({
game,
matchType,
players: [{ id: userId, displayName: userName }],
}),
});
const { sessionId, sessionToken } = await response.json();
res.json({ sessionToken });
});2. Render the Game (Mobile App)
import React from 'react';
import { View } from 'react-native';
import { BetaGamerProvider, ChessBoard } from '@beta-gamer/react-native';
export default function GameScreen({ sessionToken }: { sessionToken: string }) {
return (
<BetaGamerProvider token={sessionToken}>
<View style={{ flex: 1, padding: 16 }}>
<ChessBoard style={{ flex: 1 }} />
</View>
</BetaGamerProvider>
);
}That's it! Your users can now play chess with real-time multiplayer, matchmaking, and bot opponents on mobile.
🎮 Supported Games
| Game | Component | Description | Native |
|------|-----------|-------------|--------|
| ♟️ Chess | ChessBoard | Full-featured chess with move validation | ✅ |
| ⬤ Checkers | CheckersBoard | Classic checkers with king promotion | ✅ |
| 🔴 Connect 4 | Connect4Board | Drop pieces to get four in a row | ✅ |
| ❌ Tic-tac-toe | TictactoeBoard | Simple 3x3 grid game | ✅ |
| 🃏 Chkobe | ChkobeBoard | Strategic card game | ✅ |
| 🏃 Subway Runner | SubwayRunnerGame | Endless runner game | 🌐 WebView |
Game-Specific Packages
For advanced customization, install individual game packages:
npm install @beta-gamer/react-native-chess
npm install @beta-gamer/react-native-checkers
npm install @beta-gamer/react-native-connect4
npm install @beta-gamer/react-native-tictactoe
npm install @beta-gamer/react-native-chkobe📖 Documentation
Architecture Overview
┌─────────────────────────────────────────────────────────────┐
│ Your React Native App │
├─────────────────────────────────────────────────────────────┤
│ BetaGamerProvider (Session Management + Socket.IO) │
│ ├── useSession() - Session data & player info │
│ ├── useSocket() - Raw socket for custom events │
│ ├── useGameState() - Current game state │
│ └── useTheme() - Theming tokens │
├─────────────────────────────────────────────────────────────┤
│ Native Game Components (ChessBoard, etc.) │
│ ├── Game Logic & State Management │
│ ├── Move Validation & Turn Management │
│ └── Native UI Rendering & Touch Handling │
├─────────────────────────────────────────────────────────────┤
│ Beta Gamer Backend │
│ ├── Matchmaking & Room Management │
│ ├── Game Engine & Move Processing │
│ ├── Bot AI & Difficulty Scaling │
│ └── Real-time Event Broadcasting │
└─────────────────────────────────────────────────────────────┘Session Flow
sequenceDiagram
participant MobileApp
participant YourBackend
participant BetaGamer
participant SDK
MobileApp->>YourBackend: Request game session
YourBackend->>BetaGamer: POST /v1/sessions
BetaGamer-->>YourBackend: sessionId + sessionToken (JWT)
YourBackend-->>MobileApp: sessionToken
MobileApp->>SDK: <BetaGamerProvider token={sessionToken}>
SDK->>BetaGamer: Connect via Socket.IO
BetaGamer-->>SDK: Real-time game eventsBetaGamerProvider
The BetaGamerProvider is the root component that manages session state and Socket.IO connections:
<BetaGamerProvider
token={sessionToken} // Required: JWT session token
serverUrl="https://api.beta-gamer.com" // Optional: API server URL
socketPath="/socket.io" // Optional: Socket.IO path
connectSocket={true} // Optional: Auto-connect socket
>
{/* Your game components */}
</BetaGamerProvider>Hooks
useSession()
Access decoded session data:
import { useSession } from '@beta-gamer/react-native';
import { View, Text } from 'react-native';
function GameInfo() {
const session = useSession();
return (
<View>
<Text style={{ fontSize: 18, fontWeight: 'bold' }}>
Game: {session.game}
</Text>
<Text>Mode: {session.mode}</Text>
<Text>Match Type: {session.matchType}</Text>
<Text>
Players: {session.players.map(p => p.displayName).join(', ')}
</Text>
</View>
);
}useSocket()
Access raw Socket.IO instance for custom events:
import { useEffect } from 'react';
import { useSocket } from '@beta-gamer/react-native';
import { View, TouchableOpacity, Text } from 'react-native';
function CustomGameLogic() {
const socket = useSocket();
useEffect(() => {
if (!socket) return;
socket.on('custom:event', (data) => {
console.log('Custom event received:', data);
});
return () => socket.off('custom:event');
}, [socket]);
const sendCustomEvent = () => {
socket?.emit('custom:action', { data: 'example' });
};
return (
<TouchableOpacity onPress={sendCustomEvent}>
<Text>Send Custom Event</Text>
</TouchableOpacity>
);
}useGameState()
Access current game state:
import { useGameState } from '@beta-gamer/react-native';
import { View, Text } from 'react-native';
function GameStatus() {
const gameState = useGameState();
return (
<View>
<Text>Status: {gameState.status}</Text>
{gameState.status === 'ended' && (
<Text>Winner: {gameState.winner || 'Draw'}</Text>
)}
</View>
);
}💡 Examples
Basic Chess Game
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { BetaGamerProvider, ChessBoard } from '@beta-gamer/react-native';
export default function ChessGame({ sessionToken }: { sessionToken: string }) {
return (
<View style={styles.container}>
<BetaGamerProvider token={sessionToken}>
<Text style={styles.title}>Chess Game</Text>
<ChessBoard
style={styles.board}
showCoords={true}
showLastMove={true}
/>
</BetaGamerProvider>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#1a1a1a',
padding: 16,
},
title: {
color: 'white',
fontSize: 24,
fontWeight: 'bold',
textAlign: 'center',
marginBottom: 16,
},
board: {
flex: 1,
},
});Bot Game with Difficulty Selection
import React, { useState } from 'react';
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';
import { BetaGamerProvider, TictactoeBoard } from '@beta-gamer/react-native';
export default function BotGame() {
const [sessionToken, setSessionToken] = useState<string | null>(null);
const [difficulty, setDifficulty] = useState<'easy' | 'medium' | 'hard'>('medium');
const startBotGame = async () => {
const response = await fetch('/api/create-session', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
game: 'tictactoe',
matchType: 'bot',
botDifficulty: difficulty,
players: [{ id: 'user_123', displayName: 'Player' }],
}),
});
const { sessionToken } = await response.json();
setSessionToken(sessionToken);
};
if (!sessionToken) {
return (
<View style={styles.lobbyContainer}>
<Text style={styles.title}>Tic-tac-toe vs Bot</Text>
<View style={styles.difficultyContainer}>
{(['easy', 'medium', 'hard'] as const).map(level => (
<TouchableOpacity
key={level}
onPress={() => setDifficulty(level)}
style={[
styles.difficultyButton,
difficulty === level && styles.difficultyButtonActive
]}
>
<Text style={[
styles.difficultyText,
difficulty === level && styles.difficultyTextActive
]}>
{level}
</Text>
</TouchableOpacity>
))}
</View>
<TouchableOpacity onPress={startBotGame} style={styles.startButton}>
<Text style={styles.startButtonText}>Start Game</Text>
</TouchableOpacity>
</View>
);
}
return (
<BetaGamerProvider token={sessionToken}>
<View style={styles.gameContainer}>
<TictactoeBoard style={styles.gameBoard} />
</View>
</BetaGamerProvider>
);
}
const styles = StyleSheet.create({
lobbyContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
padding: 20,
backgroundColor: '#f5f5f5',
},
gameContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
padding: 20,
},
title: {
fontSize: 24,
fontWeight: 'bold',
marginBottom: 30,
textAlign: 'center',
},
difficultyContainer: {
flexDirection: 'row',
marginBottom: 30,
},
difficultyButton: {
paddingHorizontal: 20,
paddingVertical: 10,
marginHorizontal: 5,
backgroundColor: '#e0e0e0',
borderRadius: 8,
},
difficultyButtonActive: {
backgroundColor: '#3b82f6',
},
difficultyText: {
fontSize: 16,
textTransform: 'capitalize',
},
difficultyTextActive: {
color: 'white',
},
startButton: {
backgroundColor: '#10b981',
paddingHorizontal: 30,
paddingVertical: 15,
borderRadius: 8,
},
startButtonText: {
color: 'white',
fontSize: 18,
fontWeight: 'bold',
},
gameBoard: {
width: 300,
height: 300,
},
});🔧 API Reference
Components
BetaGamerProvider
Root provider component that manages session and socket state.
Props:
token: string- Required. JWT session token from your backendserverUrl?: string- API server URL (default:https://api.beta-gamer.com)socketPath?: string- Socket.IO path (default:/socket.io)connectSocket?: boolean- Auto-connect socket (default:true)children: React.ReactNode- Child components
Game Components
All game components accept these common props:
style?: ViewStyle- React Native style objectonGameOver?: (result: GameResult) => void- Game over callback
Chess: ChessBoard
showCoords?: boolean- Show board coordinates (default:false)showLastMove?: boolean- Highlight last move (default:true)showCaptured?: boolean- Show captured pieces (default:false)
Checkers: CheckersBoard
showLastMove?: boolean- Highlight last move (default:true)orientation?: 'red' | 'black'- Board orientation (default: player color)
Connect 4: Connect4Board
showLastMove?: boolean- Highlight last move (default:true)
Tic-tac-toe: TictactoeBoard
showLastMove?: boolean- Highlight last move (default:true)
Chkobe: ChkobeBoard
theme?: ChkobeTheme- Custom theme object
🎨 Styling & Theming
StyleSheet Integration
All components work with React Native's StyleSheet:
import { StyleSheet } from 'react-native';
const styles = StyleSheet.create({
gameBoard: {
flex: 1,
backgroundColor: '#f0f0f0',
borderRadius: 8,
margin: 16,
},
});
<ChessBoard style={styles.gameBoard} />Responsive Design
Components automatically adapt to screen size:
import { Dimensions } from 'react-native';
const { width, height } = Dimensions.get('window');
const boardSize = Math.min(width, height) * 0.8;
<ChessBoard style={{ width: boardSize, height: boardSize }} />🔍 Troubleshooting
Common Issues
❌ "useBetaGamer must be used inside "
Make sure all game components are wrapped in BetaGamerProvider:
// ❌ Wrong
<ChessBoard />
// ✅ Correct
<BetaGamerProvider token={sessionToken}>
<ChessBoard />
</BetaGamerProvider>❌ Metro bundler errors with Socket.IO
Add to your metro.config.js:
const { getDefaultConfig } = require('expo/metro-config');
const config = getDefaultConfig(__dirname);
config.resolver.assetExts.push('cjs');
module.exports = config;❌ Android network security issues
Add to android/app/src/main/res/xml/network_security_config.xml:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">api.beta-gamer.com</domain>
</domain-config>
</network-security-config>📚 FAQ
Q: Does this work with Expo? A: Yes! The SDK is fully compatible with Expo managed workflow.
Q: Can I customize the game UI?
A: Yes! Use the style prop and React Native styling to customize appearance.
Q: How do I handle different screen sizes?
A: Components are responsive by default. Use Dimensions API for custom layouts.
Q: Can I use this offline? A: No, games require an internet connection for real-time multiplayer.
Q: How do I test on device? A: Use Expo Go or build a development build. Socket.IO works on real devices.
📄 License
MIT © Beta Gamer
Made with ❤️ by the Beta Gamer team
Website • Documentation • Discord • Twitter
