This is a submission for the Sanity Challenge, Path Two: Vibe-Code Something Strange
What I Built
NOVA AI Civilization Lab is an AI-powered civilization simulation where a small virtual society evolves through structured world events, AI-generated citizen reactions, and human decisions.
The civilization currently contains 8 citizens with different occupations, personalities, goals, moods, energy levels, locations, and relationships. It also contains important infrastructure such as the Town Hall, General Hospital, Power Station, Central School, and Market. This structured world state is stored in the Sanity Content Lake.
When an event happens — such as a city-wide blackout, an emergency supply shortage, or a communication network failure — NOVA sends the current world state to an AI model. The AI generates a contextual reaction for every citizen, including a proposed action, rationale, mood change, and energy change.
But the AI cannot directly decide what becomes part of the world.
Every AI proposal enters a human approval queue, where I can approve or reject it. Approved reactions modify the citizen's persistent state in Sanity, while rejected proposals do not affect the civilization. Once all decisions are complete, the world event can be resolved and the resulting state becomes the starting point for future events.
This means later simulations operate on the consequences of earlier human decisions instead of starting from a blank prompt every time.
The project combines Next.js, TypeScript, Sanity, and Groq to experiment with a simple idea:
AI proposes. Humans decide. Sanity remembers.
I built NOVA as an experiment in human-controlled AI simulation: rather than using AI only to generate isolated text, I wanted to see what happens when AI operates over a persistent, structured world while a human remains responsible for deciding which generated actions become reality.
Demo
🚀 Live Application:
https://nova-ai-civilization.vercel.app
🧠 Sanity Studio:
https://nova-ai-civilization.vercel.app/studio
The deployed application demonstrates the complete NOVA simulation loop:
- A structured world event is created in Sanity.
- The event appears immediately in the NOVA World Control dashboard.
- The AI analyzes the event together with the current citizens and world state.
- It generates individual proposed reactions for all 8 citizens.
- Each proposal includes an action, AI rationale, proposed mood, and energy change.
- I manually approve or reject each AI proposal.
- Approved decisions update the citizen's persistent state.
- After all decisions are reviewed, the event can be resolved.
- The resulting civilization state becomes context for future simulations.
For example, during the NOVA Communication Failure event, the AI generated different responses based on each citizen's role and personality. The Power Engineer investigated infrastructure diagnostics, the Mayor organized an emergency council, the Police Officer organized a manual patrol network, and the Student became curious about the engineering problem.
I deliberately approved some proposals and rejected others. The dashboard then reflected only the approved state changes, demonstrating the project's central human-in-the-loop design.
Simulation Flow
World Event → AI Simulation → Citizen Proposals → Human Approval / Rejection → Persistent Sanity State → Next Event
The deployed dashboard also exposes the live citizen network and infrastructure state stored in the Sanity Content Lake.
1. World Event Created — NOVA Water System Failure
2. AI Simulation Complete — 8 Citizen Responses Generated
3. Human Review — AI Proposals Awaiting Decisions
4. Human Decisions — Approved and Rejected AI Proposals
5. Decisions Complete — Event Ready for Resolution
6. Event Resolved — Persistent World State Continues
Code
💻 GitHub Repository:
https://github.com/mahilanjp/nova-ai-civilization
The project is built with Next.js, TypeScript, Sanity, and Groq.
The codebase includes:
- A Next.js frontend for the NOVA World Control dashboard
- An embedded Sanity Studio at
/studio - Structured Sanity schemas for citizens, locations, relationships, world events, and citizen reactions
- Server-side API routes for AI simulation and state mutations
- Groq-powered generation of citizen reactions
- Human approval/rejection endpoints that determine which AI proposals become part of the persistent world state
- Event resolution logic that allows the civilization to progress through multiple simulations
Sensitive credentials such as the Groq API key and Sanity write token are stored as environment variables and are not committed to the repository.
My Build Process
I built NOVA as an AI-assisted project using ChatGPT together with VS Code. Instead of asking the AI to generate the entire application in one prompt, I developed it incrementally: architecture first, then the Sanity data model, simulation engine, human approval system, UI, testing, and deployment.
Starting With the World Model
The first important decision was to avoid treating the civilization as one large block of AI-generated text.
I modeled the world as structured Sanity content:
- Citizens
- Locations
- Relationships
- World Events
- Citizen Reactions
Each citizen has persistent attributes such as occupation, personality, goal, mood, energy, status, and location. Locations also maintain infrastructure state.
This allowed the AI to reason about structured world state while Sanity remained the source of truth.
Building the AI Simulation Loop
The next challenge was connecting a world event to AI-generated citizen behavior.
When an event is simulated, a Next.js server route reads the current event, citizens, relationships, and world state from Sanity and sends the relevant context to Groq.
The AI must return structured reaction proposals rather than unrestricted prose.
For each citizen, it proposes:
- A reaction
- A user-facing rationale
- A new mood
- An energy change
- Other relevant state changes
The proposals are then written back to Sanity as pending Citizen Reaction documents.
Keeping a Human in the Loop
I did not want AI output to automatically become reality in the simulation.
Every generated reaction enters an approval queue.
I can Approve or Reject each proposal individually. Approved proposals modify persistent citizen state, while rejected proposals remain recorded but do not change the citizen.
Only after the decisions are complete can the world event be resolved.
This created the core loop:
Event → AI proposals → Human decisions → State mutation → Persistent world → Next event
The next simulation therefore operates on a world affected by previous decisions.
Things That Did Not Work the First Time
The build process had several failures and course corrections.
One of the first AI integration attempts failed because the Groq model I initially configured was no longer available. The API returned a model-related error, so I investigated the failure and switched the simulation route to an available model.
I also encountered a confusing issue where Sanity updates succeeded but the dashboard sometimes displayed older data. The problem came from cached reads. I changed the Sanity client configuration to avoid stale CDN results for the live simulation dashboard.
Another issue appeared while building the event resolution API. The frontend expected JSON, but an incorrect/missing API route returned an HTML error page instead, producing an error similar to:
Unexpected token '<', "<!DOCTYPE "... is not valid JSON
I traced the request path, corrected the Next.js API route structure, and retested the complete resolution flow.
Filtering also needed improvement. After running multiple events, reactions from an earlier event could appear alongside the current event. I changed the dashboard query logic so the AI decision queue is scoped to the active event.
Deployment produced another useful debugging step. I connected the GitHub repository to Vercel, configured the required environment variables, and deployed the Next.js application. I then registered the deployed /studio URL with Sanity so the embedded production Studio could access the project correctly.
Testing the Civilization Across Multiple Events
I tested the system with several events rather than stopping after the first successful AI response.
Examples included:
- The Great NOVA Blackout
- Emergency Supply Shortage
- NOVA Recovery Initiative
- NOVA Communication Failure
This let me verify that citizen state persists between simulations.
During the NOVA Communication Failure, for example, the AI proposed role-specific behavior for the Mayor, Power Engineer, Police Officer, Doctor, Teacher, Journalist, Shopkeeper, and Student.
I intentionally approved some proposals and rejected others to verify that only approved decisions affected persistent state.
After all eight proposals were reviewed, the event became eligible for resolution. Resolving it cleared the active event and decision queue while preserving the resulting citizen state.
What AI Helped With
AI helped me reason through architecture, generate and refine implementation code, debug API failures, improve the simulation prompt, and iterate on the dashboard.
However, I did not treat generated code or generated world decisions as automatically correct.
I tested each major step, inspected errors, changed the implementation when something failed, and kept human approval as an explicit part of the simulation itself.
That process also influenced the final idea behind NOVA: AI can propose how a world evolves, but a human decides which proposals become canon.
Sanity Project Details
🧩 Sanity Project: NOVA AI Civilization Lab
Project ID: 4anu1sha
Dataset: production
Embedded Sanity Studio:
https://nova-ai-civilization.vercel.app/studio
Sanity is not used only as a CMS for static content in NOVA. It acts as the persistent structured memory and state layer for the simulated civilization.
The Content Lake stores five interconnected document types:
- Citizen — identity, occupation, personality, goals, mood, energy, status, and current location
- Location — city locations and their infrastructure state, including condition, power availability, capacity, and importance
- Relationship — directional relationships between citizens, including relationship type, trust, affinity, and notes
- World Event — events affecting the civilization, including event type, severity, affected locations, lifecycle status, and world impact
- Citizen Reaction — AI-generated responses linked to both a citizen and a world event, including the proposed action, rationale, state changes, and human approval status
These references allow NOVA to query the civilization as a connected structured world rather than reconstructing everything from unstructured AI conversation history.
The simulation reads the current state from Sanity before generating AI proposals. Human-approved decisions are then written back to Sanity, making those changes persistent context for later events.
This means Sanity functions as the civilization's evolving source of truth:
Structured Content → AI Reasoning → Human Approval → Sanity Mutation → New World State
The Sanity Studio is embedded directly inside the deployed Next.js application at /studio, where the underlying citizens, locations, relationships, events, and reactions can be inspected.
What I Learned
Building NOVA changed how I think about AI applications.
The most interesting part was not generating more text — it was deciding what AI should be allowed to change.
By combining structured Sanity data with AI-generated proposals and explicit human approval, NOVA separates AI reasoning from authoritative state changes. The model can suggest how citizens respond, but it cannot silently rewrite the civilization.
I also learned that persistent structured state makes simulations much more interesting. Each event can build on the consequences of previous events instead of resetting the world for every prompt.
There is still much more I could explore: richer relationships, longer-term memories, infrastructure recovery, economic systems, autonomous event generation, and more complex world rules.
For this challenge, though, I wanted to build one complete idea end-to-end:
AI proposes. Humans decide. Sanity remembers.
Thanks for exploring NOVA AI Civilization Lab.






Top comments (0)