Tickd.ai
← The Tickd Guide

Inspiration

How to Build a Generative Cryptid Sighting Tracker for a Fictional 1970s Town Using Claude and Python

Ditch the boring boilerplate databases. Learn how to use Python and Claude to construct a procedurally generated municipal archive of eerie, interconnected cryptid sightings in a fictional 1970s Pacific Northwest logging town.

Updated 9/15/2026

The Charm of Municipal Weirdness

Building another CRUD app to track tasks or manage a hypothetical inventory is a brilliant way to bore yourself to tears. If you want to actually push the boundaries of structured LLM outputs, you need a project with a bit more grit.

We are going to build a procedural archive tracker for Blackwood Pines—a fictional, rain-slicked logging town in the Pacific Northwest, circa 1974. The town is plagued by something strange in the treeline, and the local sheriff’s department is overwhelmed with reports of floating lights, five-foot-tall owls with human teeth, and static-filled radio interference.

Using Python and /platforms/claude, we will construct a generative engine that doesn't just spit out random spooky stories, but builds an interconnected, chronologically consistent database of local panic. You will be able to query the archives, generate new reports that naturally link to existing town lore, and figure out what makes these local legends tick.

The Architecture of a Local Conspiracy

To make this feel like a living, breathing archive rather than a collection of disjointed horror stories, we need structure. Randomness is the enemy of world-building. If witness A reports a "metallic hum" near the old copper mine on a Tuesday, we want witness B's report on Thursday to mention their cattle behaving strangely three miles downwind.

Our system relies on three core components: 1. The Lore Ledger (JSON): A persistent state file tracking established facts (e.g., key NPCs, landmarks, the suspected cryptid's evolving physical traits, and unresolved mystery threads). 2. The Generation Engine (Python): Routs requests to Claude, injecting the current Lore Ledger to ensure new sightings reference previous events. 3. The Municipal Interface (CLI): A retro-themed command-line terminal to browse files, search by witness name or location, and trigger new nights of investigative logging.

Setting Up the State

First, let's define the baseline of our town. We need a local schema to keep our LLM grounded. Create a town_state.json file to act as our local database:

`json { "town_name": "Blackwood Pines", "year": 1974, "locations": [ "Oakhaven Timber Mill", "Route 9 Cutter's Pass", "Whispering Creek Campground", "The Copperhead Ridge Fire Tower" ], "active_phenomena": [ "The Copperhead hum (a low-frequency vibration causing nosebleeds)", "The Tall Man of the Pines (witnesses report an unusually thin figure wearing a yellow raincoat)" ], "logged_sightings": [] } `

Writing the Python Generator

We will write a Python script that reads this JSON, prompts Claude to generate a highly detailed, historically grounded incident report, and then updates the ledger with any new details introduced by the model.

If you need help setting up your API environment, consult the Claude Support documentation for authentication and rate limit details.

`python import json import os from anthropic import Anthropic

client = Anthropic(api_key=os.environ.get("ANTHROPIC_API_KEY"))

def load_state(): with open("town_state.json", "r") as f: return json.load(f)

def save_state(state): with open("town_state.json", "w") as f: json.dump(state, f, indent=2)

def generate_sighting(state): # We construct a system prompt that forces Claude to behave like a bored # 1970s sheriff's dispatcher typing on an IBM Selectric. system_prompt = """ You are the dispatch officer for the Blackwood Pines Sheriff's Department in 1974. Your job is to transcribe incoming phone calls and walk-in statements into formal incident reports. The tone must be dry, slightly bureaucratic, but highly detailed. Use spelling and phrasing appropriate for 1970s small-town America. Avoid modern jargon. No mentions of 'UFOs' or 'cryptids' unless specifically prompted—stick to what the witness actually describes. """ user_prompt = f""" Generate a new incident report based on the current town history. Current Town Lore Ledger: {json.dumps(state, indent=2)} Guidelines for this entry: 1. Pick one existing location and at least one active phenomenon to reference. 2. Introduce a new witness (give them a realistic local job: lumberjack, diner waitress, high school principal). 3. Add one minor, creepy detail that doesn't fully make sense yet (e.g., clock hands spinning backward, the smell of burnt hair). 4. Output your response strictly in the following JSON format: {{ "incident_id": "BP-1974-XXXX", "date": "October X, 1974", "time": "HH:MM", "location": "Selected Location", "witness_name": "Witness Name", "witness_occupation": "Occupation", "narrative": "The full transcript of the event...", "new_clues": ["clue 1", "clue 2"] }} """

response = client.messages.create( model="claude-3-5-sonnet-20241022", max_tokens=1000, system=system_prompt, messages=[{"role": "user", "content": user_prompt}], temperature=0.82 ) # Parse the structured response report_data = json.loads(response.content[0].text) return report_data `

Grounding the Prompts

To make this system work beautifully, you should master the art of structured system instructions. Our custom prompt forces the model to ignore typical Hollywood tropes. Instead of producing generic werewolf stories, it leans into the eerie, mundane details of regional folklore.

You can experiment with different atmospheric modifiers using our /prompts generator to create unique structural templates for your LLMs. In this case, we rely heavily on the "bureaucratic veneer" to contrast with the impossible events being reported.

Running Your Creepy Local Terminal

When you run the script, it should append the newly generated incident reports back into your local town_state.json ledger. Over several runs, the list of active phenomena will expand. Claude will look at previous reports in the JSON log and begin to draw connections:

  • Run 1: A truck driver reports his headlights failing near Cutter's Pass while observing a tall figure in a yellow raincoat standing in the middle of the road.
  • Run 2: A local park ranger finds a discarded, torn yellow raincoat near the timber mill, smelling of sulfur and ozone.
  • Run 3: A high schooler reports that her father's yellow raincoat has gone missing from their porch, and their family dog refuses to go near the woods.

This creates an incredibly satisfying, emergent narrative loop. If you want to dive deeper into the technical mechanics of structured outputs and managing world state with LLMs, check out our comprehensive /glossary to learn more about state management in generative applications.

pythonclaudeproceduralgame-devcreative

Keep going

Build something with the prompt generator, decode the jargon in the glossary, or compare the tools on our platform deep-dives.