# Building NecroOS: A Haunted Windows 95 Simulator with Kiro AI
What if your computer was haunted? Not just buggy—actually possessed. That 2 AM thought turned into NecroOS, a horror game disguised as a Windows 95 desktop simulator. And I built it using Kiro AI's spec-driven development workflow.

🎃 The Concept
NecroOS starts as a comforting Windows 95 desktop—teal wallpaper, chunky pixels, satisfying clicks. But gradually, subtly, things go wrong. Your cursor drifts. The calculator gives you 2+2=5. Files appear in folders you just emptied. The horror isn't in-your-face—it's the creeping dread of familiar technology betraying you.
Live Demo: necro-os.vercel.app
Source Code: github.com/AstaadDahiya/Necro-OS

🛠️ The Tech Stack
- Vue 3 + Pinia for reactive state management
- Google Gemini AI (2.5 Flash) for Cursed Clippy, Spirit Board, and Soul Scanner
- Web Audio API for 4-layer dynamic audio mixing
- 98.css for authentic Windows 95 styling
- Vite for blazing-fast development
- Vercel for deployment
The numbers: 37,529 lines of code, 171 files, 11 functional apps, 4 difficulty modes, multiple endings.
🎯 The Kiro Difference: Spec-Driven Development
Here's where it gets interesting. I didn't just "vibe code" this project. I used Kiro AI's spec-driven workflow, which completely transformed how I build software.
The Traditional Approach (Vibe Coding)
Me: "Add some spooky audio effects"
Kiro: "What kind of effects? How should they trigger?"
Me: "Uh... whispers? When things get scary?"
Kiro: [Generates basic audio player]
Me: "Actually, I need multiple layers that blend dynamically..."
Kiro: [Refactors]
Me: "And it needs to scale with possession level..."
Kiro: [Refactors again]
Result: 3 iterations, inconsistent implementation, no clear architecture.
The Spec-Driven Approach
Instead, I created 4 comprehensive specs that became my project's blueprint:
- necro-os - Base operating system
- necro-os-advanced-haunting - Possession mechanics (22 tasks)
- necro-os-visual-corruption - CRT effects and glitches
- necro-os-progressive-corruption - Level-based haunting
Each spec had three documents:
1. requirements.md - The "What"
Using EARS format (Easy Approach to Requirements Syntax):
## Requirement 1: Possession Level System
**User Story**: As a player, I want the haunting to gradually intensify,
so that I experience escalating horror over time.
**Acceptance Criteria**:
1. THE System SHALL track possession level from 0 to 100
2. WHEN possession reaches 30, THE System SHALL trigger cursor corruption
3. WHILE game runs, THE System SHALL increase possession by 1.5 points/min
2. design.md - The "How"
Technical architecture with formulas:
## Possession Level Formula
$$\Delta P = 1.5 \times m_d \times \frac{\Delta t}{60000}$$
Where:
- $\Delta P$ = possession increase
- $m_d$ = difficulty multiplier (Tourist: 0.5x, Nightmare: 3.0x)
- $\Delta t$ = time elapsed (ms)
## Audio Volume Scaling
$$V(P) = V_{\text{base}} \times (1 + 0.05 \times P)$$
3. tasks.md - The "When"
Actionable implementation checklist:
- [ ] 1. Set up Pinia store structure
- [ ] 2. Implement possession tracking with formula
- Use setInterval for continuous updates
- Apply difficulty multiplier
- _Requirements: 1.1, 1.2, 1.3_
- [ ] 3. Add threshold watchers (30, 45, 70, 80, 100)
The Workflow in Action
Phase 1: Define requirements → "What should it do?"
Phase 2: Design architecture → "How should it work?"
Phase 3: Break into tasks → "What's the implementation order?"
Phase 4: Execute → "Implement task 2.1"
When I said "implement task 2.1", Kiro read all three docs and generated production-ready code with full context. No clarifying questions. No iterations.
💡 Strategic Prompt Engineering
The quality of AI-generated code is directly proportional to the context you provide. Here's what I learned:
❌ Vague Prompt
"Create an audio system"
✅ Precision Prompt
"Create a 4-layer audio haunting system using Web Audio API with independent
gain nodes for ambient, effects, whispers, and tension. Scale volume using
V = baseVolume × (1 + 0.05 × possessionLevel). Handle browser autoplay
restrictions with lazy initialization. Integrate with Pinia advancedHaunting
store for reactive updates."
The result: Kiro generated a complete, optimized audio system in one shot—Web Audio API architecture, gain nodes, volume formulas, autoplay handling, Pinia integration, error handling, and JSDoc documentation.
🎨 The Horror Mechanics
Possession System
Everything revolves around one number: possession level (0-100). It drives all horror effects:
- 30%: Cursor starts drifting
- 45%: Wallpaper flickers
- 70%: Whispers and phantom notifications
- 80%: Heartbeat tension, full chaos
- 100%: Possessed ending
4-Layer Audio System
Instead of random spooky sounds, I built a dynamic audio architecture:
class AudioHauntingService {
layers = {
ambient: { baseVolume: 0.3 }, // Background dread
effects: { baseVolume: 0.5 }, // Phantom typing, HDD grinding
whispers: { baseVolume: 0.2 }, // Barely audible voices
tension: { baseVolume: 0.4 } // Pre-jumpscare heartbeat
}
updateVolume(possessionLevel) {
Object.entries(this.layers).forEach(([name, layer]) => {
const multiplier = 1 + (0.05 * possessionLevel)
const newVolume = layer.baseVolume * multiplier
layer.gainNode.gain.setValueAtTime(newVolume, this.audioContext.currentTime)
})
}
}
Volume scales with possession level, creating audio that responds to gameplay.
Exorcism Mechanics
Players aren't helpless:
- Text Exorcism: Type "begone spirit" (-15 possession)
- File Exorcism: Delete cursed files (-8 possession)
- Puzzle Exorcism: Complete symbol sequences in 30s (-20 possession)
Each has a 2-minute cooldown, creating strategic gameplay.
AI Integration with Gemini
Three apps use Google Gemini AI:
Cursed Clippy: Sarcastic AI assistant with command execution
systemPrompt: `You are Cursed Clippy, a sarcastic AI haunting a Windows 95
desktop. Make references to being trapped. Use 90s internet culture.
Execute commands via [COMMAND:action:target] syntax.`
Spirit Board: Ouija board with AI-generated responses
prompt: `You are a spirit communicating through a Ouija board.
Respond in max 30 characters. Use only letters, numbers, spaces.`
Soul Scanner: Webcam facial expression analysis with Gemini Vision API
prompt: `Analyze this person's expression in one cryptic sentence (max 15 words).
If happy, threaten them. If scared, mock them. If neutral, make eerie observations.`
📊 The Results
Time Comparison:
- Planning with specs: 2 hours
- Implementation: 6 hours (22 tasks)
- Refactoring: 30 minutes
- Total: 8.5 hours
Without specs: Estimated 20+ hours with multiple rewrites
Quality Improvements:
- ✅ Got it right the first time (minimal refactoring)
- ✅ Consistent architecture across all features
- ✅ Built-in documentation
- ✅ Clear definition of "done"
- ✅ Easy to resume after breaks
🎓 Key Lessons
1. Spec-Driven > Vibe Coding for Complex Projects
Specs aren't slower—they're front-loaded thinking. Spend 2 hours planning to save 12 hours refactoring.
2. Specificity Beats Brevity in Prompts
- Bad: "Make it faster"
- Good: "Batch DOM updates using requestAnimationFrame to maintain 60 FPS"
3. Context Persistence is Everything
Specs gave Kiro a complete mental model. Each conversation built on the last. No context loss between sessions.
4. Accessibility in Horror is Possible
I added photosensitivity warnings, reduced motion mode, and keyboard navigation without losing the scary parts.
5. Audio is 50% of Horror
Investing in the Web Audio API multi-layer system paid huge dividends. Simple <audio> tags wouldn't have cut it.
🚀 What's Next
I'm planning:
- Multiplayer haunting where possession spreads between users
- Procedural jumpscare generation using AI
- VR support for truly immersive terror
- More endings based on player choices
💭 Final Thoughts
NecroOS started as a weird 2 AM idea and turned into the most complex project I've built. But the real story isn't the horror game—it's discovering that spec-driven development with AI is a game-changer.
Kiro didn't build NecroOS. I architected it through strategic prompts and specs. Kiro implemented my vision.
That's the difference between "AI wrote my code" and "I used AI as a force multiplier for my ideas."
The haunting is just beginning. 👻
Try it: necro-os.vercel.app
Source: github.com/AstaadDahiya/Necro-OS
Built with: Vue 3, Gemini AI, Kiro, and way too much coffee ☕
Top comments (0)