Python scripts
Every scene has a script: Home → Script opens it in a tab beside the scene. Press ▶ Run (⌘Enter) to run it, ■ Stop to stop. The script is saved with the scene. To keep a script on its own, press Save… in the Script tab: it goes to My Assets (this device, or your account), and Open… brings it back into any scene. Examples in the Script tab opens the ready-made ones in the Marketplace (a PID-balanced cart-pole, a projectile experiment, orbits …); one you choose goes into the Script tab and runs when you press Run.
import studio as s
s.clear()
s.ground()
ball = s.circle(0, 2, 0.1, mass=0.5, name="Ball")
@s.on_step
def push(t, dt):
ball.force = (1.0, 0.0) # newtons, until changed
s.record(t=t, x=ball.x, v=ball.vx)
s.run(3) # seconds
Units are SI. x points right and y up; angles are in radians, counter-clockwise positive, as in Properties. The full list of functions is the Python reference.
What a script can do
- Build a scene in code: bodies, grounds, joints, in loops (a chain of 20 pendulums, a grid of boxes).
- Control it while it runs: a function decorated with
@s.on_stepruns before every simulation step and can set forces, torques, motor speeds and positions — a controller, a thrust schedule, a switch. - React to events:
@s.on_collisionwhen two bodies start touching,@s.on_endwhen the run ends. - Measure: read any body's or joint's state, and
s.record(...)rows into a table (the Script sheet of the Table tab) for graphs and CSV. - Experiment: run, reset, change a parameter, run again — and print a result.
How it runs
Run sends the script and the scene to Python (Pyodide) running in a separate, locked-down worker of the browser: it has no network, no storage and no access to the page. Python asks the studio for what it wants (make a body, set a force, record a row); the studio checks every request and applies it. A script that does not answer within a few seconds is stopped, so an endless loop cannot freeze the studio. Loading Python takes a few seconds the first time, then well under a second.
In the studio s.run() ends the script's top level and the simulation then runs; put what should happen afterwards in a function decorated with @s.on_end. Run starts from the scene as it was before the last run, and is one undo step.
A scene you open from someone else may contain a script: it runs only when you press Run, and never in a shared link's player.
The same script on your computer
The studio module also runs locally against the engine's Python module, at the studio's Research step, and prints the same results:
PYTHONPATH=PhysicsEngineCore:PhysicsEngineCore/python python3 cartpole_pid.py
There s.run() returns when the time is up, and s.open("scene.physics.json") loads a scene saved by the studio.