gdscript_styleguide.rst 25 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064
  1. .. _doc_gdscript_styleguide:
  2. GDScript style guide
  3. ====================
  4. This style guide lists conventions to write elegant GDScript. The goal is to
  5. encourage writing clean, readable code and promote consistency across projects,
  6. discussions, and tutorials. Hopefully, this will also support the development of
  7. auto-formatting tools.
  8. Since GDScript is close to Python, this guide is inspired by Python's
  9. `PEP 8 <https://www.python.org/dev/peps/pep-0008/>`__ programming
  10. style guide.
  11. Style guides aren't meant as hard rulebooks. At times, you may not be able to
  12. apply some of the guidelines below. When that happens, use your best judgment,
  13. and ask fellow developers for insights.
  14. In general, keeping your code consistent in your projects and within your team is
  15. more important than following this guide to a tee.
  16. .. note::
  17. Godot's built-in script editor uses a lot of these conventions
  18. by default. Let it help you.
  19. Here is a complete class example based on these guidelines:
  20. ::
  21. class_name StateMachine
  22. extends Node
  23. ## Hierarchical State machine for the player.
  24. ##
  25. ## Initializes states and delegates engine callbacks ([method Node._physics_process],
  26. ## [method Node._unhandled_input]) to the state.
  27. signal state_changed(previous, new)
  28. @export var initial_state: Node
  29. var is_active = true:
  30. set = set_is_active
  31. @onready var _state = initial_state:
  32. set = set_state
  33. @onready var _state_name = _state.name
  34. func _init():
  35. add_to_group("state_machine")
  36. func _enter_tree():
  37. print("this happens before the ready method!")
  38. func _ready():
  39. state_changed.connect(_on_state_changed)
  40. _state.enter()
  41. func _unhandled_input(event):
  42. _state.unhandled_input(event)
  43. func _physics_process(delta):
  44. _state.physics_process(delta)
  45. func transition_to(target_state_path, msg={}):
  46. if not has_node(target_state_path):
  47. return
  48. var target_state = get_node(target_state_path)
  49. assert(target_state.is_composite == false)
  50. _state.exit()
  51. self._state = target_state
  52. _state.enter(msg)
  53. Events.player_state_changed.emit(_state.name)
  54. func set_is_active(value):
  55. is_active = value
  56. set_physics_process(value)
  57. set_process_unhandled_input(value)
  58. set_block_signals(not value)
  59. func set_state(value):
  60. _state = value
  61. _state_name = _state.name
  62. func _on_state_changed(previous, new):
  63. print("state changed")
  64. state_changed.emit()
  65. class State:
  66. var foo = 0
  67. func _init():
  68. print("Hello!")
  69. .. _formatting:
  70. Formatting
  71. ----------
  72. Encoding and special characters
  73. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  74. * Use line feed (**LF**) characters to break lines, not CRLF or CR. *(editor default)*
  75. * Use one line feed character at the end of each file. *(editor default)*
  76. * Use **UTF-8** encoding without a `byte order mark <https://en.wikipedia.org/wiki/Byte_order_mark>`_. *(editor default)*
  77. * Use **Tabs** instead of spaces for indentation. *(editor default)*
  78. Indentation
  79. ~~~~~~~~~~~
  80. Each indent level should be one greater than the block containing it.
  81. **Good**:
  82. .. rst-class:: code-example-good
  83. ::
  84. for i in range(10):
  85. print("hello")
  86. **Bad**:
  87. .. rst-class:: code-example-bad
  88. ::
  89. for i in range(10):
  90. print("hello")
  91. for i in range(10):
  92. print("hello")
  93. Use 2 indent levels to distinguish continuation lines from
  94. regular code blocks.
  95. **Good**:
  96. .. rst-class:: code-example-good
  97. ::
  98. effect.interpolate_property(sprite, "transform/scale",
  99. sprite.get_scale(), Vector2(2.0, 2.0), 0.3,
  100. Tween.TRANS_QUAD, Tween.EASE_OUT)
  101. **Bad**:
  102. .. rst-class:: code-example-bad
  103. ::
  104. effect.interpolate_property(sprite, "transform/scale",
  105. sprite.get_scale(), Vector2(2.0, 2.0), 0.3,
  106. Tween.TRANS_QUAD, Tween.EASE_OUT)
  107. Exceptions to this rule are arrays, dictionaries, and enums. Use a single
  108. indentation level to distinguish continuation lines:
  109. **Good**:
  110. .. rst-class:: code-example-good
  111. ::
  112. var party = [
  113. "Godot",
  114. "Godette",
  115. "Steve",
  116. ]
  117. var character_dict = {
  118. "Name": "Bob",
  119. "Age": 27,
  120. "Job": "Mechanic",
  121. }
  122. enum Tiles {
  123. TILE_BRICK,
  124. TILE_FLOOR,
  125. TILE_SPIKE,
  126. TILE_TELEPORT,
  127. }
  128. **Bad**:
  129. .. rst-class:: code-example-bad
  130. ::
  131. var party = [
  132. "Godot",
  133. "Godette",
  134. "Steve",
  135. ]
  136. var character_dict = {
  137. "Name": "Bob",
  138. "Age": 27,
  139. "Job": "Mechanic",
  140. }
  141. enum Tiles {
  142. TILE_BRICK,
  143. TILE_FLOOR,
  144. TILE_SPIKE,
  145. TILE_TELEPORT,
  146. }
  147. Trailing comma
  148. ~~~~~~~~~~~~~~
  149. Use a trailing comma on the last line in arrays, dictionaries, and enums. This
  150. results in easier refactoring and better diffs in version control as the last
  151. line doesn't need to be modified when adding new elements.
  152. **Good**:
  153. .. rst-class:: code-example-good
  154. ::
  155. var array = [
  156. 1,
  157. 2,
  158. 3,
  159. ]
  160. **Bad**:
  161. .. rst-class:: code-example-bad
  162. ::
  163. var array = [
  164. 1,
  165. 2,
  166. 3
  167. ]
  168. Trailing commas are unnecessary in single-line lists, so don't add them in this case.
  169. **Good**:
  170. .. rst-class:: code-example-good
  171. ::
  172. var array = [1, 2, 3]
  173. **Bad**:
  174. .. rst-class:: code-example-bad
  175. ::
  176. var array = [1, 2, 3,]
  177. Blank lines
  178. ~~~~~~~~~~~
  179. Surround functions and class definitions with two blank lines:
  180. ::
  181. func heal(amount):
  182. health += amount
  183. health = min(health, max_health)
  184. health_changed.emit(health)
  185. func take_damage(amount, effect=null):
  186. health -= amount
  187. health = max(0, health)
  188. health_changed.emit(health)
  189. Use one blank line inside functions to separate logical sections.
  190. .. note::
  191. We use a single line between classes and function definitions in the class reference and
  192. in short code snippets in this documentation.
  193. Line length
  194. ~~~~~~~~~~~
  195. Keep individual lines of code under 100 characters.
  196. If you can, try to keep lines under 80 characters. This helps to read the code
  197. on small displays and with two scripts opened side-by-side in an external text
  198. editor. For example, when looking at a differential revision.
  199. One statement per line
  200. ~~~~~~~~~~~~~~~~~~~~~~
  201. Avoid combining multiple statements on a single line, including conditional
  202. statements, to adhere to the GDScript style guidelines for readability.
  203. **Good**:
  204. .. rst-class:: code-example-good
  205. ::
  206. if position.x > width:
  207. position.x = 0
  208. if flag:
  209. print("flagged")
  210. **Bad**:
  211. .. rst-class:: code-example-bad
  212. ::
  213. if position.x > width: position.x = 0
  214. if flag: print("flagged")
  215. The only exception to that rule is the ternary operator:
  216. ::
  217. next_state = "idle" if is_on_floor() else "fall"
  218. Format multiline statements for readability
  219. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  220. When you have particularly long ``if`` statements or nested ternary expressions,
  221. wrapping them over multiple lines improves readability. Since continuation lines
  222. are still part of the same expression, 2 indent levels should be used instead of one.
  223. GDScript allows wrapping statements using multiple lines using parentheses or
  224. backslashes. Parentheses are favored in this style guide since they make for
  225. easier refactoring. With backslashes, you have to ensure that the last line
  226. never contains a backslash at the end. With parentheses, you don't have to
  227. worry about the last line having a backslash at the end.
  228. When wrapping a conditional expression over multiple lines, the ``and``/``or``
  229. keywords should be placed at the beginning of the line continuation, not at the
  230. end of the previous line.
  231. **Good**:
  232. .. rst-class:: code-example-good
  233. ::
  234. var angle_degrees = 135
  235. var quadrant = (
  236. "northeast" if angle_degrees <= 90
  237. else "southeast" if angle_degrees <= 180
  238. else "southwest" if angle_degrees <= 270
  239. else "northwest"
  240. )
  241. var position = Vector2(250, 350)
  242. if (
  243. position.x > 200 and position.x < 400
  244. and position.y > 300 and position.y < 400
  245. ):
  246. pass
  247. **Bad**:
  248. .. rst-class:: code-example-bad
  249. ::
  250. var angle_degrees = 135
  251. var quadrant = "northeast" if angle_degrees <= 90 else "southeast" if angle_degrees <= 180 else "southwest" if angle_degrees <= 270 else "northwest"
  252. var position = Vector2(250, 350)
  253. if position.x > 200 and position.x < 400 and position.y > 300 and position.y < 400:
  254. pass
  255. Avoid unnecessary parentheses
  256. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  257. Avoid parentheses in expressions and conditional statements. Unless
  258. necessary for order of operations or wrapping over multiple lines,
  259. they only reduce readability.
  260. **Good**:
  261. .. rst-class:: code-example-good
  262. ::
  263. if is_colliding():
  264. queue_free()
  265. **Bad**:
  266. .. rst-class:: code-example-bad
  267. ::
  268. if (is_colliding()):
  269. queue_free()
  270. .. _boolean_operators:
  271. Boolean operators
  272. ~~~~~~~~~~~~~~~~~
  273. Prefer the plain English versions of boolean operators, as they are the most accessible:
  274. - Use ``and`` instead of ``&&``.
  275. - Use ``or`` instead of ``||``.
  276. - Use ``not`` instead of ``!``.
  277. You may also use parentheses around boolean operators to clear any ambiguity.
  278. This can make long expressions easier to read.
  279. **Good**:
  280. .. rst-class:: code-example-good
  281. ::
  282. if (foo and bar) or not baz:
  283. print("condition is true")
  284. **Bad**:
  285. .. rst-class:: code-example-bad
  286. ::
  287. if foo && bar || !baz:
  288. print("condition is true")
  289. Comment spacing
  290. ~~~~~~~~~~~~~~~
  291. Regular comments (``#``) and documentation comments (``##``) should start with a
  292. space, but not code that you comment out. Additionally, code region comments
  293. (``#region``/``#endregion``) must follow that precise syntax, so they should not
  294. start with a space.
  295. Using a space for regular and documentation comments helps differentiate text
  296. comments from disabled code.
  297. **Good**:
  298. .. rst-class:: code-example-good
  299. ::
  300. # This is a comment.
  301. #print("This is disabled code")
  302. **Bad**:
  303. .. rst-class:: code-example-bad
  304. ::
  305. #This is a comment.
  306. # print("This is disabled code")
  307. .. note::
  308. In the script editor, to toggle commenting of the selected code, press
  309. :kbd:`Ctrl + K`. This feature adds/removes a single ``#`` sign before any
  310. code on the selected lines.
  311. Prefer writing comments on their own line as opposed to inline comments
  312. (comments written on the same line as code). Inline comments are best used for
  313. short comments, typically a few words at most:
  314. **Good**:
  315. .. rst-class:: code-example-good
  316. ::
  317. # This is a long comment that would make the line below too long if written inline.
  318. print("Example") # Short comment.
  319. **Bad**:
  320. .. rst-class:: code-example-bad
  321. ::
  322. print("Example") # This is a long comment that would make this line too long if written inline.
  323. Whitespace
  324. ~~~~~~~~~~
  325. Always use one space around operators and after commas. Also, avoid extra spaces
  326. in dictionary references and function calls. One exception to this is for
  327. single-line dictionary declarations, where a space should be added after the
  328. opening brace and before the closing brace. This makes the dictionary easier to
  329. visually distinguish from an array, as the ``[]`` characters look close to
  330. ``{}`` with most fonts.
  331. **Good**:
  332. .. rst-class:: code-example-good
  333. ::
  334. position.x = 5
  335. position.y = target_position.y + 10
  336. dict["key"] = 5
  337. my_array = [4, 5, 6]
  338. my_dictionary = { key = "value" }
  339. print("foo")
  340. **Bad**:
  341. .. rst-class:: code-example-bad
  342. ::
  343. position.x=5
  344. position.y = mpos.y+10
  345. dict ["key"] = 5
  346. myarray = [4,5,6]
  347. my_dictionary = {key = "value"}
  348. print ("foo")
  349. Don't use spaces to align expressions vertically:
  350. ::
  351. x = 100
  352. y = 100
  353. velocity = 500
  354. Quotes
  355. ~~~~~~
  356. Use double quotes unless single quotes make it possible to escape fewer
  357. characters in a given string. See the examples below:
  358. ::
  359. # Normal string.
  360. print("hello world")
  361. # Use double quotes as usual to avoid escapes.
  362. print("hello 'world'")
  363. # Use single quotes as an exception to the rule to avoid escapes.
  364. print('hello "world"')
  365. # Both quote styles would require 2 escapes; prefer double quotes if it's a tie.
  366. print("'hello' \"world\"")
  367. Numbers
  368. ~~~~~~~
  369. Don't omit the leading or trailing zero in floating-point numbers. Otherwise,
  370. this makes them less readable and harder to distinguish from integers at a
  371. glance.
  372. **Good**:
  373. .. rst-class:: code-example-good
  374. ::
  375. var float_number = 0.234
  376. var other_float_number = 13.0
  377. **Bad**:
  378. .. rst-class:: code-example-bad
  379. ::
  380. var float_number = .234
  381. var other_float_number = 13.
  382. Use lowercase for letters in hexadecimal numbers, as their lower height makes
  383. the number easier to read.
  384. **Good**:
  385. .. rst-class:: code-example-good
  386. ::
  387. var hex_number = 0xfb8c0b
  388. **Bad**:
  389. .. rst-class:: code-example-bad
  390. ::
  391. var hex_number = 0xFB8C0B
  392. Take advantage of GDScript's underscores in literals to make large numbers more
  393. readable.
  394. **Good**:
  395. .. rst-class:: code-example-good
  396. ::
  397. var large_number = 1_234_567_890
  398. var large_hex_number = 0xffff_f8f8_0000
  399. var large_bin_number = 0b1101_0010_1010
  400. # Numbers lower than 1000000 generally don't need separators.
  401. var small_number = 12345
  402. **Bad**:
  403. .. rst-class:: code-example-bad
  404. ::
  405. var large_number = 1234567890
  406. var large_hex_number = 0xfffff8f80000
  407. var large_bin_number = 0b110100101010
  408. # Numbers lower than 1000000 generally don't need separators.
  409. var small_number = 12_345
  410. .. _naming_conventions:
  411. Naming conventions
  412. ------------------
  413. These naming conventions follow the Godot Engine style. Breaking these will make
  414. your code clash with the built-in naming conventions, leading to inconsistent
  415. code. As a summary table:
  416. +---------------+----------------+----------------------------------------------------+
  417. | Type | Convention | Example |
  418. +===============+================+====================================================+
  419. | File names | snake_case | ``yaml_parser.gd`` |
  420. +---------------+----------------+----------------------------------------------------+
  421. | Class names | PascalCase | ``class_name YAMLParser`` |
  422. +---------------+----------------+----------------------------------------------------+
  423. | Node names | PascalCase | ``Camera3D``, ``Player`` |
  424. +---------------+----------------+----------------------------------------------------+
  425. | Functions | snake_case | ``func load_level():`` |
  426. +---------------+----------------+----------------------------------------------------+
  427. | Variables | snake_case | ``var particle_effect`` |
  428. +---------------+----------------+----------------------------------------------------+
  429. | Signals | snake_case | ``signal door_opened`` |
  430. +---------------+----------------+----------------------------------------------------+
  431. | Constants | CONSTANT_CASE | ``const MAX_SPEED = 200`` |
  432. +---------------+----------------+----------------------------------------------------+
  433. | Enum names | PascalCase | ``enum Element`` |
  434. +---------------+----------------+----------------------------------------------------+
  435. | Enum members | CONSTANT_CASE | ``{EARTH, WATER, AIR, FIRE}`` |
  436. +---------------+----------------+----------------------------------------------------+
  437. File names
  438. ~~~~~~~~~~
  439. Use snake_case for file names. For named classes, convert the PascalCase class
  440. name to snake_case::
  441. # This file should be saved as `weapon.gd`.
  442. class_name Weapon
  443. extends Node
  444. ::
  445. # This file should be saved as `yaml_parser.gd`.
  446. class_name YAMLParser
  447. extends Object
  448. This is consistent with how C++ files are named in Godot's source code. This
  449. also avoids case sensitivity issues that can crop up when exporting a project
  450. from Windows to other platforms.
  451. Classes and nodes
  452. ~~~~~~~~~~~~~~~~~
  453. Use PascalCase for class and node names:
  454. ::
  455. extends CharacterBody3D
  456. Also use PascalCase when loading a class into a constant or a variable:
  457. ::
  458. const Weapon = preload("res://weapon.gd")
  459. Functions and variables
  460. ~~~~~~~~~~~~~~~~~~~~~~~
  461. Use snake\_case to name functions and variables:
  462. ::
  463. var particle_effect
  464. func load_level():
  465. Prepend a single underscore (\_) to virtual methods functions the user must
  466. override, private functions, and private variables:
  467. ::
  468. var _counter = 0
  469. func _recalculate_path():
  470. Signals
  471. ~~~~~~~
  472. Use the past tense to name signals:
  473. ::
  474. signal door_opened
  475. signal score_changed
  476. Constants and enums
  477. ~~~~~~~~~~~~~~~~~~~
  478. Write constants with CONSTANT\_CASE, that is to say in all caps with an
  479. underscore (\_) to separate words:
  480. ::
  481. const MAX_SPEED = 200
  482. Use PascalCase for enum *names* and CONSTANT\_CASE for their members, as they
  483. are constants:
  484. ::
  485. enum Element {
  486. EARTH,
  487. WATER,
  488. AIR,
  489. FIRE,
  490. }
  491. Write enums with each item on its own line. This allows adding documentation comments above each item
  492. more easily, and also makes for cleaner diffs in version control when items are added or removed.
  493. **Good**:
  494. .. rst-class:: code-example-good
  495. ::
  496. enum Element {
  497. EARTH,
  498. WATER,
  499. AIR,
  500. FIRE,
  501. }
  502. **Bad**:
  503. .. rst-class:: code-example-bad
  504. ::
  505. enum Element { EARTH, WATER, AIR, FIRE }
  506. Code order
  507. ----------
  508. This section focuses on code order. For formatting, see
  509. :ref:`formatting`. For naming conventions, see :ref:`naming_conventions`.
  510. We suggest to organize GDScript code this way:
  511. ::
  512. 01. @tool, @icon, @static_unload
  513. 02. class_name
  514. 03. extends
  515. 04. ## doc comment
  516. 05. signals
  517. 06. enums
  518. 07. constants
  519. 08. static variables
  520. 09. @export variables
  521. 10. remaining regular variables
  522. 11. @onready variables
  523. 12. _static_init()
  524. 13. remaining static methods
  525. 14. overridden built-in virtual methods:
  526. 1. _init()
  527. 2. _enter_tree()
  528. 3. _ready()
  529. 4. _process()
  530. 5. _physics_process()
  531. 6. remaining virtual methods
  532. 15. overridden custom methods
  533. 16. remaining methods
  534. 17. subclasses
  535. And put the class methods and variables in the following order depending on their access modifiers:
  536. ::
  537. 1. public
  538. 2. private
  539. We optimized the order to make it easy to read the code from top to bottom, to
  540. help developers reading the code for the first time understand how it works, and
  541. to avoid errors linked to the order of variable declarations.
  542. This code order follows four rules of thumb:
  543. 1. Properties and signals come first, followed by methods.
  544. 2. Public comes before private.
  545. 3. Virtual callbacks come before the class's interface.
  546. 4. The object's construction and initialization functions, ``_init`` and
  547. ``_ready``, come before functions that modify the object at runtime.
  548. Class declaration
  549. ~~~~~~~~~~~~~~~~~
  550. If the code is meant to run in the editor, place the ``@tool`` annotation on the
  551. first line of the script.
  552. Follow with the optional ``@icon`` then the ``class_name`` if necessary. You can turn a
  553. GDScript file into a global type in your project using ``class_name``. For more
  554. information, see :ref:`doc_gdscript_basics_class_name`.
  555. Then, add the ``extends`` keyword if the class extends a built-in type.
  556. Following that, you should have the class's optional
  557. :ref:`documentation comments <doc_gdscript_documentation_comments>`.
  558. You can use that to explain the role of your class to your teammates, how it works,
  559. and how other developers should use it, for example.
  560. ::
  561. class_name MyNode
  562. extends Node
  563. ## A brief description of the class's role and functionality.
  564. ##
  565. ## The description of the script, what it can do,
  566. ## and any further detail.
  567. Signals and properties
  568. ~~~~~~~~~~~~~~~~~~~~~~
  569. Write signal declarations, followed by properties, that is to say, member
  570. variables, after the docstring.
  571. Enums should come after signals, as you can use them as export hints for other
  572. properties.
  573. Then, write constants, exported variables, public, private, and onready
  574. variables, in that order.
  575. ::
  576. signal player_spawned(position)
  577. enum Jobs {
  578. KNIGHT,
  579. WIZARD,
  580. ROGUE,
  581. HEALER,
  582. SHAMAN,
  583. }
  584. const MAX_LIVES = 3
  585. @export var job: Jobs = Jobs.KNIGHT
  586. @export var max_health = 50
  587. @export var attack = 5
  588. var health = max_health:
  589. set(new_health):
  590. health = new_health
  591. var _speed = 300.0
  592. @onready var sword = get_node("Sword")
  593. @onready var gun = get_node("Gun")
  594. .. note::
  595. GDScript evaluates ``@onready`` variables right before the ``_ready``
  596. callback. You can use that to cache node dependencies, that is to say, to get
  597. child nodes in the scene that your class relies on. This is what the example
  598. above shows.
  599. Member variables
  600. ~~~~~~~~~~~~~~~~
  601. Don't declare member variables if they are only used locally in a method, as it
  602. makes the code more difficult to follow. Instead, declare them as local
  603. variables in the method's body.
  604. Local variables
  605. ~~~~~~~~~~~~~~~
  606. Declare local variables as close as possible to their first use. This makes it
  607. easier to follow the code, without having to scroll too much to find where the
  608. variable was declared.
  609. Methods and static functions
  610. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  611. After the class's properties come the methods.
  612. Start with the ``_init()`` callback method, that the engine will call upon
  613. creating the object in memory. Follow with the ``_ready()`` callback, that Godot
  614. calls when it adds a node to the scene tree.
  615. These functions should come first because they show how the object is
  616. initialized.
  617. Other built-in virtual callbacks, like ``_unhandled_input()`` and
  618. ``_physics_process``, should come next. These control the object's main loop and
  619. interactions with the game engine.
  620. The rest of the class's interface, public and private methods, come after that,
  621. in that order.
  622. ::
  623. func _init():
  624. add_to_group("state_machine")
  625. func _ready():
  626. state_changed.connect(_on_state_changed)
  627. _state.enter()
  628. func _unhandled_input(event):
  629. _state.unhandled_input(event)
  630. func transition_to(target_state_path, msg={}):
  631. if not has_node(target_state_path):
  632. return
  633. var target_state = get_node(target_state_path)
  634. assert(target_state.is_composite == false)
  635. _state.exit()
  636. self._state = target_state
  637. _state.enter(msg)
  638. Events.player_state_changed.emit(_state.name)
  639. func _on_state_changed(previous, new):
  640. print("state changed")
  641. state_changed.emit()
  642. Static typing
  643. -------------
  644. GDScript supports :ref:`optional static typing<doc_gdscript_static_typing>`.
  645. Declared types
  646. ~~~~~~~~~~~~~~
  647. To declare a variable's type, use ``<variable>: <type>``:
  648. ::
  649. var health: int = 0
  650. To declare the return type of a function, use ``-> <type>``:
  651. ::
  652. func heal(amount: int) -> void:
  653. Inferred types
  654. ~~~~~~~~~~~~~~
  655. In most cases, you can let the compiler infer the type using ``:=``.
  656. Prefer ``:=`` when the type is written on the same line as the assignment,
  657. otherwise prefer writing the type explicitly.
  658. **Good**:
  659. .. rst-class:: code-example-good
  660. ::
  661. # The type can be int or float, and thus should be stated explicitly.
  662. var health: int = 0
  663. # The type is clearly inferred as Vector3.
  664. var direction := Vector3(1, 2, 3)
  665. Include the type hint when the type is ambiguous, and
  666. omit the type hint when it's redundant.
  667. **Bad**:
  668. .. rst-class:: code-example-bad
  669. ::
  670. # Typed as int, but it could be that float was intended.
  671. var health := 0
  672. # The type hint has redundant information.
  673. var direction: Vector3 = Vector3(1, 2, 3)
  674. # What type is this? It's not immediately clear to the reader, so it's bad.
  675. var value := complex_function()
  676. In some cases, the type must be stated explicitly, otherwise the behavior
  677. will not be as expected because the compiler will only be able to use
  678. the function's return type. For example, ``get_node()`` cannot infer a type
  679. unless the scene or file of the node is loaded in memory. In this case, you
  680. should set the type explicitly.
  681. **Good**:
  682. .. rst-class:: code-example-good
  683. ::
  684. @onready var health_bar: ProgressBar = get_node("UI/LifeBar")
  685. Alternatively, you can use the ``as`` keyword to cast the return type, and
  686. that type will be used to infer the type of the var.
  687. .. rst-class:: code-example-good
  688. ::
  689. @onready var health_bar := get_node("UI/LifeBar") as ProgressBar
  690. # health_bar will be typed as ProgressBar
  691. This option is also considered more :ref:`type-safe<doc_gdscript_static_typing_safe_lines>` than the first.
  692. **Bad**:
  693. .. rst-class:: code-example-bad
  694. ::
  695. # The compiler can't infer the exact type and will use Node
  696. # instead of ProgressBar.
  697. @onready var health_bar := get_node("UI/LifeBar")