Getting two players climbing the same substructure in White Knuckle simultaneously is — to put it gently — not something Dark Machine designed the game to support. The game was built around one set of hands, one set of inputs, one simulation. We're dragging co-op into SUB-STRUCTURE 17 whether the codebase likes it or not.

The Core Problem

White Knuckle's physics are tight. Your grip, your momentum, the ledges you grab, the items — it's all deeply local. There's no built-in concept of "another player exists." So step one of WKMultiplayer was figuring out what we even needed to sync.

The answer: position, grip state, held objects, items and velocity. Everything else — animations, particle effects, sounds — can be derived or run locally. We're not trying to sync the entire simulation, just the parts that matter for shared gameplay.

Why Steam P2P?

We're using Steam's P2P networking layer, specifically SteamNetworkingMessages. No dedicated server, no port forwarding, no headache. The host runs the authoritative simulation; the peer does client prediction and gets corrected on tick.

The host is always right. The peer is usually right. When they disagree, we yell at the peer until it agrees.

In practice this means the host's world state is the source of truth. Every N milliseconds (currently 50ms, so 20 ticks/sec), the host serializes the relevant state, sends a delta to the peer, and the peer reconciles. If the peer predicted wrong, it snaps to the corrected state. There's a tiny rubber-banding effect on bad connections that we're working on smoothing out.

What's Actually Working

As of now:

  • Two players can load into the same run
  • Position sync is live — you can see each other move
  • Grip state syncs (you can see each other grab ledges)
  • Basic collision awareness (you can't clip through each other... most of the time)

What's not working yet: object interaction sync, death/respawn coordination, and there's a bug where if you grab the peer the game just gives up and goes home. We're aware.

What's Next

Before we ship on Thunderstore we need: stable object sync, working room generation sync, proper disconnect handling, and at least one full run from bottom to top without a crash. All of this is taking a while. collin is providing emotional support. Cass is doing their uni thesis. We're getting there.

More updates coming. Until then — keep climbing.