Skip to content

physics lib

Omar Mohamed edited this page Mar 11, 2026 · 5 revisions

Physics Engine

InteractiveStuff ships with a built-in Physics Engine script library written in Vyn. It simulates spring-based item rotation that reacts to player movement, camera rotation, and wind — giving held items a natural, physical feel without you having to write the math yourself.

Import it in any script with:

importScript("interactivestuff", "physics_engine")

How It Works

The physics engine maintains a spring-damper simulation on two rotation axes. Each frame, it accumulates forces from:

  • Player movement — acceleration when you walk, sprint, or strafe
  • Camera rotation — impulses from looking around
  • Vertical movement — jumping, falling, landing
  • Wind — a procedural layered sine wave that adds subtle organic drift

After calling runPhysicsEngine(...), the results are written to two global variables you can read directly:

Variable Description
angleX Current rotation angle on the X axis (pitch-like sway)
angleZ Current rotation angle on the Z axis (roll-like sway)

Apply these to your item using rotateX and rotateZ.


runPhysicsEngine(stiffness, damping, moveRes, lookRes, vertRes, inertial, maxAngle, windMult)

Runs one tick of the physics simulation. Call this once per frame at the top of your script before applying the resulting angles.

Returns 0 early (no-op) if called more than once in the same tick, or if the frame delta is too large (e.g. after a freeze or lag spike — in that case velocities are also reset for stability).

Parameters

Parameter Type Description
stiffness Double How strongly the item springs back to its resting position. Higher = snappier return. Recommended range: 0.10.5
damping Double How quickly oscillation dies out. Higher = less bouncy. Recommended range: 0.30.8
moveRes Double How strongly player movement acceleration affects the angles. Higher = more sway when walking/running. Recommended range: 1.05.0
lookRes Double How strongly camera rotation affects the angles. Higher = more tilt when turning. Recommended range: 0.53.0
vertRes Double How strongly vertical movement (jumping/falling) affects the X angle. Recommended range: 1.04.0
inertial Double Global inertia multiplier. Scales both wind forces and movement/look impulses. Higher = heavier, more sluggish feel. Recommended range: 0.52.0
maxAngle Double Maximum angle clamp in degrees. The simulation will not exceed this in either direction. Recommended range: 5.020.0
windMult Double Wind effect strength. Set to 0 to disable wind entirely. Recommended range: 0100

Usage Example

Basic sway

importScript("interactivestuff", "physics_engine")

~ Run the simulation each frame
runPhysicsEngine(0.2, 0.5, 2.0, 1.0, 1.5, 1.0, 15.0, 50)

~ Apply the resulting angles to the held item
make item player.getMainHandItem()
item.rotateX(angleX)
item.rotateZ(angleZ)

Heavy, sluggish weapon feel

importScript("interactivestuff", "physics_engine")

runPhysicsEngine(0.1, 0.4, 3.0, 1.5, 2.0, 1.8, 20.0, 30)

make item player.getMainHandItem()
item.rotateX(angleX)
item.rotateZ(angleZ)

Lightweight item, minimal sway, no wind

importScript("interactivestuff", "physics_engine")

runPhysicsEngine(0.4, 0.7, 1.0, 0.5, 0.8, 0.6, 8.0, 0)

make item player.getMainHandItem()
item.rotateX(angleX)
item.rotateZ(angleZ)

Combined with other transforms

importScript("interactivestuff", "physics_engine")

runPhysicsEngine(0.25, 0.55, 2.5, 1.2, 1.5, 1.0, 12.0, 40)

make item player.getMainHandItem()

~ Physics sway
item.rotateX(angleX)
item.rotateZ(angleZ)

~ Additional idle bob
make bob item.smooth(0, 0.03, 0.05 * getDelta())
item.translateY(bob)

Parameter Reference Summary

Goal Adjust
Snappier return to rest Increase stiffness
Less bouncy / more stable Increase damping
More sway when walking Increase moveRes
More tilt when turning Increase lookRes
Stronger jump/fall reaction Increase vertRes
Heavier, more inertial feel Increase inertial
Limit maximum lean angle Decrease maxAngle
Remove wind drift Set windMult to 0

Notes

  • The simulation is framerate-independent — it uses getDelta() internally so results are consistent at any FPS.
  • The engine resets automatically if a large frame spike is detected (delta > 5.0), preventing the item from flying off-screen after a freeze.
  • angleX and angleZ are global variables — they persist between frames and are updated in-place each call.
  • Only one physics simulation can run per script. If you need independent physics on multiple items (e.g. a parent and overlay), apply the same angleX/angleZ to both.

📖 InteractiveStuff Docs


🧱 Types


⚙️ Scripting

📃 Built-in Library

Clone this wiki locally