SurfCraft dev log

CS:S surf ramps and surf physics for Minecraft 26.3, built step by step. Updated 2026-10-02 12:37.

Picking the ramp angles from real surf maps
01 Picking the ramp angles from real surf maps2026-10-01 01:30

Every surf face in 41 local KSF maps: 51 degrees is by far the most common, so Surf Ramp uses a 5:4 slope (51.3 degrees); Steep Surf Ramp uses 2:1 (63.4 degrees). A 1x1 45-degree wedge would be walkable ground in Source, not a surf ramp.

How blocks join into one ramp
02 How blocks join into one ramp2026-10-01 01:30

Each ramp block stores its cut of a shared plane, so blocks placed next to each other continue the same slope at any size. The geometry (RampCell) is tested for exact plane continuity across neighbours.

First ramp textures
03 First ramp textures2026-10-01 01:31

The blocks agent drew two 16x16 textures in code (no fal key): cool teal for the 51-degree Surf Ramp, amber for the 63-degree Steep Surf Ramp, with a lit top/left edge to fit Minecraft's pixel style.

First in-game render
04 First in-game render2026-10-01 01:38

The client game test builds a showcase in a superflat world: a joined 51-degree Surf Ramp (teal) backed by a 63-degree Steep Surf Ramp (amber), plus single blocks of each in all four facings. Slopes render as exact geometry, not stair steps.

Smooth slope up close, items in the hotbar
05 Smooth slope up close, items in the hotbar2026-10-01 01:38

Up close, the blocks join into one continuous slope with the texture lined up across cells. The hotbar shows both ramp items as wedges.

Java physics vs the real CS:S server
06 Java physics vs the real CS:S server2026-10-01 01:56

The physics port replays a recording from a real Counter-Strike: Source server on surf_kitsune's ramp: same inputs, same ramp, worst difference 0.006 units over 100 ticks (tolerance 0.05). 17 recordings (18 replays) pass this way.

The 63-degree Steep Surf Ramp
07 The 63-degree Steep Surf Ramp2026-10-01 01:56

The 2:1 side of the showcase: eight blocks long and six tall, one smooth plane with a continuous grid.

One block of each type, in every facing
08 One block of each type, in every facing2026-10-01 01:56

Single ramp blocks facing north, east, south and west. Behind them, the cross-section of the joined showcase: a 51-degree side and a 63-degree side meeting at the ridge.

First surf in game
09 First surf in game2026-10-01 02:36

The CS:S movement core now drives the player in Minecraft: dropped onto a 51-degree ramp at 788 units/s while holding the strafe key into the slope, the player glides along it. The speedometer above the hotbar shows horizontal speed in units/s.

The Karambit
10 The Karambit2026-10-01 03:00

SurfCraft's surf-building tool: a 16x16 CS:GO-style karambit drawn in code, with a claw blade in a Fade finish (gold, purple, pink), a black grip and a finger ring. Zoomed, at 1x to 8x, and in hand next to the hotbar.

Getting the sprite to read as a karambit
11 Getting the sprite to read as a karambit2026-10-01 03:00

Before and after: the first tries drew a flat arc with a 1-pixel ring. The final sprite has a hooked claw blade with a dark outline (like vanilla swords) and a ring with a clear hole.

Copy a ramp chunk, extend it three times
12 Copy a ramp chunk, extend it three times2026-10-01 03:00

Sneak + right-click copies a hand-built 63-degree chunk (6x6x4, 96 blocks) onto the knife. Three right-clicks on the ramp put a copy after its end each time: 16 blocks long, every cell on the same slope plane.

The default module: a two-sided surf ramp
13 The default module: a two-sided surf ramp2026-10-01 03:00

A fresh knife places the classic two-sided 51-degree ramp in one click: Surf Ramp 5:4 on both sides of a ridge, 8 wide, 5 tall, 8 long (224 blocks), cut with the ramp plane formula.

Placement preview: green fits, red is blocked
14 Placement preview: green fits, red is blocked2026-10-01 03:00

Holding the knife outlines the box a click would fill, using the server's own placement code: green when it fits, red with the blocked cells outlined, and at a ramp's end the next extension.

All or nothing
15 All or nothing2026-10-01 03:00

Clicking where it doesn't fit places nothing: the action bar gives the reason and red dust marks the 44 cells in the way. In survival the knife also takes one item per block, or lists what's missing; sneak + right-click in the air undoes.

The knife remembers its module
16 The knife remembers its module2026-10-01 03:00

The copied module is stored on the item (palette plus run-length encoded blocks), so it survives restarts; the tooltip shows its size and the controls.

Surfing in third person
17 Surfing in third person2026-10-01 03:09

Third-person view of a survival surf run on the 51-degree ramp at 724 units/s. The legs stay still while sliding instead of running in place, the speedometer reads horizontal speed, and the server accepted every move without a single correction.

2200 units/s on a dedicated server
18 2200 units/s on a dedicated server2026-10-01 03:43

The same surf run against an in-process dedicated server over a real local connection, in survival, on the 63-degree ramp at 2200 units/s. 254 blocks along the ramp, plus four fast crossings over an apex: the server corrected nothing and logged no 'moved wrongly'.

