The Story of Gravity Golf: Orbital slingshot physics inside Reddit
๐ The Inspiration
The concept of Gravity Golf was born from a simple question: How can we turn Reddit's community-driven threads into interactive celestial playgrounds?
We wanted to capture the magic of retro gravitational slingshot games (like Kerbal Space Program trajectory planning and classic Gravitar) and merge it directly into the Reddit feed. The core vision was a premium, visually striking space console that felt like an operating cockpit terminal. It needed to be highly addictive, procedurally rich, and entirely type-safe on top of Redditโs new Devvit Web environment.
๐ How We Built the Physics Engine & Mechanics
We bypassed high-overhead physics frameworks and built a custom Euler integration orbital solver inside Phaser 4 to achieve accurate Keplerian gravity dynamics.
1. Planetary Gravity Fields
The spacecraft's motion is governed by Newton's law of universal gravitation. In each frame step, the gravitational pull from all celestial bodies is accumulated:
$$\vec{F}g = \sum{i=1}^{N} -G \frac{m_{ship} m_i}{|\vec{r}_i|^3} \vec{r}_i$$
Where:
- $G = 0.15$ is the scale-adjusted gravitational constant.
- $m_i$ is the mass of the $i$-th planet.
- $\vec{r}_i$ is the vector pointing from the ship to the center of the planet.
Applying the force accumulation, the acceleration and velocity of the spacecraft are computed iteratively:
$$\vec{v}{t+1} = \vec{v}_t + \frac{\vec{F}_g}{m{ship}} \Delta t$$ $$\vec{x}{t+1} = \vec{x}_t + \vec{v}{t+1} \Delta t$$
We implement this simulation forward in time up to 250 steps to draw the tactical trajectory prediction dots, letting users preview complex orbital paths and gravity-assists before launching.
๐๏ธ Procedural Sound Synthesis (Web Audio API)
One of the largest architectural challenges was that Devvit packages static asset bundles within an isolated iframe, which regularly caused Phaser asset preloader network blocks or caching failures for .mp3/.wav audios.
To guarantee zero-crash, latency-free audio, we built a custom procedural synthesizer using the browser's native Web Audio API:
- Engine Launch: An oscillator sweep starting at $150\text{ Hz}$ and linearly rising to $800\text{ Hz}$ over $0.25\text{ seconds}$ using an exponential gain envelope.
- Explosions: A synthesized pink noise node passed through a low-pass filter with rapid sweep decay from $1000\text{ Hz}$ to $50\text{ Hz}$.
- Star Collect: A high-frequency dual-oscillator chime ($880\text{ Hz} \rightarrow 1320\text{ Hz}$) forming a retro 8-bit major arpeggio.
- Shield Deflection: A rapid frequency modulation pop using a triangle oscillator sweep.
๐ Challenges Faced & Solutions
1. Screen Scaling and Out-of-Bounds Glitch
- The Problem: On mobile screens (where physical viewports shrink), the ball would immediately reset on launch. This was because the out-of-bounds boundary check evaluated against physical pixel dimensions, causing start positions on larger maps to be instantly flagged as "off-screen."
- The Solution: We switched the Phaser scaling system from
RESIZEtoFITand locked the camera logical resolution internally to $1024 \times 768$. Phaser automatically maps this logical matrix to any display device while preserving coordinate checks.
2. Vite & Phaser Bundling Isolation
- The Problem: The console threw
Uncaught ReferenceError: Phaser is not definedinsideGame.tsduring runtime physics loops. Vite's treeshaking separated Phaser modules, leaving the global namespace unpopulated. - The Solution: We eliminated all global runtime references to the
Phaserpackage, replacing Phaser's native vector distance functions with an inline Euclidean distance helper: $$d = \sqrt{(x_2 - x_1)^2 + (y_2 - y_1)^2}$$ This resulted in a bundle that compiles in under $1\text{ second}$ with zero external dependencies.
๐ What We Learned
- Procedural Synthesis is King: Bypassing traditional media assets in serverless, iframe-framed environments like Devvit eliminates asset-loading lag and asset-blocking issues.
- Locked Logical Viewports: Designing layouts around a locked $4:3$ virtual aspect ratio scaled by the engine is significantly more robust than computing screen dimensions on the fly for physics slingshots.
- Community-Driven UGC is Powerful: Building the Level Blueprint Editor empowers players to create and share their own maps, changing the game from a single-player trial to a community universe.
Built With
- css3
- devvit
- html5
- phaser4
- redis
- typescript
Log in or sign up for Devpost to join the conversation.