RISE Logo-Light

Implementation

Build the game with Shreds integration and transaction pooling

Game Implementation

Now let's build the core game component with Shreds integration for blockchain-backed precision.

The complete implementation can be found in the GitHub repository. We'll highlight only the key sections here.

Key Concepts

Transaction Pool Pattern:

  • Pre-sign 10 transactions at initialization
  • Each click retrieves a pre-signed transaction from the pool
  • Background refilling at 50% capacity ensures the pool never depletes
  • Zero signing latency during gameplay

Game State Machine:

  • IDLE → WAITING → READY → FINISHED
  • Random delay (1-5s) between WAITING and READY
  • Measure reaction time with performance.now()
  • Record transaction confirmation time separately

Shreds Integration:

  • Use eth_sendRawTransactionSync for synchronous confirmations
  • Returns when transaction is finalized (3ms), not just submitted
  • Critical for accurate timing measurements

Core Implementation Highlights

src/app/single-player/page.tsx (excerpt)
// Transaction pool for pre-signed transactions
const preSignedPool: {
  transactions: `0x${string}`[];
  currentIndex: number;
  baseNonce: number;
} = {
  transactions: [],
  currentIndex: 0,
  baseNonce: 0,
};

// Pre-sign batch of transactions
const preSignBatch = async (startNonce: number, batchSize: number) => {
  const signingPromises = Array.from({ length: batchSize }, async (_, i) => {
    const txData = {
      to: account.address,
      value: 0n,
      data: `0x${(i + 1).toString(16).padStart(2, "0")}` as `0x${string}`,
      nonce: startNonce + i,
      gasPrice: gasPrice,
      gas: gasLimit,
      type: "legacy" as const,
    };
    return await client.signTransaction(txData);
  });
  return await Promise.all(signingPromises);
};

// Send transaction synchronously
const handleClick = async () => {
  const signedTx = getNextTransaction();
  const txStart = performance.now();

  await client.request({
    method: 'eth_sendRawTransactionSync',
    params: [signedTx]
  });

  const txTime = Math.round(performance.now() - txStart);
  // Record result with reaction time + TX time
};

Complete Source Code

For the full game implementation including:

  • Complete game state management
  • Landing page with animated background
  • Results table and statistics
  • Play again functionality

Visit: https://github.com/awesamarth/reaction-time


Running the Game

Fund Your Burner Wallet

Before playing, you need testnet ETH. Visit the RISE Faucet and request funds for your burner wallet address (check the navbar after starting the app).

Start Development Server

npm run dev
yarn dev
pnpm dev
bun run dev

Open your browser and navigate to http://localhost:3000.

Playing the Game

Start the Game

Click the "START GAME" button on the landing page. Wait for "INITIALIZING..." to change to "CLICK TO START".

Round 1

Click the purple box to start. It will turn red with "WAIT..." - don't click yet!

After 1-5 seconds, it turns green with "CLICK NOW!" - click as fast as you can!

Transaction Recording

The box turns yellow with "RECORDING..." while your click is being recorded on the blockchain. This takes only ~3ms!

View Results

After each round, your results appear in the table below:

  • Reaction Time: Your raw reflexes
  • TX Time: How long RISE took to confirm
  • Total Time: Combined time

Complete 5 Rounds

Repeat for rounds 2-5. After the final round, view your FINAL STATS showing averages and blockchain overhead percentage.

The game in action should look like this:

Reaction Time Game

Pro Tip

The average human reaction time is 200-300ms. If your TX time is only 3ms, RISE adds less than 2% overhead to your total response time!


Understanding the Code

Transaction Pool Pattern

Why this works:

  1. Signing is slow (~50ms) - doing it during gameplay adds latency
  2. Pre-signing is instant - transaction is ready to send immediately
  3. Background refilling - pool never runs out during a 5-round game
  4. Synchronous confirmation - eth_sendRawTransactionSync waits for finality

Timing Precision

The game uses performance.now() for microsecond precision:

// When box turns green
greenTimeRef.current = performance.now();

// When user clicks
clickTimeRef.current = performance.now();

// Calculate reaction time
const reactionTime = Math.round(clickTimeRef.current - greenTimeRef.current) - ADJUSTMENT;

The 100ms adjustment accounts for:

  • Browser rendering delays
  • Monitor refresh rate (~16ms at 60Hz)
  • Event propagation time

Performance Insights

What the Game Proves

This game demonstrates three critical points:

  1. Blockchain Can Be Fast: 3ms confirmations are comparable to database writes
  2. Pre-signing Works: Zero-latency gameplay with background pool management
  3. RISE Enables New Use Cases: Gaming, high-frequency trading, realtime auctions

Advanced Optimizations

Background Refilling Strategy

The pool refills at 50% capacity to ensure transactions are always ready:

if (preSignedPool.currentIndex % 5 === 0 && !preSignedPool.hasTriggeredRefill) {
  preSignedPool.hasTriggeredRefill = true;
  const nextNonce = preSignedPool.baseNonce + preSignedPool.transactions.length;

  preSignBatch(nextNonce, 10).then(() => {
    preSignedPool.hasTriggeredRefill = false; // Ready for next refill
  });
}

Why 50% threshold?

  • Signing 10 transactions takes ~500ms
  • Typical game round takes 2-6 seconds
  • Pool will never deplete during gameplay

Security Considerations

Burner Wallet Best Practices

Production Warning

This tutorial uses an exposed private key for simplicity. In production:

  • Use server-side signing with API routes
  • Implement rate limiting to prevent abuse
  • Never expose private keys in client code
  • Consider using threshold signatures or MPC

Next Steps

Congratulations! You've built a realtime blockchain game with 3ms confirmations. Here are some ideas to extend your game:

  1. Multiplayer Mode: Add realtime leaderboards using Shreds events
  2. NFT Rewards: Mint achievement NFTs for top scores
  3. Smart Contract Integration: Record high scores on-chain
  4. Advanced Analytics: Track improvement over time
  5. Tournament Mode: Compete against other players

Resources