Siege Tower
A wheeled wooden siege tower, 4.4 m square at the base and 3 to 5 storeys (about 10 to 16 m) tall, clad in wet hides, planks or iron plates on the front and sides with an open back full of ladders. Six solid wheels roll with distance (spin rigs, tick + loop); the assault ramp at the top is hinged at its foot (rotate rig on x: 0 drawn up, 90 lowered toward +Z onto a wall).
- Size
- 5.6 × 15.4 × 5.0 m
- Triangles
- 2,324
- Kit
- Castle
Tune it
4 knobs: Storeys, Cladding, Wood, Banner.
Specs
- Size
- 5.6 × 15.4 × 5.0 m width × height × depth
- Triangles
- 2,324 of 6,000
- Draw calls
- 1 one vertex-colour material
- Loop clip
- 4.084 m of travel per cycle
- Moving parts
- 7 wheel_0 · spin, wheel_1 · spin, wheel_2 · spin, wheel_3 · spin, wheel_4 · spin, wheel_5 · spin, ramp · rotate
- Knobs
- 4 3 presets
- Night lights
- 0 none
Passed the validator: real scale, rests on y = 0, front faces +Z, deterministic.
Use it
Code for the specimen as it is set up above; it follows your knobs.
import { createAsset } from 'https://gaitkit.com/cdn/siege-tower.mjs';
const siegeTower = createAsset();
scene.add(siegeTower); // rests on y = 0, front faces +Z
let dist = 0;
renderer.setAnimationLoop(() => {
dist += speed * clock.getDelta();
siegeTower.position.z = dist;
siegeTower.userData.tick(dist); // wheels roll exactly with the distance
renderer.render(scene, camera);
});import { useMemo, useRef } from 'react';
import { useFrame } from '@react-three/fiber';
import { createAsset } from 'https://gaitkit.com/cdn/siege-tower.mjs';
export function SiegeTower({ speed = 1 }) {
const model = useMemo(() => createAsset(), []);
const dist = useRef(0);
useFrame((_, dt) => {
dist.current += speed * dt;
model.position.z = dist.current;
model.userData.tick(dist.current); // wheels roll exactly with the distance
});
return <primitive object={model} />;
}# Import siege-tower.glb (download below). It carries an in-place "Loop" animation.
@onready var anim: AnimationPlayer = $SiegeTower/AnimationPlayer
func _physics_process(delta):
velocity = transform.basis.z * speed
move_and_slide()
anim.play("Loop")
anim.speed_scale = speed / 4.084 # one Loop = 4.084 m of travel// Import siege-tower.glb with glTFast (com.unity.cloud.gltfast).
animator.Play("Loop");
animator.speed = speed / 4.084 // one Loop = 4.084 m of travelUse the gaitkit MCP server: get_variant({ "id": "siege-tower", "want": "default look" })
then place the result and drive it with userData.tick(distance).
# MCP endpoint
https://gaitkit.com/mcpKnobs
| Knob | Type | Values | Default | What it does |
|---|---|---|---|---|
storeys | range | 3 to 5, step 1 | 4 | Floors of 2.8 m each. 3 reaches a 6 m curtain wall walk (castle-wall), 5 tops a tall tower. |
cover | choice | hides planks iron | hides | What protects the front and sides: hides (patchwork of wet animal hides against fire), planks (bare timber boarding), iron (riveted iron plates). |
wood | choice | oak pine weathered dark | oak | Timber tone of the frame and wheels: oak, pine (light), weathered (silver-grey), dark (tarred). |
banner | choice | crimson azure forest gold violet black | crimson | Colour of the flag on the top platform: crimson, azure, forest, gold, violet or black. |
Presets: iron belfry {"cover":"iron","wood":"dark","storeys":5,"banner":"black"} · wall stormer {"storeys":3,"cover":"planks","wood":"pine","banner":"gold"} · hide tower {"cover":"hides","banner":"forest"}
Files
| File | What |
|---|---|
| siege-tower.glb | GLB, default look · 367 KB |
| siege-tower.mjs | ES module, every knob live |
| siege-tower.obj | OBJ, static, no colour |
| siege-tower-params.json | knob schema, presets, night zones |
Licence
Use it in games, apps, renders and client work, commercially and without credit. Do not resell it as an asset or train a 3D generator on it. The full licence.