<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Shahen</title>
    <description>The latest articles on Forem by Shahen (@shahen0x).</description>
    <link>https://forem.com/shahen0x</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3634819%2F3e9c4b76-d3d9-44c6-a0bd-2e2f33f44a01.jpeg</url>
      <title>Forem: Shahen</title>
      <link>https://forem.com/shahen0x</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/shahen0x"/>
    <language>en</language>
    <item>
      <title>Building a Horror Typing Game Where Blinking Kills You</title>
      <dc:creator>Shahen</dc:creator>
      <pubDate>Tue, 02 Dec 2025 16:21:12 +0000</pubDate>
      <link>https://forem.com/shahen0x/building-a-horror-typing-game-where-blinking-kills-you-229l</link>
      <guid>https://forem.com/shahen0x/building-a-horror-typing-game-where-blinking-kills-you-229l</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Imagine you're typing as fast as you can, trying to complete a horror story. But there's a catch. Every time you blink, a monster teleports closer. And you can't stop blinking.&lt;/p&gt;

&lt;p&gt;This game is designed to strengthen your typing ability through immersive, pressure-based learning. By eliminating the habit of looking at the keyboard and encouraging rapid, accurate input, it helps you develop true touch-typing proficiency in a way traditional tools don’t.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flmaauw35fgu14tdezb5q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flmaauw35fgu14tdezb5q.png" alt="Main Menu" width="800" height="448"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr2iotbcw3yey5o84zep4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr2iotbcw3yey5o84zep4.png" alt="Intro" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhl94xmyj0vha7xgh6gng.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhl94xmyj0vha7xgh6gng.png" alt="Game" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F565i0pdes7zbl0zn5os8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F565i0pdes7zbl0zn5os8.png" alt="Cases" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frmft4ole8bqby21g83hj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frmft4ole8bqby21g83hj.png" alt="Case" width="800" height="453"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fua5ujlyfu7c4wv2tt2nk.png" alt="Leaderboard" width="800" height="449"&gt;
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Core Pillars
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A full typing game with character-by-character validation&lt;/li&gt;
&lt;li&gt;Daily AI generated stories(cases) and typing challenges&lt;/li&gt;
&lt;li&gt;Browse old cases from the asylum, read spooky stories and play the challenge&lt;/li&gt;
&lt;li&gt;Real-time webcam face detection with calibration system for accurate blink detection&lt;/li&gt;
&lt;li&gt;A Unity WebGL game for a more immersive experience&lt;/li&gt;
&lt;li&gt;Two-way communication between React and Unity&lt;/li&gt;
&lt;li&gt;FMOD audio integration for that horror atmosphere&lt;/li&gt;
&lt;li&gt;Leaderboard with realtime player high scores&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Tech Stack
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Frontend:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Next.js 15 with App Router&lt;/li&gt;
&lt;li&gt;React 19&lt;/li&gt;
&lt;li&gt;TypeScript&lt;/li&gt;
&lt;li&gt;Tailwind CSS v4&lt;/li&gt;
&lt;li&gt;shadcn/ui components&lt;/li&gt;
&lt;li&gt;Zustand for state management&lt;/li&gt;
&lt;li&gt;React-unity-webgl package&lt;/li&gt;
&lt;li&gt;Google MediaPipe&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Backend:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Convex backend&lt;/li&gt;
&lt;li&gt;Authentication&lt;/li&gt;
&lt;li&gt;Anthropic AI SDK&lt;/li&gt;
&lt;li&gt;Recraft image generation API&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Game Engine&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Unity 6&lt;/li&gt;
&lt;li&gt;FMOD Studio for audio&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Development Tools:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Kiro IDE with specs, steering rules, agent hooks, and MCP servers&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Team
&lt;/h2&gt;

&lt;p&gt;We're two brothers from Mauritius with a shared passion for gaming and programming. Over the years, we've spent countless hours experimenting, learning, and building. Whether it's software, web platforms, or the games we've always dreamed of creating. Our goal is simple: make things people genuinely enjoy using and playing.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Kiro Specs Changed Everything
&lt;/h2&gt;

&lt;p&gt;Hackathons demand quick decisions under pressure. Features pile up fast, and without a solid direction, things fall apart just as quickly. When issues like unstable blink detection and unpredictable Unity behaviour began slowing progress, Kiro Specs provided the clarity and structure needed to keep the project on track. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Finishing a project of this scope in just 18 days simply wouldn’t have been possible without it.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Three-Document Pattern
&lt;/h3&gt;

