Real-Time Game State
Build an on-chain game with instant state updates.
onchain-game.ts
import { createPublicClient, createWalletClient, webSocket, http, encodeFunctionData } from 'viem'
import { privateKeyToAccount } from 'viem/accounts'
import { riseTestnet } from 'viem/chains'
import { sendRawTransactionSync } from 'shreds/viem'
// Simple game contract ABI
const gameAbi = [
{
inputs: [{ name: 'move', type: 'uint8' }],
name: 'makeMove',
outputs: [],
type: 'function'
},
{
inputs: [],
name: 'gameState',
outputs: [
{ name: 'player1', type: 'address' },
{ name: 'player2', type: 'address' },
{ name: 'currentTurn', type: 'address' },
{ name: 'board', type: 'uint8[9]' },
{ name: 'winner', type: 'address' }
],
type: 'function'
},
{
anonymous: false,
inputs: [
{ indexed: true, name: 'player', type: 'address' },
{ indexed: false, name: 'position', type: 'uint8' }
],
name: 'MoveMade',
type: 'event'
}
] as const
class OnChainGame {
private gameAddress: `0x${string}`
private wsClient: any
private walletClient: any
private publicClient: any
constructor(gameAddress: `0x${string}`) {
this.gameAddress = gameAddress
this.wsClient = createPublicClient({
chain: riseTestnet,
transport: webSocket()
})
this.publicClient = createPublicClient({
chain: riseTestnet,
transport: http()
})
const account = privateKeyToAccount('0x...')
this.walletClient = createWalletClient({
account,
chain: riseTestnet,
transport: http()
})
}
async makeMove(position: number) {
console.log(`Making move at position ${position}...`)
// Prepare and sign transaction
const request = await this.walletClient.prepareTransactionRequest({
to: this.gameAddress,
data: encodeFunctionData({
abi: gameAbi,
functionName: 'makeMove',
args: [position]
})
})
const serializedTransaction = await this.walletClient.signTransaction(request)
const receipt = await sendRawTransactionSync(this.publicClient, {
serializedTransaction
})
console.log('[SUCCESS] Move confirmed instantly!')
return receipt.transactionHash
}
async watchGame(onUpdate: (state: any) => void) {
// Initial state
const state = await this.getGameState()
onUpdate(state)
// Watch for updates
const unwatch = this.wsClient.watchContractEvent({
address: this.gameAddress,
abi: gameAbi,
eventName: 'MoveMade',
onLogs: async (logs) => {
// Get updated state immediately
const newState = await this.getGameState()
onUpdate(newState)
logs.forEach(log => {
console.log(`Player ${log.args.player} moved to ${log.args.position}`)
})
}
})
return unwatch
}
private async getGameState() {
const state = await this.publicClient.readContract({
address: this.gameAddress,
abi: gameAbi,
functionName: 'gameState'
})
return {
player1: state[0],
player2: state[1],
currentTurn: state[2],
board: state[3],
winner: state[4]
}
}
}
// Play the game
const game = new OnChainGame('0x...')
// Watch for updates
const unwatch = await game.watchGame((state) => {
console.log('Game state updated:', state)
// Update UI...
})
// Make a move
await game.makeMove(4) // Center position
Game Features
- Instant Moves: Players see moves immediately
- Real-Time Updates: Game state syncs across all players
- Fair Play: Blockchain ensures no cheating
- Global State: Anyone can verify the game state
Example: Tic-Tac-Toe UI
// Simple console UI for the game
function displayBoard(board: number[]) {
const symbols = [' ', 'X', 'O']
console.clear()
console.log('Current Board:')
console.log(`
${symbols[board[0]]} | ${symbols[board[1]]} | ${symbols[board[2]]}
---------
${symbols[board[3]]} | ${symbols[board[4]]} | ${symbols[board[5]]}
---------
${symbols[board[6]]} | ${symbols[board[7]]} | ${symbols[board[8]]}
`)
}
// Game loop
const game = new OnChainGame('0x...')
await game.watchGame((state) => {
displayBoard(state.board)
if (state.winner !== '0x0000000000000000000000000000000000000000') {
console.log(`Winner: ${state.winner}`)
} else {
console.log(`Current turn: ${state.currentTurn}`)
}
})
Advanced Gaming Features
- Tournaments: Create brackets with instant match results
- Leaderboards: Real-time ranking updates
- Achievements: Instant NFT minting for milestones
- Betting: Place and settle bets immediately
Benefits for Gaming
- No Lag: Moves confirmed in milliseconds
- Provably Fair: All game logic on-chain
- Global Play: Anyone can join from anywhere
- Instant Rewards: Prizes distributed immediately
Next Steps
- Build more complex games (poker, chess, RPGs)
- Add multiplayer matchmaking
- Implement game economies with tokens
- Create gaming tournaments