Click or Bang: 3D Revolver Simulator

Inspiration

The inspiration for Click or Bang came from a fascination with the mechanical precision of firearms and the high-fidelity "inspection animations" found in AAA first-person shooters. We wanted to capture the visceral, tactile satisfaction of a Colt Python .357—the heavy click of the cylinder, the snap of the crane, and the violent kick of the recoil—but we wanted to bring this experience entirely to the web browser.

We were also driven by a technical challenge: Can we build a photorealistic 3D prop without loading a single external 3D model file? We wanted to prove that React and Three.js are powerful enough to procedurally generate complex industrial designs on the fly.

What it does

Click or Bang is a fully interactive, photorealistic 3D simulation of a .357 Magnum revolver.

  • Physics-Based Recoil: It doesn't just play an animation; it simulates mass and spring tension to calculate the "kick" and muzzle climb in real-time.
  • Manual Operation: Users can open the cylinder, spin the chamber, and perform a full reload.
  • Russian Roulette Mode: A dedicated feature allowing users to load a single round into a random chamber, spin the cylinder, and test their luck.
  • Visual Fidelity: Features dynamic lighting, metallic PBR (Physically Based Rendering) textures, muzzle flashes, and smoke particles.

How we built it

The project is built using React 19, Three.js, and React Three Fiber (R3F).

  • Procedural Modeling: This is the project's technical highlight. We did not import .obj or .glb files. Every component—the barrel, the hammer, the grip, and even the individual bullets—is constructed programmatically using geometric primitives (Cylinders, Boxes, Tori) composed together in React components.
  • State Management: We used React state to track the revolver's logic (which chamber has a bullet, the rotation angle, the hammer state).
  • Animation Loop: We utilized the useFrame hook to interpolate physics calculations and handle particle effects at 60 FPS, ensuring the recoil feels smooth and responsive.

Challenges we ran into

  1. Geometric Composition: Creating organic shapes, like the curved revolver grip, using only basic geometric primitives was a significant puzzle. We had to layer multiple shapes and use RoundedBox geometries to approximate the machined steel look.
  2. The "React vs. Loop" Conflict: React is declarative (state changes), while 3D animation is imperative (frame loops). Synchronizing the React state (e.g., "Bullet fired") with the imperative visual effects (Recoil kick + Flash + Smoke) required careful management of refs and memory to prevent frame drops.
  3. Lighting & Materials: Getting the "Gunmetal" and "Chrome" materials to look realistic required fine-tuning roughness and metalness values and finding the perfect HDRI environment map for reflections.

Accomplishments that we're proud of

  • Zero Assets: The entire application is incredibly lightweight because there are no heavy 3D model assets to download. It runs instantly.
  • The "Feel": We are proud of the recoil physics. The gun feels heavy and powerful, not like a weightless toy.
  • The Russian Roulette Mechanic: The logic for randomizing the bullet position and tracking the rotation step to determine if the gun goes "Click" or "Bang" works seamlessly.

What we learned

  • Advanced Three.js: We deepened our understanding of scene graphs, vector math, and material properties.
  • Procedural Generation: We learned how to break down complex real-world objects into simple geometric components.
  • Physics in UI: We learned how to implement simple spring-damper physics systems within a web frontend to create natural motion.

What's next for Click or Bang

  • Audio Engineering: Adding high-quality, spatial audio for the mechanical clicks, cylinder spins, and gunshots.
  • Mobile Gyroscope: Implementing support for mobile devices so users can aim the gun by physically moving their phone.
  • ** disassembly Mode:** An educational mode that explodes the view of the gun to teach users about the internal firing mechanism and safety mechanisms.

Built With

Share this project:

Updates