Developer Guide (Version 1.12)

Physics Scripting Guide

When scripting physics, deciding on an appropriate threading strategy can be important. This topic offers physics scripting advice on threading and troubleshooting and provides some sample code.


When writing scripts that interact with physics, it is important to understand how the physics system processes requests. You can configure the physics system to run in several different ways, each with its own benefits and drawbacks. This guide covers the two most common configurations.

Physics on a Separate Thread

Running the physics simulation on its own thread takes advantage of a machine's multiple cores and should lead to faster frame rates on physics-intensive games. However, this approach can make gameplay scripting more complex.


This is the default configuration starting in Lumberyard 1.8.

The following diagram shows the relationships between the physics thread and main thread.

            Physics on a separate thread

If a change request arrives when the simulation is busy, the request is queued and is processed the next time the simulation runs. If the simulation is idle, the change request is processed immediately.

Similarly, if a query is made when the simulation is busy, the response contains the state from the end of the last simulation. If the simulation is idle when the query is made, the response represents the true latest state.

In the diagram, note how OnPrePhysicsUpdate and OnPostPhysicsUpdate run between simulations. This means that requests are processed immediately and queries represent the true latest state. You should avoid performing time-consuming tasks in the OnPrePhysicsUpdate and OnPostPhysicsUpdate functions. Such tasks delay the start of simulation on the physics thread.

During the OnTick event, the state of the simulation can vary. Requests are either queued or processed immediately depending on whether the simulation has been completed for the frame.

The following table provides some tips on using the OnTick, OnPrePhysicsUpdate, and OnPostPhysicsUpdate functions.

Function Good For Bad For EBus
OnTick Making fire-and-forget requests Knowing when a request is done processing TickBus



Making a request and reliably querying its impact Time-consuming tasks PhysicsSystemEventBus

Physics on the Main Thread

Running the physics simulation in the main thread makes gameplay scripting simpler and more reliable. All requests are processed immediately and all queries represent the latest state. However, a physics-intensive game is more likely to impact the frame rate.

The following diagram illustrates a physics simulation on the main thread.

            Physics in the main thread

To enable physics in the main thread, type the following in the game.cfg file:


Physics Scripting Tips and Tricks

Following are a few troubleshooting tips for physics scripting.

To turn on debug rendering of physics proxies

Do one of the following:

  • In the console, type the following: 

  • In Lumberyard Editor,in the Rollup Bar, click the Display Settings tab. Under Render Settings in the Profile Options section, select Show Proxy.

Correcting Objects That Float Away

If an entity floats away like a balloon, check the following common causes and solutions:

  • The entity has gone beyond the borders of the terrain. The solution is to stay on the terrain.

  • The entity has a low mass, and CryPhysics has determined that it is less dense than air. The solution is to adjust the mass or density.

Scripting with Physics Example

The following code example uses BehaviorContext syntax to script the physics for a rocket.

local rocket = { Properties = { InitialVelocity = {default=Vector3(), description="The initial speed and direction of the entity"}, Impulse = {default=Vector3(), description="The impulse to add every frame"}, }, } function rocket:OnActivate() PhysicsComponentRequestBus.Event.SetVelocity(self.entityId, self.Properties.InitialVelocity) self.TickHandler = TickBus.CreateHandler(self) end function rocket:OnTick(dt, scriptTime) PhysicsComponentRequestBus.Event.AddImpulse(self.Properties.Impulse) end function rocket:OnDeactivate() self.TickHandler:Disconnect() end return rocket