3D game with physics-based Racing Geometry

Visit
Client:
Martynas Juska
Industry:
Gaming
Framework:
React 3 Fiber
Style:
Rough Geometry

Project Overview

3D racing game built entirely in the browser where you navigate narrow corridor on the clock. The game features real-time physics and destructible obstacles that shatter on impact, showing how complex 3D physics can have it's own style when combines with simple geometry.

React Three Fiber 3D racing game with wooden corridor

Design & User Experience

Webflow is web development platform that combines a powerful visual design tool and a built-in Content Management System (CMS). It is known for appealing to designers and developers a like. Webflow is increasing in popularity especially for landing pages, marketing teams and start ups for a ease of use and easy content editting capabilities which doesn't require any technical knowledge.

Browser-based 3D game with physics-powered gameplay
Player sphere smashing through red cubes with Rapier.js physics
Icosahedron player jumping over spinning obstacle in 3D web game
Airborne player demonstrating jump physics in React 3D game

Tools & Tech

React & React Three Fiber Architecture

The game leverages React Three Fiber (R3F) as its core framework, providing a declarative React approach to Three.js development. This architecture enables component-based 3D scene construction with predictable state management and lifecycle hooks. The modular structure separates concerns into distinct components - like Player, Level, SmashableBox, and Experience - making the codebase maintainable and scalable. Each obstacle type (BlockSpinner, BlockLimbo, BlockAxe) extends from reusable base components, demonstrating clean inheritance patterns and DRY principles.

Three.js Rendering Pipeline

Custom Three.js geometries and materials optimize rendering performance across the game. The icosahedronGeometry creates the player's distinctive spherical form with minimal polygon count while maintaining visual appeal. Shared geometry instances for obstacles reduce memory overhead - all smashable boxes reference a single BoxGeometry instance rather than creating duplicates. The wooden corridor textures utilize optimized WebP format with proper texture mapping including diffuse, normal, roughness, and ambient occlusion maps. Texture configuration includes proper color space management (sRGB for color maps, Linear for data maps) and repeat wrapping for seamless tiling.

Physics Engine with Rapier.js

Rapier.js powers the realistic physics simulation, chosen for its WebAssembly performance advantages over traditional JavaScript physics engines. The implementation features kinematic bodies for moving obstacles with precise trajectory control, dynamic rigid bodies for smashable boxes with custom mass and damping properties, and collision detection with ray casting for ground detection during jumps. Each smashable box maintains individual physics properties (restitution: 0.8, friction: 0.05) creating satisfying destruction effects. The physics world automatically sleeps inactive bodies after 2 seconds of stillness, significantly improving performance when dealing with hundreds of physics objects.

State Management with Zustand

Zustand with subscribeWithSelector middleware manages game logic efficiently, providing granular subscription to state changes without unnecessary re-renders. The game state tracks phase transitions (ready, playing, ended), timing for speed runs, and obstacle count configuration. The middleware pattern enables specific component subscriptions - the Player component only re-renders on phase changes, not on timer updates. Custom memory cleanup functions trigger garbage collection during phase transitions, preventing memory leaks during extended play sessions.

Performance Optimization Strategies

Multiple optimization layers ensure smooth 60fps gameplay even on mid-range devices. Object pooling shares geometry and material instances across all similar meshes, reducing GPU memory usage by approximately 70%. Conditional shadow casting only applies to active objects, with sleeping physics bodies disabling shadows to save rendering cycles. Memory management includes explicit disposal of textures and geometries when components unmount, with forced garbage collection hints during game restarts. The useFrame hook implements delta-time calculations for frame-independent movement, ensuring consistent gameplay across different refresh rates. Level-of-detail optimizations reduce complexity for distant objects, while frustum culling automatically handled by Three.js prevents rendering of off-screen elements.

Development Exploration

Projects built on my spare time. Experiments, recreations, and ideas to test.