Max Payne, but in Rottweil
The premise came out of an interview I did with myself, in a tool that only asks questions and never answers. It went like this:
— What specific elements of Rottweil would best capture that dark, cinematic
atmosphere?
— haha nothing
— Are you having trouble finding a connection between the city and the game?
— yes which makes it all the more original
Which turned out to be the actual design brief. Rottweil is not a noir town and must not be made into one. It is bureaucratic, sleepy, tidy and well lit: municipal offices, a Sparkasse, a Vereinsheim, a parking garage, a garden-show construction site. The violence is an intrusion into that, never an expression of it. The moment the town itself goes sinister, the joke dies and it becomes a generic crime game.
An earlier version got this exactly backwards — carnival masks as gang uniforms, a Fasnet-mask smuggling ring, a fool-guild cartel. That is the town supplying the darkness, which is the wrong direction. Local colour is texture on the edges, never the source of the threat.
The plot, such as it is: a Landesgartenschau — a state garden show, the most harmless civic project imaginable — with a budget in the tens of millions, and a protagonist who notices that part of it goes somewhere it should not. Why does the violence find him? "he's asking too many questions."
Pass one is one room
Before any of that gets built, there is a contract, and the contract has one sentence in it that everything else is measured against:
The player dives sideways in slow motion, firing at three men as they fly past, lands hard, rolls up, and wants to do it again immediately.
If a feature does not serve that sentence, it does not go in. So pass one is one room, one gun, three to five enemies, and nothing else: no story, no menus, no audio, no comic panels, no German flavour at all.
The technical rules are just as narrow, and they are the reason it runs by
double-clicking a file: plain <script> tags and no build step, one
global per module, core three.js only — no loaders, no textures, no external assets,
no custom shaders — and nothing may fetch. The per-frame loops allocate
nothing at all: no new, no object literals, no closures inside
update. Scratch objects are allocated once at init and reused forever.
It is a prototype and it looks like one. But the dive works, and after the dive you want to do it again, which was the whole test.