Minecraft adds nothing to the physics
19 Minecraft adds nothing to the physics2026-10-01 03:43

Speed every tick of two in-game surf runs (blue) against an offline replay of the same keys and mouse through the physics core alone (orange, dashed). Positions agree exactly, bit for bit: the Minecraft pipeline changes nothing about the CS:S movement.

Bug fixed: sinking through a ramp
20 Bug fixed: sinking through a ramp2026-10-01 03:45

Found by the in-game test: a creative player flying into a slope could sink through it a hair per tick, because the exact collision stopped boxes a rounding tolerance inside. Now boxes stop where they touch: 3000 presses into the slope, zero penetration.

A real mod icon
21 A real mod icon2026-10-01 04:08

The Fabric placeholder icon is replaced with SurfCraft's own: a surf ramp in 3/4 view with the Karambit, drawn in code as 32x32 pixel art.

Fixed: the ground at a ramp's toe
22 Fixed: the ground at a ramp's toe2026-10-01 06:05

CS:S also probes each quarter of the player's box for floor; without it, a surfer at a ramp's foot stayed airborne and kept speed (2:1 toe: 1101 vs 463 u/s).

Fixed: bunny hopping dodged fall damage
23 Fixed: bunny hopping dodged fall damage2026-10-01 06:05

Auto hop landed and jumped within one tick 7 times in 10, so the server never saw the landing. Now that tick reports the touchdown: 221 of 221 drops hurt as without jump.

Speedometer off the action bar
24 Speedometer off the action bar2026-10-01 06:18

It was drawn on the action-bar line, garbling Karambit messages, and read 0 u/s at rest beside a ramp. Now it sits one line above and hides below 1 u/s.

Packet bursts no longer stop surfers
25 Packet bursts no longer stop surfers2026-10-01 06:18

A 300 ms stall or client hitch lands 6 move packets in one server tick; vanilla's check sent surfers above 1312 u/s back and stopped them dead. Surfers now get a 10-block budget per packet (server game test).

Other players see surfers glide
26 Other players see surfers glide2026-10-01 06:18

The server now tells each client who is surfing, so another player's legs settle on a ramp instead of running in mid-air.

Ramps built side by side keep their own plane
27 Ramps built side by side keep their own plane2026-10-01 06:46

D1: a second 5:4 ramp built by hand beside the first came out as a sawtooth; placement now continues the ramp you click, then the cell's own slice, then the lower plane.

Rain stops on ramps
28 Rain stops on ramps2026-10-01 06:46

D2: ramps now block motion like smooth stone, so rain, snow and lightning stop on them; it used to rain under a hollow ramp roof.

Ramps cast shadows
29 Ramps cast shadows2026-10-01 06:46

D5: occlusion shapes instead of noOcclusion: the hollow ramp (right) now shades the ground like the solid one, and hidden faces are culled.

Ramp fields render as fast as stone
30 Ramp fields render as fast as stone2026-10-01 06:47

D5: frame rate over six 16-tall A-frames as a share of the same field in stone: 81% before, 100% after (one dot per client run).

The selection outline is the real wedge
31 The selection outline is the real wedge2026-10-01 06:47

D9: the outline on a ramp traces the cell's exact edges instead of the 8-step staircase that collision uses.

A 208-block surf ramp from 25 Karambit clicks
32 A 208-block surf ramp from 25 Karambit clicks2026-10-01 06:47

D4: extend reads only the ramp's end slice, so a copied 16-tall 5:4 A-frame grows to 208 blocks through real clicks (it used to stop at 40).

Extend preview cost no longer grows with the ramp
33 Extend preview cost no longer grows with the ramp2026-10-01 06:47

D3: plan(), run every tick while the knife points at a ramp, went from 1.7-4.9 ms (refusing past 8,192 cells) to about 0.03 ms at any length.

34 Surfing the course end to end2026-10-01 08:09

Survival: Karambit crafted by hand, 96-block ramp from 12 clicks, ramp 2 free-placed; two keyboard-and-mouse runs, 10.6 s and 123 blocks each, top 680 u/s, full health, 0 server corrections

The start pad, built by hand
35 The start pad, built by hand2026-10-01 08:11

Survival, real clicks: ramp 1 hangs from a pillar the player jumped up, the Karambit placed it 4 up and extended it 11 times to 96 blocks; the pad clings to its north end.

End of ramp 1 at 609 u/s
36 End of ramp 1 at 609 u/s2026-10-01 08:11

First person, keyboard and mouse: 96 blocks of surfing took the run-up's 250 u/s to 609; ramp 2 and the gold-marked finish pad wait below the 5-block gap.

Third person on ramp 2 at 660 u/s
37 Third person on ramp 2 at 660 u/s2026-10-01 08:12

Run 2 after the gap's air strafe (A + mouse left, then D + mouse right): landed on the free-placed ramp 2 and gaining, full health, no server correction.

Published: free and open source
38 Published: free and open source2026-10-02 12:37

SurfCraft 0.1.0 is public at github.com/a-funk/SurfCraft under the MIT License (Valve's Source 1 SDK License acknowledged for the SDK-derived movement code), with the jar on the release page.