Canonical benchmark brief

11. Stormwind Trebuchet Simulator

Back to all prompts
# 11. Stormwind Trebuchet Simulator

Build a full-screen 3D counterweight trebuchet simulator with real, inspectable physics. The player operates a siege engine from a field outside Stormwind, tunes its mechanical setup, fires a stone at the city fortifications, and automatically follows the projectile all the way to impact.

The point is not just spectacle. The trebuchet must behave like a coupled mechanical system: the counterweight falls, the throwing arm rotates around its axle, the sling trails and whips forward, the release pin lets one sling end go, and the projectile continues under gravity, aerodynamic drag, and wind. A first-time viewer should understand why a shot flew long, fell short, or struck the wall.

The page opens directly into the live siege scene. No landing page, title card, or setup wizard.

## Scene and Objective

Place one large, mechanically credible counterweight trebuchet on a muddy siege field outside Stormwind. The city must be clearly readable in the distance through its white-stone walls, blue-and-gold roofs, gatehouse, towers, banners, and layered fantasy skyline.

The player attacks fortifications only. Do not show civilians, gore, or harm to people. Valid targets are:

- The main gate
- A wall section
- A defensive tower
- A line of empty practice shields or siege targets outside the wall

The initial camera begins in a slow three-quarter orbit around the trebuchet, with Stormwind framed beyond it. The engine is already loaded and ready to tune.

## Trebuchet Geometry

Model the engine as working geometry, not as a decorative prop:

- Heavy timber frame with visible cross-bracing
- Rigid axle and rotating throwing arm
- Short counterweight arm and long throwing arm with a visibly unequal pivot ratio
- Hinged counterweight box that hangs vertically as the arm rotates
- Rope sling with two visible segments, a projectile pouch, and a release ring/pin
- Winch, winding rope, trigger, and loading trough
- Wheels, pegs, iron straps, and joint hardware that help communicate scale
- A stone projectile that visibly sits in the sling before firing

Do not substitute a torsion catapult, ballista, cannon, or simple rotating stick. It must read and operate as a counterweight trebuchet.

## Real Physics Requirements

Use a deterministic fixed-step simulation at 1/120 second or smaller. Rendering may interpolate between physics steps.

Before release, simulate the coupled system:

1. **Counterweight** — gravity acts on a hinged or vertically hanging counterweight mass.
2. **Throwing arm** — rotates around the axle with configurable arm lengths, mass, and moment of inertia.
3. **Sling** — behaves as a pendulum attached to the long arm tip. Its pouch position and velocity must come from the arm and sling state, not from a separate canned animation.
4. **Energy losses** — include modest axle friction, sling damping, and aerodynamic loss. Total mechanical energy should broadly reconcile rather than increase from nowhere.
5. **Release** — one sling end releases because its ring passes the configured release-pin angle. Do not trigger release at a hard-coded elapsed time.

After release, transition continuously into projectile flight:

- Preserve the pouch's world-space position and velocity at the release instant. No teleport or velocity jump.
- Apply gravity at 9.81 m/s².
- Apply quadratic aerodynamic drag using air density, projectile frontal area, and drag coefficient.
- Apply a configurable horizontal wind vector through relative air velocity.
- Use continuous or swept collision checks so fast projectiles cannot tunnel through a wall.

The same configuration and random seed must produce the same trajectory and impact.

## Player Tuning

Provide a compact engineering panel that updates the predicted shot before firing. Every control must materially affect the simulated mechanism:

- Counterweight mass: 1,000–12,000 kg
- Projectile mass: 20–250 kg
- Long-arm length: 6–15 m
- Short-arm length or pivot ratio
- Sling length: 4–14 m
- Release-pin angle: adjustable in degrees
- Axle height
- Wind speed and direction
- Aim direction / traverse
- Optional axle friction or sling damping under an Advanced section

Show sensible starting values that can hit near Stormwind's outer wall. Sliders must include their current numeric values and units.

Changing a setting must immediately update:

- Estimated range
- Estimated apex
- Estimated flight time
- Release speed
- Predicted impact point
- A visible trajectory arc or landing marker

The prediction must be generated from the same physics model used by the live shot. Do not use a separate hand-authored curve.

## Firing Sequence

The primary action should be obvious and satisfying:

1. **Wind / Reset** — returns the arm, counterweight, sling, and projectile to the loaded state.
2. **Fire** — releases the trigger and runs the full physical simulation.
3. The arm accelerates, the sling whips around, and the projectile releases naturally.
4. At release, the camera automatically cuts into projectile chase mode.
5. The camera follows slightly behind and above the stone while keeping Stormwind and the trajectory readable.
6. Near impact, ease into a wider side angle so the player can see what was hit.
7. Hold briefly on the impact result, then offer **Replay** and **Reset**.

The player must be able to fire repeatedly with different configurations without reloading the page.

## Projectile Camera

The automatic projectile follow is a central requirement, not an optional flourish.

- Follow the actual simulated projectile transform.
- Use smooth spring-damped camera motion rather than snapping directly to the stone.
- Keep the horizon legible and avoid violent roll.
- Pull back as speed rises and tighten slightly near impact.
- Show a subtle speed line, wind streak, or ground shadow to communicate motion.
- Pressing **C** toggles between chase camera, wide ballistic view, and the trebuchet view.
- Pressing **T** toggles the trajectory line.
- Pressing **R** replays the most recent shot from the projectile camera without recalculating it.