&lt;p&gt;Every feature we built followed the same pattern:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;requirements.md&lt;/strong&gt; - What are we building? What does "done" look like?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;design.md&lt;/strong&gt; - How are we building it? What are the algorithms?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;tasks.md&lt;/strong&gt; - What are the exact steps to implement it?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This might sound like overkill for a hackathon, but it actually saved us time. When you're sleep-deprived at 2 AM and trying to remember how the Eye Aspect Ratio calculation works, having it documented in &lt;code&gt;design.md&lt;/code&gt; is a lifesaver.&lt;/p&gt;

&lt;h3&gt;
  
  
  Real Example: The Blink Detector Spec
&lt;/h3&gt;

&lt;p&gt;Let's look at how we specced out the blink detection system. This was one of our most complex features.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;From requirements.md:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;### Requirement 3: Eye Aspect Ratio Calculation&lt;/span&gt;

&lt;span class="gs"&gt;**User Story:**&lt;/span&gt; As a developer, I want the system to calculate Eye Aspect Ratio (EAR) 
from facial landmarks, so that eye openness can be quantified.

&lt;span class="gu"&gt;#### Acceptance Criteria&lt;/span&gt;
&lt;span class="p"&gt;
1.&lt;/span&gt; THE system SHALL use MediaPipe face mesh landmark indices for left eye 
   (33, 133, 159, 145, 160, 144) and right eye (362, 263, 386, 374, 385, 380)
&lt;span class="p"&gt;2.&lt;/span&gt; WHEN facial landmarks are detected, THE system SHALL calculate EAR using 
   the formula: (vertical1 + vertical2) / (2.0 &lt;span class="err"&gt;*&lt;/span&gt; horizontal)
&lt;span class="p"&gt;3.&lt;/span&gt; THE system SHALL calculate Euclidean distance in 3D space (x, y, z) for landmark pairs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice the EARS format (Event-Action-Response-State). It's precise. It's testable. When we implemented the hook, we knew exactly what success looked like.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;From design.md:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;### P4: Blink Detection State Machine&lt;/span&gt;

&lt;span class="gs"&gt;**Property:**&lt;/span&gt; A valid blink follows the state machine: 
open → closing → closed (2-15 frames) → opening → open

&lt;span class="gs"&gt;**Verification:**&lt;/span&gt; State transitions follow defined rules, 
blink count only increments on complete cycle

&lt;span class="gs"&gt;**Covers:**&lt;/span&gt; AC4.1, AC4.2, AC4.3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The design doc gave us the algorithm. We didn't have to figure out blink detection logic on the fly. We had already thought through edge cases like "what if someone holds their eyes closed for 3 seconds?" (that's drowsiness, not a blink).&lt;/p&gt;

&lt;h3&gt;
  
  
  The Monster Teleportation System
&lt;/h3&gt;

&lt;p&gt;Here's another example. The monster needed to teleport closer with each blink, then sprint at you on the final one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;From requirements.md:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;### AC3: Blink Teleportation&lt;/span&gt;

&lt;span class="gs"&gt;**Given**&lt;/span&gt; the player has more than 1 life remaining  
&lt;span class="gs"&gt;**When**&lt;/span&gt; the player blinks (blink event received from React)  
&lt;span class="gs"&gt;**Then**&lt;/span&gt; the player should lose 1 life  
&lt;span class="gs"&gt;**And**&lt;/span&gt; the monster should teleport closer to the camera by a calculated distance  
&lt;span class="gs"&gt;**And**&lt;/span&gt; the calculated distance should be: (startingDistance - goalDistance) / (lives - 1)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;From design.md:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;### P3: Teleport Distance Accuracy&lt;/span&gt;

&lt;span class="gs"&gt;**Property:**&lt;/span&gt; Each teleport moves monster by exactly 
(startingDistance - goalDistance) / (lives - 1)

&lt;span class="gs"&gt;**Verification:**&lt;/span&gt; Distance change per blink equals calculated teleportDistance ± 0.01

&lt;span class="gs"&gt;**Covers:**&lt;/span&gt; AC3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With 5 lives, starting at 10 units and a goal of 2 units, each blink moves the monster exactly 2 units closer. Math done once, documented forever.&lt;/p&gt;

&lt;h2&gt;
  
  
  Steering Rules: Your AI Copilot's Memory
&lt;/h2&gt;

&lt;p&gt;Specs handle individual features. But what about project-wide standards? That's where steering rules come in.&lt;/p&gt;

