You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Refactor lobby_worker and configure auto-formatting
- Separate inline CSS and JS from lobby_worker/index.html
- Update build scripts to include separate asset files
- Configure Prettier and lint-staged for automated formatting
- Enable Rust auto-formatting via rustfmt
- Apply formatting to entire project
Copy file name to clipboardExpand all lines: ARTICLE.md
+10-9Lines changed: 10 additions & 9 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,18 +1,19 @@
1
1
# How I Built a Real-Time Multiplayer Game on the Edge with Rust and WebAssembly
2
2
3
-
> *Real-time multiplayer games are mostly about trade-offs: latency vs authority, simplicity vs correctness, and cost vs control. This article walks through an approach that worked well for me — using Rust compiled to WebAssembly to share deterministic game logic between the browser and Cloudflare’s edge.*
3
+
> _Real-time multiplayer games are mostly about trade-offs: latency vs authority, simplicity vs correctness, and cost vs control. This article walks through an approach that worked well for me — using Rust compiled to WebAssembly to share deterministic game logic between the browser and Cloudflare’s edge._
4
4
5
5
**[Play the live demo →](https://pongo.tre.systems/)** | **[View source on GitHub →](https://github.com/rgilks/pongo)**
6
6
7
7
---
8
8
9
9
## Why Pong?
10
10
11
-
In 1972, Atari released *Pong*, effectively kicking off the video game industry. More than fifty years later, it turns out to be a great test case for multiplayer networking.
11
+
In 1972, Atari released _Pong_, effectively kicking off the video game industry. More than fifty years later, it turns out to be a great test case for multiplayer networking.
12
12
13
13
In many modern games, latency can be masked with animation, camera tricks, or generous hitboxes. Pong gives you none of that. The physics are simple, the ball is fast, and if your paddle isn’t exactly where you expect it to be, you feel it immediately.
3.**State validation** — preventing the client and server from drifting apart.
@@ -29,7 +30,7 @@ When building **Pongo**, my goal wasn’t just to recreate a classic — it was
29
30
30
31
The solution I landed on was a kind of “universal app” architecture, built with **Rust**, **WebAssembly (WASM)**, and **Cloudflare Durable Objects**.
31
32
32
-
Most multiplayer games try to share logic between client and server, but language boundaries usually get in the way. By writing the core game logic in Rust, I can compile it to WebAssembly and run the *same code* in two very different environments:
33
+
Most multiplayer games try to share logic between client and server, but language boundaries usually get in the way. By writing the core game logic in Rust, I can compile it to WebAssembly and run the _same code_ in two very different environments:
33
34
34
35
1.**The Browser** — rendering at 120Hz+ with WebGPU.
35
36
2.**The Edge** — running inside a Cloudflare Durable Object at a fixed 60Hz.
@@ -51,7 +52,7 @@ graph TD
51
52
Input["Player Input"]
52
53
Predict["Client Predictor\n(Prediction)"]
53
54
Render["WebGPU Renderer"]
54
-
55
+
55
56
Input --> Predict
56
57
Predict -->|"Step (Frame Rate)"| Logic
57
58
Predict --> Render
@@ -108,7 +109,7 @@ Each match runs inside a **Cloudflare Durable Object**. A Durable Object is a si
108
109
This is the key difference from typical stateless serverless functions: a Durable Object can host a proper **game loop**.
0 commit comments