# Implementation (/docs/cookbook/reaction-time-game/implementation)



import { Tabs, Tab } from 'fumadocs-ui/components/tabs';
import { Steps, Step } from 'fumadocs-ui/components/steps';
import { Callout } from 'fumadocs-ui/components/callout';

## 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](https://github.com/awesamarth/reaction-time). 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

```typescript title="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](https://github.com/awesamarth/reaction-time)

***

## Running the Game

### Fund Your Burner Wallet

Before playing, you need testnet ETH. Visit the [RISE Faucet](https://faucet.testnet.riselabs.xyz) and request funds for your burner wallet address (check the navbar after starting the app).

### Start Development Server

<Tabs items={['npm', 'yarn', 'pnpm', 'bun']} groupId="package-manager">
  <Tab value="npm">
    ```bash
    npm run dev
    ```
  </Tab>

  <Tab value="yarn">
    ```bash
    yarn dev
    ```
  </Tab>

  <Tab value="pnpm">
    ```bash
    pnpm dev
    ```
  </Tab>

  <Tab value="bun">
    ```bash
    bun run dev
    ```
  </Tab>
</Tabs>

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

### Playing the Game

<Steps>
  <Step>
    ### Start the Game

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

  <Step>
    ### 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!
  </Step>

  <Step>
    ### Transaction Recording

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

  <Step>
    ### 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
  </Step>

  <Step>
    ### Complete 5 Rounds

    Repeat for rounds 2-5. After the final round, view your **FINAL STATS** showing averages and blockchain overhead percentage.
  </Step>
</Steps>

The game in action should look like this:

<img alt="Reaction Time Game" src={__img0} placeholder="blur" />

<Callout type="info" title="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!
</Callout>

***

## Understanding the Code

### Transaction Pool Pattern

<Mermaid
  chart="sequenceDiagram
    participant Game
    participant Pool
    participant RISE

    Note over Game,Pool: Initialization
    Game->>Pool: Pre-sign 10 transactions
    Pool->>Pool: Store signed txs
    Game->>Game: Ready to play!

    Note over Game,RISE: During Gameplay
    Game->>Pool: Get next transaction
    Pool->>Game: Return pre-signed tx
    Game->>RISE: eth_sendRawTransactionSync
    RISE->>Game: Confirmed in 3ms!

    Note over Pool: Background Refill
    Pool->>Pool: At 50% capacity
    Pool->>Pool: Pre-sign 10 more txs"
/>

**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:

```typescript
// 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:

```typescript
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

<Callout type="warn" title="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
</Callout>

## 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

### Related Tutorials

* [Shred Ninja](/docs/cookbook/shred-ninja) - Realtime event monitoring
* [RISEx Trading Bot](/docs/cookbook/risex-telegram-bot) - Build a Telegram perp trading bot
* [Deploy Your First Contract](/docs/cookbook/deploy-first-contract) - Smart contract deployment

### Resources

* [GitHub Repository](https://github.com/awesamarth/reaction-time) - Complete source code
* [Shreds Documentation](/docs/builders/shreds) - Complete Shreds API reference
* [RISE Testnet Details](/docs/builders/testnet-details) - Network information
* [Viem Documentation](https://viem.sh) - Ethereum client library
* [RISE Faucet](https://faucet.testnet.riselabs.xyz) - Get testnet ETH
