Berk Karataş

Junior software engineer · Ankara · 2026

Two games in progress: SHŪDEN and UPTAG.

I build games in my own time, end to end: design, code, art pipeline and testing. One is a slow, lamp-lit horror game for PC. The other is a fast arcade climber for phones. Every image on this page comes from these two projects.

SHŪDEN"the last train" · narrative horror · PC

1998, the small town of Nekomachi. You work the only ticket window of a station that closes in twelve nights. The living and the dead wait in the same queue. At 02:10 two trains arrive: Platform 1 takes the living home, Platform 2 takes the dead beyond. Some of the dead are wearing living faces. You have a lamp, a few questions, a logbook and the evening paper.

Three.js r186TypeScriptElectron · Steam firstBlender via Python~38k lines TS
IN-GAMEThe window, night 1, 23:10
IN-GAMEOpening, rain
IN-GAMELamp held, gas low
Look

Light costs gas

The lamp shows what a passenger really is, but it burns a 16-second gas budget. Below 30% the slips come back UNREADABLE and the booth goes dark.

Ask

Two questions

Cross-check answers against the newspaper and the logbook. A certain slip never lies. Disguises only blind you, so a fake always leaves at least two contradictions.

Stamp

Home or beyond

Stamp each passenger 帰 HOME or 往 BEYOND. Nobody runs away: they wait on their platform, and by 02:10 the platforms read like a ledger of your night.

From concept to the booth

It started as a cheerful station diorama.

The first concept was a cross-section model of a Japanese station, rendered in Blender from Python scripts. A grey-box prototype proved the management idea was not fun, so I kept the world and the wooden kokeshi passengers and rebuilt the game around one decision: who is alive.

The art moved with it: from glossy lacquer to worn wood, hard lamp light and sick green fluorescents. Heads are sculpted by script in Blender with a living and a dead variant; bodies are lathed in code.

CONCEPTLineup, Blender
CONCEPTStation diorama
PIPELINEHeads, living / dead
IN-GAMEEvening paper
IN-GAMELogbook
Build sheet境川線 · Nekomachi Stn.
Engine
Three.js r186, TypeScript and Vite; Electron for the Steam build. About 38,000 lines of game code.
Assets
A Blender pipeline written in Python (about 5,800 lines) that builds rooms and props, bakes the lighting and exports GLB.
Look
A PS1-style post-process: 540 lines of resolution, 15-bit colour and Bayer dithering, with no vertex wobble. Diegetic UI: a wall clock, a glass gas gauge and stamped evidence slips.
Scope
Day 0 plus 12 nights, about 2.5 to 3 hours for a first playthrough. English in-game text; Japanese signage checked for accuracy.
Status
The first nights are playable. The central mystery is still being written.

UPTAG

RUN. JUMP. TAG THE BLOCK.

A vertical arcade climber made for one thumb. You run along the floors of a city block, turn speed into height, bounce off walls into combos and keep ahead of a camera that never stops rising. Each city has its own look, music and platform types, and every run can be replayed frame for frame.

PixiJS v8TypeScriptCapacitor 8 · Android / iOS~30k lines TS
IN-GAMETitle
IN-GAMECreator
IN-GAMEBrickside
IN-GAMERain Market
IN-GAMESalt Steps
IN-GAMEChiptown
SPEED

Momentum jumps

The faster you run, the higher you go. A long run-up can clear several floors at once.

CHAIN

Wall-bounce combos

Chain multi-floor jumps and wall bounces to build a combo multiplier and climb faster.

PRESSURE

The rising camera

From the 10th floor the camera climbs on its own and speeds up. Fall below it and the run is over.

THUMB

Hold to jump big

Hold for higher, bigger jumps and slide sideways to steer. The scheme came from watching how people actually held the phone.

The engine under it

Same inputs, same run. Every time.

The game logic runs in its own simulation: a fixed 50 Hz step, fixed-point maths and a seeded random generator. Rendering only reads from it. Because the simulation is deterministic, a run is just its inputs, which gives you exact replays and ghost races for free, and is the base for live 1v1 racing with rollback.

Automated tests replay recorded runs and check that the result never changes, and they check that old save files still load after every schema change.

// every 20 ms, independent of frame rate
tick(state, input)  // fixed-point, seeded RNG
  move(player, input)
  collide(player, platforms)
  combo.update()
  camera.rise(state.floor)
// render: interpolate between two ticks
draw(lerp(prev, cur, alpha))
// a run = seed + inputs → replay, ghost, 1v1

Cities in concept

5 cities are in the game with 26 platform types and Endless, Daily and Weekly modes. More were explored as concept frames before production.

CONCEPTTarget frame
CONCEPTBloom
CONCEPTClockwork
CONCEPTMoonside
CONCEPTSunken Fair
CONCEPTTwin Suns

How I build

AI-assisted, with a person making the calls.

I write and steer the code with Claude Code. For each game I set up a team of specialised AI agents, 15 for SHŪDEN and 17 for UPTAG, covering game design, art direction, UX, sound, performance and QA. They draft, review and argue. I decide what goes in, read the changes, and play every build myself on real devices.

What that looks like day to day

  • One written canon per game, so every agent and every change works from the same source.
  • Review rounds with a score threshold before art is accepted; a frame that misses it goes back.
  • Ideas get cut when play proves them wrong, like UPTAG's in-run card system, which broke the flow.
  • Type checks, builds and determinism tests run on every change.

Ready for Unity and C#

In my gamesIn Unity
Fixed 50 Hz simulation tickFixedUpdate
Platform and city definitions as dataScriptableObjects
Small objects composed of systemsComponents
Blender to GLB export pipelineAsset import
Java OOP from universityC# classes

Let's talk games.

I'm a 2025 graduate based in Ankara and open to relocation. Happy to walk through either game, live.