Optimization using Servers


There are, of course, always drawbacks:

  • There is an extra layer of complexity
  • Performance is lower than using simple APIs directly
  • It is not possible to use multiple threads to control them
  • More memory is needed.



Still, Godot is designed to work around this problem.




  • VisualServer: handles everything related to graphics.
  • PhysicsServer: handles everything related to 3D physics.
  • Physics2DServer: handles everything related to 2D physics.
  • AudioServer: handles everything related to audio.



The key to using servers is understanding Resource ID (RID) objects. These are opaque handles to the sever implementation. They are allocated and freed manually. Almost every function in the servers requires RIDs to access the actual resource.


For nodes, there are many functions available:

  • Pour CanvasItem, la méthode CanvasItem.get_canvas_item() retourne l’élément RID du canvas dans le serveur.
  • For CanvasLayer, the CanvasLayer.get_canvas() method will return the canvas RID in the server.
  • For Viewport, the Viewport.get_viewport_rid() method will return the viewport RID in the server.
  • For 3D, the World resource (obtainable in the Viewport and Spatial nodes) contains functions to get the VisualServer Scenario, and the PhysicsServer Space. This allows creating 3D objects directly with the server API and using them.
  • For 2D, the World2D resource (obtainable in the Viewport and CanvasItem nodes) contains functions to get the VisualServer Canvas, and the Physics2DServer Space. This allows creating 2D objects directly with the server API and using them.
  • The VisualInstance class, allows getting the scenario instance and instance base via the VisualInstance.get_instance() and VisualInstance.get_base() respectively.



Création d’un sprite


extends Node2D

func _ready():
    # Create a canvas item, child of this node.
    var ci_rid = VisualServer.canvas_item_create()
    # Make this node the parent.
    VisualServer.canvas_item_set_parent(ci_rid, get_canvas_item())
    # Draw a sprite on it.
    # Remember, keep this reference.
    var sprite = load("res://mysprite.png")
    # Add it, centered.
    # Add the item, rotated 45 degrees and translated.
    VisualServer.canvas_item_set_transform(ci_rid, xform)

The Canvas Item API in the server allows you to add draw primitives to it. Once added, they can’t be modified. The Item needs to be cleared and the primitives re-added (this is not the case for setting the transform, which can be done as many times as desired).

Primitives are cleared this way:


Instantiating a Mesh into 3D space

The 3D APIs are different than the 2D ones, so the instantiation API must be used.

extends Spatial

func _ready():
    # Create a visual instance (for 3D).
    var instance = VisualServer.instance_create()
    # Set the scenario from the world, this ensures it
    # appears with the same objects as the scene.
    var scenario = get_world().scenario
    VisualServer.instance_set_scenario(instance, scenario)
    # Add a mesh to it.
    # Remember, keep the reference.
    var mesh = load("res://mymesh.obj")
    VisualServer.instance_set_base(instance, mesh)
    # Move the mesh around.
    VisualServer.instance_set_transform(instance, xform)

Creating a 2D RigidBody and moving a sprite with it


func _body_moved(state, index):
    # Created your own canvas item, use it here.
    VisualServer.canvas_item_set_transform(canvas_item, state.transform)

func _ready():
    # Create the body.
    var body = Physics2DServer.body_create()
    Physics2DServer.body_set_mode(body, Physics2DServer.BODY_MODE_RIGID)
    # Add a shape.
    var shape = RectangleShape2D.new()
    shape.extents = Vector2(10, 10)
    # Make sure to keep the shape reference!
    Physics2DServer.body_add_shape(body, shape)
    Physics2DServer.body_set_space(body, get_world_2d().space)
    # Move initial position.
    # Add the transform callback, when body moves
    # The last parameter is optional, can be used as index
    # if you have many bodies and a single callback.
    Physics2DServer.body_set_force_integration_callback(body, self, "_body_moved", 0)


Obtention des données depuis les serveurs


Because of this, most APIs in such servers are designed so it’s not even possible to request information back, until it’s actual data that can be saved.