⚠ HexCrawl is currently in Pre-Alpha. Expect rough edges and frequent changes. Follow the Dev Blog for updates.

The Most Important Claude Prompt

The single most important thing I’ve learned to include strategically in my prompts to Claude Code is:

Don’t write any code.

OK, sorry for the click-bait. But here’s the thought behind that - Claude is good at more than just writing code. Claude can also act as a research partner and a rubber duck. But for Claude to do that, it must be asked.

Claude is the Proverbial Man With a Hammer

“To the man with a hammer every problem is a nail.” Or as my director told me back in my intern days: “If I give a problem to an engineer, they’ll write some code; if I give a problem to an artist, they’ll draw a picture.”

Claude really wants to write code, and Claude also really likes to repeat patterns. If Claude wrote code in response to your last three prompts, you can bet that it’s going to do so again after the next prompt unless you explicitly tell it not to.

But why wouldn’t you want Claude to write code? The answer is because you don’t know what code you want to write yet. When you find yourself in that situation where it’s no longer simple execution and you need to explore ideas and really think about a problem, try posing the problem to Claude with the specific instruction to not write code. It’s surprising how much this can help.

Story Time

OK, here’s a practical example. I was writing some code around the effect system. The effect system is a way to run game logic at specific nodes within an encounter tree. It usually appears in data as a simple command and some key-value pair arguments. IE:

"effects": [
  { 
    "type": "modify_gold", 
    "params": { "amount": "5" } 
  }
]

Effects when run load a script based on their type (in this case effects/modify_gold.ts) which is given the params dictionary and few top level objects. Effects can do things like modify resources (gold, food, health, mana), grant loot, and now mark a legendary item as discovered (more on legendary items in a future post).

I had a solid feature plan and was executing phase three when in the review step I discovered a bad code smell was forming in the code Claude had written. Uh-oh.

What’s That Smell?

The impact of each effect on the game state needs to be communicated back to the client eventually, and I found in each case the code was doing something different and bespoke. Resource changes were detected by snapshotting at the start and then examining deltas. The top level runEffects call was checking to see if any loot got created and returning it to the caller. And now the worst case – the encounter system after calling runEffects was looping through all the effects to search for any of type discover_legendary to create a list of new discoveries to send down. Ick.

The more I dove into the code the worse it got. It turns out encounter nodes that started combat did that in yet another way. Man, we really needed some top level thing to accumulate all the changes that navigating an encounter tree create to reflect back to the client. I didn’t quite know what I wanted, but I knew I needed something.

Claude as a Researcher

Claude is actually pretty good at providing options when you have vague ideas of what you want and aren’t really ready to start cutting code yet. But you have to tell it that’s what’s going on. It also helps you get your own head into the right space - because now Claude is going to start suggesting some good things and some terrible things. You need to be ready to hold its feet to the fire and interrogate it over what it presents.

Here’s what I prompted it with in this case:

Do not write any code yet, but propose a method by which we might refactor the code to allow encounter node progression to create game state change (granting loot, starting a combat, marking legendaries as discovered, and potential future expansion) that is accumulated while effects are processing and correctly packaged up and returned to the client.

Claude came back with the most obvious answer: create a context object and pass it into the encounters to accumulate data. Claude is obviously more wordy than this, but here’s the gist of its answer:

Proposed approach: EncounterNodeContext
Introduce a mutable context object — created once per node resolution, passed through every layer of effect processing — that effects write into directly. The caller creates it, threads it down, reads from it at the end. No scraping.

OK, but I knew combat was going to be stickier. I needed more conversation with Claude, and here’s the good news - once Claude is in a pattern, it wants to repeat that pattern. At this point you can just talk to Claude and it will continue not writing code until you tell it to do so again. It may ask you if you want to write code, but once warned against it Claude generally sticks to that instruction until told otherwise.

Continuing the Conversation

I followed up with:

Give me more details on how we'd roll combat starting into this. Would the static data actually include a "start_combat" effect, or would that be programmatically inserted when the node type is combat?

And Claude correctly identified that this was a terrible idea:

The short answer: neither option is fully clean, and the right call depends on where you draw the boundary between "what the effect system is for" and "what the encounter service is for."

It then gave me a ton of ideas. Some of them were great. Others were terrible. But the good news is, it was now pitching ideas, acting as a researcher, and producing no code. Eventually when we hit on a solution I was able to tell it what I did and did not like, and I did so by simply referencing what was already in context from our prior discussion:

OK, let's go ahead and implement this. Do not include the optional further step of applyNodeEffects.

Final Thoughts

If you’re really out there in ideation mode, instead of just telling it “implement x but not y” you might want to ask it to write a full planning doc. Because of course all this context isn’t free - you’re really chewing up context talking back and forth with Claude. So if you go out into space and come back again, it may be good to restart with a fresh context.

If a full planning doc is overkill, you can also ask Claude to do the work for you:

Please emit a concise prompt I can give to a fresh context to implement x and y but not z.

Then just copy/paste that sucker into your new context.

Thanks

A quick shout-out to Christian Boos, who wrote this lovely tool claude-code-log that helps you dig up and review past Claude sessions. Super helpful in writing this post, and I’m sure will be a very helpful tool in future as well. Thanks Christian!