# Implementation (/docs/cookbook/shred-ninja/implementation)



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

## Game Implementation

The complete Shred Ninja implementation can be found in the [GitHub repository](https://github.com/awesamarth/shred-ninja). We'll cover the key concepts here.

### Key Implementation Concepts

**Shreds Subscription:**

```typescript
const client = createPublicClient({
  chain: riseTestnet,
  transport: webSocket('wss://testnet.riselabs.xyz/ws'),
}).extend(shredActions)

const unwatch = client.watchShreds({
  includeStateChanges: false,
  onShred: (shred) => {
    // Process realtime events
  },
})
```

**Event Filtering:**

* Filter logs by Transfer event signature
* Match against USDC and USDT contract addresses
* Extract and process only relevant transfers
* Deduplicate using transaction hash + log index

**Progressive Difficulty:**

```typescript
// Show fewer events at low scores
if (currentScore < 25) {
  shouldSpawn = eventCounter % 3 === 0; // Every 3rd event
} else if (currentScore < 50) {
  shouldSpawn = eventCounter % 2 === 0; // Every 2nd event
} else {
  shouldSpawn = true; // Every event
}
```

**Audio Synthesis:**

```typescript
const playTone = (frequency: number, duration: number) => {
  const audioContext = new AudioContext();
  const oscillator = audioContext.createOscillator();
  oscillator.frequency.value = frequency;
  oscillator.type = "sine";
  oscillator.start();
  oscillator.stop(audioContext.currentTime + duration);
};

sounds.tap = () => {
  playTone(523, 0.1); // C5
  playTone(659, 0.1, 0.05); // E5
};
```

**Framer Motion Animation:**

```typescript
<motion.div
  initial={{ y: -80, x: token.x }}
  animate={{ y: window.innerHeight + 80 }}
  exit={{ scale: 0, opacity: 0 }}
  transition={{ duration: 5, ease: "linear" }}
  onClick={() => handleTap(token)}
>
  {token.type === "USDC" ? "C" : "T"}
</motion.div>
```

### Complete Source Code

For the full implementation including:

* Complete Shreds subscription setup
* Game state management
* Audio synthesis functions
* Progressive difficulty system
* Token animation and collision detection

Visit: [https://github.com/awesamarth/shred-ninja](https://github.com/awesamarth/shred-ninja)

***

## Running and Testing

### Start the Development Server

<Steps>
  <Step>
    ### Run the App

    <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 `http://localhost:3000` in your browser.
  </Step>

  <Step>
    ### How to Play

    * Green tokens (USDC transfers) = **TAP THEM**
    * Red tokens (USDT transfers) = **AVOID THEM**
    * Miss 10 green tokens = Game over
    * Tap a red token = Game over
    * Difficulty increases with your score
  </Step>

  <Step>
    ### Understanding What You See

    Every token represents a real blockchain transfer happening on RISE Testnet at that moment. The 3-5ms latency makes it feel like a traditional web app, not blockchain!
  </Step>
</Steps>

When running, the game should look like this:

<img alt="Shred Ninja Gameplay" src={__img0} placeholder="blur" />

***

## How It Works

### Event Flow Timeline

1. **Tx execution**: 0ms
2. **Shred delivered**: 3-5ms
3. **Token spawns**: 5-10ms (including React render)
4. **Player sees token**: 10-15ms after blockchain event

This demonstrates RISE's capability: events arrive fast enough for interactive gaming!

### Deduplication Strategy

```typescript
const processedTokens = new Set<string>();

// Create unique ID
const tokenId = `${tx.hash}-${log.logIndex}`;
if (processedTokens.has(tokenId)) return;
processedTokens.add(tokenId);
```

Prevents the same transfer from spawning multiple tokens if delivered in multiple shreds.

### Miss Detection

```typescript
// Set timeout when token spawns
const missTimeout = setTimeout(() => {
  if (tokenType === "USDC") {
    setMisses((m) => {
      const newMisses = m + 1;
      if (newMisses >= 10) {
        sounds.gameOver();
        setStatus("gameOver");
      }
      return newMisses;
    });
  }
  setTokens((prev) => prev.filter((t) => t.id !== tokenId));
}, 4500); // Match animation duration
```

Tapping clears the timeout; reaching bottom increments miss counter.

***

## Customization Ideas

### Adjust Difficulty

Modify the difficulty thresholds:

```typescript
if (currentScore < 10) {
  shouldSpawn = eventCounter % 4 === 0; // Easier
} else if (currentScore < 30) {
  shouldSpawn = eventCounter % 2 === 0;
} else {
  shouldSpawn = true; // Harder
}
```

### Add More Token Types

Monitor additional ERC20 contracts:

```typescript
const USDC_ADDRESS = "0x...";
const USDT_ADDRESS = "0x...";
const DAI_ADDRESS = "0x..."; // New token

// In onShred callback
const tokenType =
  log.address.toLowerCase() === USDC_ADDRESS ? "USDC" :
  log.address.toLowerCase() === USDT_ADDRESS ? "USDT" :
  log.address.toLowerCase() === DAI_ADDRESS ? "DAI" : null;
```

### Change Animation Speed

Adjust the falling speed:

```typescript
<motion.div
  transition={{ duration: 3, ease: "linear" }} // Faster
>
```

Remember to match the timeout duration!

***

## Next Steps

Congratulations! You've built a realtime blockchain game. You now understand how to:

* Establish WebSocket connections to RISE Testnet
* Subscribe to blockchain events with `watchShreds`
* Filter and process ERC20 transfer events
* Handle event deduplication
* Build realtime UIs powered by blockchain data

### Ideas to Extend

1. **Leaderboards**: Record high scores with player addresses
2. **Multiplayer**: Show other players' scores in realtime
3. **NFT Rewards**: Mint achievement NFTs for milestones
4. **Custom Tokens**: Let users choose which tokens to monitor
5. **Sound Effects**: Add unique sounds for different token types

### Related Tutorials

* [Reaction Time Game](/docs/cookbook/reaction-time-game) - 3ms transaction confirmations
* [RISE Wallet Demo](/docs/cookbook/rise-wallet-quickstart) - Wallet integration patterns
* [RISEx Telegram Bot](/docs/cookbook/risex-telegram-bot) - AI trading bot

### Resources

* [GitHub Repository](https://github.com/awesamarth/shred-ninja) - Complete source code
* [Shreds Documentation](/docs/builders/shreds) - Complete API reference
* [Shreds Quickstart](/docs/builders/shreds/quickstart) - Quick intro
* [Viem Documentation](https://viem.sh) - Ethereum library
* [Framer Motion Docs](https://www.framer.com/motion/) - Animation library
* [RISE Testnet Details](/docs/builders/testnet-details) - Network info