&lt;p&gt;We created steering files for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Project vision&lt;/strong&gt; - Understand the grand vision of the project&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unity development standards&lt;/strong&gt; - Unity 6.1 patterns, Input System usage, lifecycle methods&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;State management&lt;/strong&gt; - When to use Zustand vs useState, store patterns&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Import aliases&lt;/strong&gt; - Always use &lt;code&gt;@/&lt;/code&gt; paths, never relative imports&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;shadcn/ui components&lt;/strong&gt; - Always check if a component exists before building custom&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's a snippet from our Unity steering rule:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;### Cache Component References&lt;/span&gt;

// ✅ Correct - Cache in Awake/Start
private Rigidbody rb;

void Awake()
{
    rb = GetComponent&lt;span class="nt"&gt;&amp;lt;Rigidbody&amp;gt;&lt;/span&gt;();
}

// ❌ Wrong - GetComponent every frame
void Update()
{
    GetComponent&lt;span class="nt"&gt;&amp;lt;Rigidbody&amp;gt;&lt;/span&gt;().AddForce(Vector3.up);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every time Kiro helped us write Unity code, it followed these patterns automatically. No more explaining the same best practices over and over.&lt;/p&gt;

&lt;h2&gt;
  
  
  Agent Hooks: Automation That Actually Helps
&lt;/h2&gt;

&lt;p&gt;We set up an agent hook that validates spec traceability whenever we save a spec file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"On Spec Update - Validate Traceability"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"when"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fileEdited"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"patterns"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"**/{requirements.md,design.md,tasks.md}"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"then"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"askAgent"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"prompt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Analyze the spec files and validate traceability..."&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every time we saved a spec file, Kiro would check:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Does every requirement have a corresponding property?&lt;/li&gt;
&lt;li&gt;Does every property have a task that implements it?&lt;/li&gt;
&lt;li&gt;Are there any orphaned elements?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This caught gaps we would have missed. Like when we added a new acceptance criterion but forgot to update the design properties.&lt;/p&gt;

&lt;h2&gt;
  
  
  MCP Integrations: The Secret Weapons
&lt;/h2&gt;

&lt;p&gt;Kiro's MCP (Model Context Protocol) support turned out to be one of our most valuable tools. We integrated several MCP servers that dramatically improved our development workflow.&lt;/p&gt;

&lt;h3&gt;
  
  
  Browser Automation for Real Testing
&lt;/h3&gt;

&lt;p&gt;Since our game runs in the browser and involves webcam access, blink detection, and Unity WebGL, we needed to test everything in a real browser environment. Checking if code compiles isn't enough when you're dealing with MediaPipe initialization, webcam permissions, and Unity-React communication.&lt;/p&gt;

&lt;p&gt;With browser automation, Kiro could actually:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open the game in a real browser&lt;/li&gt;
&lt;li&gt;Check console logs for errors&lt;/li&gt;
&lt;li&gt;Verify that components were rendering correctly&lt;/li&gt;
&lt;li&gt;Test the webcam permission flow&lt;/li&gt;
&lt;li&gt;Debug Unity WebGL loading issues&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This was especially helpful for catching issues that only appear at runtime. Things like MediaPipe failing to initialize, Unity events not reaching React, or the webcam feed not displaying. These are problems you simply can't catch without running the app in an actual browser.&lt;/p&gt;

&lt;h3&gt;
  
  
  Convex Documentation via Context7
&lt;/h3&gt;

&lt;p&gt;We relied heavily on the Convex documentation through Context7 MCP. Building the backend for daily story generation, leaderboards, and case management became much smoother when Kiro had direct access to up-to-date Convex docs.&lt;/p&gt;

&lt;p&gt;Instead of context-switching to browser tabs and copy-pasting examples, we could ask Kiro to implement features and it would pull the correct patterns directly from the documentation. This helped us implement features like scheduled story generation and real-time leaderboard updates with almost no mistakes.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Development Loop
&lt;/h3&gt;

&lt;p&gt;The combination of these MCP integrations created a tight feedback loop:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Write code with Kiro (using Convex docs for backend patterns)&lt;/li&gt;
&lt;li&gt;Kiro opens the browser and tests the changes&lt;/li&gt;
&lt;li&gt;If something breaks, Kiro reads the console logs&lt;/li&gt;
&lt;li&gt;Fix and repeat&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;During a hackathon where every minute counts, automating this loop saved us hours of manual testing and debugging.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Typing Game: Character-by-Character Precision
&lt;/h2&gt;

&lt;p&gt;The typing game needed to feel responsive. Every keystroke matters when a monster is breathing down your neck.&lt;/p&gt;

&lt;p&gt;From our design doc:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;### Natural Typing with Error Correction (Improvement 7)&lt;/span&gt;

&lt;span class="gs"&gt;**Core Principle**&lt;/span&gt;: Users can type freely, including mistakes. 
The system provides visual feedback for errors but allows the full input to remain, 
enabling natural self-correction with backspace.

&lt;span class="gs"&gt;**Typing Behavior**&lt;/span&gt;:
&lt;span class="p"&gt;1.&lt;/span&gt; Users can type any characters, including incorrect ones
&lt;span class="p"&gt;2.&lt;/span&gt; The cursor advances with each character typed (correct or incorrect)
&lt;span class="p"&gt;3.&lt;/span&gt; Visual feedback shows which characters are correct (green) and incorrect (red)
&lt;span class="p"&gt;4.&lt;/span&gt; Users can use backspace to delete characters and correct their mistakes
&lt;span class="p"&gt;5.&lt;/span&gt; Only when the entire word is typed correctly can users press Space/Enter to advance
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We went through 7 iterations of the typing mechanics. Each improvement was documented, so we could trace why we made certain decisions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Unity and React: Two Worlds, One Game
&lt;/h2&gt;

&lt;p&gt;The trickiest part was getting Unity and React to talk to each other. Unity handles the 3D horror scene. React handles the typing game and blink detection.&lt;/p&gt;

&lt;p&gt;From our interop spec:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;### Requirement 2: GameIsReady Event&lt;/span&gt;

&lt;span class="gs"&gt;**User Story:**&lt;/span&gt; As React, I want to know when Unity is ready, so that I can show the game.

&lt;span class="gu"&gt;#### Acceptance Criteria&lt;/span&gt;
&lt;span class="p"&gt;
1.&lt;/span&gt; THE React.jslib SHALL define a GameIsReady function
&lt;span class="p"&gt;2.&lt;/span&gt; THE function SHALL call window.dispatchReactUnityEvent("GameIsReady")
&lt;span class="p"&gt;3.&lt;/span&gt; THE MainMenuManager SHALL call GameIsReady() in Start()
&lt;span class="p"&gt;4.&lt;/span&gt; THE call SHALL only execute in WebGL builds (not in Editor)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Simple, clear, testable. When something broke in the Unity-React communication, we knew exactly where to look.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI-Generated Horror Stories
&lt;/h2&gt;

&lt;p&gt;Every 24 hours, Claude generates a new horror story for players to type. The spec made this straightforward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;### Requirement 2: Story Generation Action&lt;/span&gt;

&lt;span class="gu"&gt;#### Acceptance Criteria&lt;/span&gt;
&lt;span class="p"&gt;
1.&lt;/span&gt; WHEN the generation action runs, THE system SHALL call Claude API with the prompt
&lt;span class="p"&gt;2.&lt;/span&gt; THE system SHALL use Claude tool use to enforce the Story interface format
&lt;span class="p"&gt;3.&lt;/span&gt; IF generation fails, THEN THE system SHALL retry up to 3 times with 5 minute delays
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The story has a title, introduction, and 8 progressive chapters. Each chapter has a difficulty level. Players type through the story while the monster gets closer with every blink.&lt;/p&gt;

&lt;h2&gt;
  
  
  What We Learned
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Specs aren't bureaucracy.&lt;/strong&gt; They're thinking tools. Writing requirements forces you to actually understand what you're building before you build it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Steering rules compound.&lt;/strong&gt; Every rule we added made Kiro more helpful. By the end of the hackathon, it felt like working with a teammate who actually remembered our coding standards.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Agent hooks catch mistakes early.&lt;/strong&gt; The traceability check saved us from shipping incomplete features multiple times.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Documentation is debugging.&lt;/strong&gt; When something broke, we could read our own design docs instead of reverse-engineering our code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It Yourself
&lt;/h2&gt;

&lt;p&gt;Type to Death is live. See how long you can survive without blinking.&lt;br&gt;
&lt;a href="//type-to-death.vercel.app"&gt;Play Game&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And if you're building something complex, give Kiro specs a try. Start with one feature. Write the requirements, design the solution, break it into tasks. You might be surprised how much clearer everything becomes.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built during Kiroween Hackathon by two brothers from Mauritius who probably should have blinked less during testing.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>kiro</category>
      <category>kiroween</category>
      <category>kirodotdev</category>
      <category>gamedev</category>
    </item>
  </channel>
</rss>