Honor `prefers-reduced-motion`: disable camera shake, soften camera acceleration, default to the wide ballistic view, and keep all mechanics and controls functional.

## Stormwind Target and Impact

Stormwind should be a built 3D environment rather than a painted backdrop:

- Layered white-stone curtain walls with crenellations
- A main blue-roofed gatehouse
- Defensive towers and gold-trimmed banners
- Additional blue-and-gold roofs and tall fantasy spires behind the wall
- A road, siege trenches, scattered equipment, and terrain between the trebuchet and city

Impacts must correspond to the simulated collision point:

- Ground impacts create a dirt burst and crater decal or displaced patch.
- Wall, gate, and tower hits create localized dust, chips, and a small number of masonry fragments.
- Repeated hits may increase a visible damage score or crack state.
- Do not collapse the whole city from one ordinary shot.
- Misses continue until they hit terrain; do not delete the projectile at an arbitrary range.

## Engineering HUD

Use compact, high-contrast siege-engineering panels inspired by a field manual. Keep the center of the screen clear for the machine and flight.

Always visible:

### Top left — Shot setup

- Counterweight and projectile mass
- Arm ratio and sling length
- Release-pin angle
- Wind

### Top right — Predicted / actual result

- Target and distance
- Predicted range
- Actual range after impact
- Release speed
- Apex and flight time
- Impact speed and hit location

### Bottom left — Energy and mechanism

- Counterweight potential energy
- Arm rotational energy
- Projectile kinetic energy
- Current phase: loaded, falling, sling acceleration, released, flight, impact

### Bottom center — Primary controls

- Large **Fire** button
- **Wind / Reset**
- Camera and trajectory hints

Use a restrained palette: timber, iron, parchment, Stormwind blue and gold, with one warm trajectory/impact accent. Avoid huge translucent titles over the scene.

## Controls

- **Space**: fire when loaded; pause/resume while simulating
- **Enter**: wind/reset after a shot
- **C**: cycle camera mode
- **T**: toggle trajectory
- **R**: replay the last shot
- **A / D** or **Arrow Left / Arrow Right**: adjust traverse
- **Tab / Shift+Tab**: navigate every tuning control and button

Pointer controls:

- Drag empty space to orbit in trebuchet view
- Scroll or pinch to zoom
- Sliders and buttons must work with mouse, touch, and keyboard

## Visual Rules

- Full-screen 3D rendered into a `<canvas>`
- Immediate readable composition: trebuchet in the foreground, Stormwind as the distant objective
- Credible timber, rope, iron, stone, cloth, dust, and terrain materials
- Soft daylight or late-afternoon lighting with readable shadows
- No external textures fetched at runtime; use procedural or locally shipped assets
- Keep UI panels from overlapping each other or covering the trebuchet at 1280×800
- On screens below 760 px, collapse tuning controls into one accessible drawer while keeping Fire, camera mode, and shot result visible
- Do not fake depth with a flat background image of Stormwind

## Hard Requirements

- Single `index.html`
- No build step
- WebGL via Three.js, Babylon.js, regl, or raw WebGL2
- Any CDN libraries must be listed in `manifest.json.externalAssets`
- Smooth at 30 fps on a 2020 laptop at 1280×800
- Keyboard accessible
- `lang="en"` on `<html>`
- No network requests for runtime art, textures, models, audio, or data
- No pre-rendered projectile animation or hard-coded impact sequence

Expose a small automated verification hook:

```js
window.__trebuchet = {
  ready: true,
  getState(),        // phase, time, loaded/fired state, camera mode
  getConfig(),       // all current physical parameters with units
  setConfig(values), // update a bounded subset of parameters
  fire(),
  reset(),
  step(seconds),     // advance the deterministic fixed-step simulation
  getTelemetry(),    // release speed, range, apex, flight time, impact data, energy values
  getProjectile(),   // world position and velocity
  getTrajectory()    // sampled points from the current prediction or completed shot
};
```

The hook may call the same public functions used by the UI. It must not contain a second simplified physics implementation.

## Loop / Validation Rule

Do not stop until you have personally verified all of the following in a browser:

1. The page opens directly into a loaded trebuchet facing a clearly recognizable Stormwind fortification, with no console errors.
2. Pressing Fire visibly drops the counterweight, rotates the arm, swings the sling, releases the projectile from the pouch, and follows it to impact.
3. The projectile position and velocity remain continuous across release.
4. At zero wind, the predicted landing point and actual ground impact agree within 3% or 5 m, whichever is larger.
5. Doubling counterweight mass from the default increases release speed and range without changing any other control.
6. Changing sling length or release-pin angle visibly changes the release moment and trajectory.
7. A strong crosswind produces visible lateral drift in the predicted arc and actual shot.
8. A fast projectile cannot tunnel through the wall.
9. Ground, gate, wall, and tower impacts are reported at the correct collision point and produce localized effects.
10. Chase, wide, and trebuchet cameras all work during flight; Replay follows the stored shot without changing its path.
11. Pause/resume, reset, repeated firing, trajectory toggle, and keyboard navigation all work.
12. Reduced-motion mode removes shake and uses the wide ballistic camera while preserving the complete simulation.
13. `window.__trebuchet.step()` produces deterministic telemetry for the same configuration across two resets.
14. The simulation remains at or above 30 fps at 1280×800 during launch, chase, and impact.

If any check fails, fix the specific mechanism and run all fourteen checks again.