using_servers.rst 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. .. _doc_using_servers:
  2. Optimization using Servers
  3. ==========================
  4. Engines like Godot provide increased ease of use thanks to their high level constructs and features.
  5. Most of them are accessed and used via the :ref:`Scene System<doc_scene_tree>`. Using nodes and
  6. resources simplifies project organization and asset management in complex games.
  7. There are, of course, always drawbacks:
  8. * There is an extra layer of complexity
  9. * Performance is lower than using simple APIs directly
  10. * It is not possible to use multiple threads to control them
  11. * More memory is needed.
  12. In many cases, this is not really a problem (Godot is very optimized, and most operations are handled
  13. with signals, so no polling is required). Still, sometimes it can be. For example, dealing with
  14. tens of thousands of instances for something that needs to be processed every frame can be a bottleneck.
  15. This type of situation makes programmers regret they are using a game engine and wish they could go
  16. back to a more handcrafted, low level implementation of game code.
  17. Still, Godot is designed to work around this problem.
  18. Servers
  19. -------
  20. One of the most interesting design decisions for Godot, is the fact that the whole scene system is
  21. *optional*. While it is not currently possible to compile it out, it can be completely bypassed.
  22. At the core, Godot uses the concept of Servers. They are very low level APIs to control
  23. rendering, physics, sound, etc. The scene system is built on top of them and uses them directly.
  24. The most common servers are:
  25. * :ref:`VisualServer <class_VisualServer>`: handles everything related to graphics.
  26. * :ref:`PhysicsServer <class_PhysicsServer>`: handles everything related to 3D physics.
  27. * :ref:`Physics2DServer <class_Physics2DServer>`: handles everything related to 2D physics.
  28. * :ref:`AudioServer <class_AudioServer>`: handles everything related to audio.
  29. Just explore their APIs and you will realize that the all functions provided are low-level
  30. implementations of everything Godot allows you to do.
  31. RIDs
  32. ----
  33. The key to using servers is understanding Resource ID (:ref:`RID <class_RID>`) objects. These are opaque
  34. handles to the server implementation. They are allocated and freed manually. Almost every
  35. function in the servers requires RIDs to access the actual resource.
  36. Most Godot nodes and resources contain these RIDs from the servers internally, and they can
  37. be obtained with different functions. In fact, anything that inherits :ref:`Resource <class_Resource>`
  38. can be directly casted to an RID (not all resources contain an RID, though, in such cases
  39. the RID will be empty). In fact, resources can be passed to server APIs as RIDs. Just make
  40. sure to keep references to the resources outside the server, because if the resource is erased,
  41. the internal RID is erased too.
  42. For nodes, there are many functions available:
  43. * For CanvasItem, the :ref:`CanvasItem.get_canvas_item() <class_CanvasItem_method_get_canvas_item>`
  44. method will return the canvas item RID in the server.
  45. * For CanvasLayer, the :ref:`CanvasLayer.get_canvas() <class_CanvasLayer_method_get_canvas>`
  46. method will return the canvas RID in the server.
  47. * For Viewport, the :ref:`Viewport.get_viewport_rid() <class_Viewport_method_get_viewport_rid>`
  48. method will return the viewport RID in the server.
  49. * For 3D, the :ref:`World <class_World>` resource (obtainable in the :ref:`Viewport <class_Viewport>`
  50. and :ref:`Spatial <class_Spatial>` nodes)
  51. contains functions to get the *VisualServer Scenario*, and the *PhysicsServer Space*. This
  52. allows creating 3D objects directly with the server API and using them.
  53. * For 2D, the :ref:`World2D <class_World2D>` resource (obtainable in the :ref:`Viewport <class_Viewport>`
  54. and :ref:`CanvasItem <class_CanvasItem>` nodes)
  55. contains functions to get the *VisualServer Canvas*, and the *Physics2DServer Space*. This
  56. allows creating 2D objects directly with the server API and using them.
  57. * The :ref:`VisualInstance<class_VisualInstance>` class, allows getting the scenario *instance* and
  58. *instance base* via the :ref:`VisualInstance.get_instance() <class_VisualInstance_method_get_instance>`
  59. and :ref:`VisualInstance.get_base() <class_VisualInstance_method_get_base>` respectively.
  60. Just explore the nodes and resources you are familiar with and find the functions to obtain the server *RIDs*.
  61. It is not advised to control RIDs from objects that already have a node associated. Instead, server
  62. functions should always be used for creating and controlling new ones and interacting with the existing ones.
  63. Creating a sprite
  64. -----------------
  65. This is a simple example of how to create a sprite from code and move it using the low-level
  66. :ref:`CanvasItem <class_CanvasItem>` API.
  67. .. tabs::
  68. .. code-tab:: gdscript GDScript
  69. extends Node2D
  70. # VisualServer expects references to be kept around.
  71. var texture
  72. func _ready():
  73. # Create a canvas item, child of this node.
  74. var ci_rid = VisualServer.canvas_item_create()
  75. # Make this node the parent.
  76. VisualServer.canvas_item_set_parent(ci_rid, get_canvas_item())
  77. # Draw a texture on it.
  78. # Remember, keep this reference.
  79. texture = load("res://my_texture.png")
  80. # Add it, centered.
  81. VisualServer.canvas_item_add_texture_rect(ci_rid, Rect2(texture.get_size() / 2, texture.get_size()), texture)
  82. # Add the item, rotated 45 degrees and translated.
  83. var xform = Transform2D().rotated(deg2rad(45)).translated(Vector2(20, 30))
  84. VisualServer.canvas_item_set_transform(ci_rid, xform)
  85. The Canvas Item API in the server allows you to add draw primitives to it. Once added, they can't be modified.
  86. The Item needs to be cleared and the primitives re-added (this is not the case for setting the transform,
  87. which can be done as many times as desired).
  88. Primitives are cleared this way:
  89. .. tabs::
  90. .. code-tab:: gdscript GDScript
  91. VisualServer.canvas_item_clear(ci_rid)
  92. Instantiating a Mesh into 3D space
  93. ----------------------------------
  94. The 3D APIs are different from the 2D ones, so the instantiation API must be used.
  95. .. tabs::
  96. .. code-tab:: gdscript GDScript
  97. extends Spatial
  98. # VisualServer expects references to be kept around.
  99. var mesh
  100. func _ready():
  101. # Create a visual instance (for 3D).
  102. var instance = VisualServer.instance_create()
  103. # Set the scenario from the world, this ensures it
  104. # appears with the same objects as the scene.
  105. var scenario = get_world().scenario
  106. VisualServer.instance_set_scenario(instance, scenario)
  107. # Add a mesh to it.
  108. # Remember, keep the reference.
  109. mesh = load("res://mymesh.obj")
  110. VisualServer.instance_set_base(instance, mesh)
  111. # Move the mesh around.
  112. var xform = Transform(Basis(), Vector3(20, 100, 0))
  113. VisualServer.instance_set_transform(instance, xform)
  114. Creating a 2D RigidBody and moving a sprite with it
  115. ---------------------------------------------------
  116. This creates a :ref:`RigidBody2D <class_RigidBody2D>` using the :ref:`Physics2DServer <class_Physics2DServer>` API,
  117. and moves a :ref:`CanvasItem <class_CanvasItem>` when the body moves.
  118. .. tabs::
  119. .. code-tab:: gdscript GDScript
  120. # Physics2DServer expects references to be kept around.
  121. var body
  122. var shape
  123. func _body_moved(state, index):
  124. # Created your own canvas item, use it here.
  125. VisualServer.canvas_item_set_transform(canvas_item, state.transform)
  126. func _ready():
  127. # Create the body.
  128. body = Physics2DServer.body_create()
  129. Physics2DServer.body_set_mode(body, Physics2DServer.BODY_MODE_RIGID)
  130. # Add a shape.
  131. shape = RectangleShape2D.new()
  132. shape.extents = Vector2(10, 10)
  133. # Make sure to keep the shape reference!
  134. Physics2DServer.body_add_shape(body, shape)
  135. # Set space, so it collides in the same space as current scene.
  136. Physics2DServer.body_set_space(body, get_world_2d().space)
  137. # Move initial position.
  138. Physics2DServer.body_set_state(body, Physics2DServer.BODY_STATE_TRANSFORM, Transform2D(0, Vector2(10, 20)))
  139. # Add the transform callback, when body moves
  140. # The last parameter is optional, can be used as index
  141. # if you have many bodies and a single callback.
  142. Physics2DServer.body_set_force_integration_callback(body, self, "_body_moved", 0)
  143. The 3D version should be very similar, as 2D and 3D physics servers are identical (using
  144. :ref:`RigidBody <class_RigidBody>` and :ref:`PhysicsServer <class_PhysicsServer>` respectively).
  145. Getting data from the servers
  146. -----------------------------
  147. Try to **never** request any information from ``VisualServer``, ``PhysicsServer`` or ``Physics2DServer``
  148. by calling functions unless you know what you are doing. These servers will often run asynchronously
  149. for performance and calling any function that returns a value will stall them and force them to process
  150. anything pending until the function is actually called. This will severely decrease performance if you
  151. call them every frame (and it won't be obvious why).
  152. Because of this, most APIs in such servers are designed so it's not even possible to request information
  153. back, until it's actual data that can be saved.