Inspiration

Stock markets and solar systems kept appearing in the same sentence whenever we talked about dominant companies, Apple pulls suppliers into its orbit, Tesla's volatility creates ripples, Berkshire moves slowly like a gas giant. We realised the metaphor wasn't just poetic, it was mathematical. The same gravitational equations that describe planetary motion describe how capital flows between companies. That was the moment we decided to stop describing it and start building it.

What it does

Market Gravity is a real-time financial simulation where every company is a planet. Planet size maps to market capitalisation, orbital speed maps to daily volatility, and direction maps to gain or loss, counter-clockwise for gaining, clockwise for losing. The S&P 500 sits at the gravitational centre as the sun, with a pulse ring that beats faster as more stocks crash simultaneously. A Kotlin companion app called Mission Control fetches live data from Yahoo Finance, calls Google Gemini for a one-sentence AI analysis of each stock's movement, and transmits everything to the C++ simulation over a TCP socket in real time. Type any ticker, hit transmit, and a new planet grows into orbit with real price data and an AI insight attached. Features include bubble mode, which inflates gaining planets and shrinks losing ones to make capital flow visible, sector isolation to focus on one industry at a time, focus mode to spotlight a selected planet, and an eject animation that fires particle explosions when a stock is removed from orbit.

How we built it

The simulation is written in C++ using OpenGL 3.3 Core Profile, running at 60fps on Mac M1. Every visual element goes through a custom GPU pipeline, planets are rendered as sphere-shaded circles using Blinn-Phong lighting in the fragment shader, trails use a ring buffer with zero per-frame heap allocation and glBufferSubData to avoid GPU memory reallocation, and orbit rings use a custom shader that brightens in the arc just behind each planet. N-body gravitational forces run between every planet every three frames, decomposed into tangential and radial components so orbits wobble realistically without becoming chaotic. The Kotlin companion app uses Java's HTTP client to hit Yahoo Finance's public API and the Gemini 2.0 Flash API, then transmits JSON payloads over a local TCP socket. The C++ side listens in a background thread, parses updates under a mutex lock, and applies them in the next render frame. Uniform locations are cached at startup, MSAA is enabled at the framebuffer level, and the font is baked into a 1024×1024 atlas using stb_truetype.

Challenges we ran into

Getting the N-body physics to feel real without becoming chaotic took significant tuning. Too strong a gravitational constant and orbits destabilise within seconds. Too weak and the effect is invisible. We decomposed forces into tangential and radial components and added per-frame damping to keep the system stable. The networking was another challenge, synchronising two separate processes without dropping frames required careful mutex design so the render thread never blocks waiting for socket data. The Retina display on M1 doubled our framebuffer dimensions without doubling the window size, which broke all coordinate calculations until we correctly tracked the pixel ratio. We also had to handle Yahoo Finance's rate limiting gracefully, the fallback data system ensures the demo never fails visibly even if the API is unavailable.

Accomplishments that we're proud of

We built a complete GPU rendering pipeline from scratch in under 24 hours, custom shaders, ring buffer trails, cached uniforms, sphere shading, and MSAA, without any rendering framework. The live data pipeline works end to end: real Yahoo Finance prices, real Gemini AI analysis, real-time planet updates with animated transitions. The gravitational metaphor actually holds up scientifically, Apple's market cap in our simulation exerts measurable gravitational force on Visa's orbit, which is a physically accurate reflection of how dominant companies distort the economic environment around them. We are proud that it genuinely reads as useful rather than just decorative.

What we learned

We learned that the hardest part of a physics simulation is not the physics, it is the stability. Small numerical errors compound over thousands of frames and destroy the visual. We learned that GPU pipelines reward planning: every decision about VAO layout, shader uniforms, and buffer strategy has a measurable performance consequence. On the product side, we learned that mapping abstract data to physical properties is a gen

Built With

Share this project:

Updates