Work in progress

The content of this page was not yet updated for Godot 4.0 and may be outdated. If you know how to improve this page or you can confirm that it's up to date, feel free to open a pull request.

Creating your first script

In this lesson, you will code your first script to make the Godot icon turn in circles using GDScript. As we mentioned in the introduction, we assume you have programming foundations. The equivalent C# code has been included in another tab for convenience.

../../_images/scripting_first_script_rotating_godot.gif

See also

To learn more about GDScript, its keywords, and its syntax, head to the GDScript reference.

See also

To learn more about C#, head to the C# basics page.

Project setup

Please create a new project to start with a clean slate. Your project should contain one picture: the Godot icon, which we often use for prototyping in the community.

We need to create a Sprite2D node to display it in the game. In the Scene dock, click the Other Node button.

../../_images/scripting_first_script_click_other_node.png

Type "Sprite2D" in the search bar to filter nodes and double-click on Sprite2D to create the node.

../../_images/scripting_first_script_add_sprite_node.webp

Your Scene tab should now only have a Sprite2D node.

../../_images/scripting_first_script_scene_tree.webp

A Sprite2D node needs a texture to display. In the Inspector on the right, you can see that the Texture property says "[empty]". To display the Godot icon, click and drag the file icon.svg from the FileSystem dock onto the Texture slot.

../../_images/scripting_first_script_setting_texture.webp

Note

You can create Sprite2D nodes automatically by dragging and dropping images on the viewport.

../../_images/scripting_first_script_dragging_sprite.png

Then, click and drag the icon in the viewport to center it in the game view.

../../_images/scripting_first_script_centering_sprite.png

Creating a new script

To create and attach a new script to our node, right-click on Sprite2D in the scene dock and select "Attach Script".

../../_images/scripting_first_script_attach_script.webp

The Attach Node Script window appears. It allows you to select the script's language and file path, among other options.

Change the Template field from "Node: Default" to "Object: Empty" to start with a clean file. Leave the other options by default and click the Create button to create the script.

../../_images/scripting_first_script_attach_node_script.webp

The Script workspace should appear with your new sprite_2d.gd file open and the following line of code:

extends Sprite2D

Every GDScript file is implicitly a class. The extends keyword defines the class this script inherits or extends. In this case, it's Sprite2D, meaning our script will get access to all the properties and functions of the Sprite2D node, including classes it extends, like Node2D, CanvasItem, and Node.

Note

In GDScript, if you omit the line with the extends keyword, your class will implicitly extend RefCounted, which Godot uses to manage your application's memory.

Inherited properties include the ones you can see in the Inspector dock, like our node's texture.

Note

By default, the Inspector displays a node's properties in "Title Case", with capitalized words separated by a space. In GDScript code, these properties are in "snake_case", which is lowercase with words separated by an underscore.

You can hover over any property's name in the Inspector to see a description and its identifier in code.

Hello, world!

Our script currently doesn't do anything. Let's make it print the text "Hello, world!" to the Output bottom panel to get started.

Add the following code to your script:

func _init():
    print("Hello, world!")

Let's break it down. The func keyword defines a new function named _init. This is a special name for our class's constructor. The engine calls _init() on every object or node upon creating it in memory, if you define this function.

Note

GDScript is an indent-based language. The tab at the start of the line that says print() is necessary for the code to work. If you omit it or don't indent a line correctly, the editor will highlight it in red and display the following error message: "Indented block expected".

Save the scene as sprite_2d.tscn if you haven't already, then press F6 (Cmd + R on macOS) to run it. Look at the Output bottom panel that expands. It should display "Hello, world!".

../../_images/scripting_first_script_print_hello_world.png

Delete the _init() function, so you're only left with the line extends Sprite2D.

Turning around

It's time to make our node move and rotate. To do so, we're going to add two member variables to our script: the movement speed in pixels per second and the angular speed in radians per second. Add the following after the extends Sprite2D line.

var speed = 400
var angular_speed = PI

Member variables sit near the top of the script, after any "extends" lines, but before functions. Every node instance with this script attached to it will have its own copy of the speed and angular_speed properties.

Note

Angles in Godot work in radians by default, but you have built-in functions and properties available if you prefer to calculate angles in degrees instead.

To move our icon, we need to update its position and rotation every frame in the game loop. We can use the _process() virtual function of the Node class. If you define it in any class that extends the Node class, like Sprite2D, Godot will call the function every frame and pass it an argument named delta, the time elapsed since the last frame.

Note

Games work by rendering many images per second, each called a frame, and they do so in a loop. We measure the rate at which a game produces images in Frames Per Second (FPS). Most games aim for 60 FPS, although you might find figures like 30 FPS on slower mobile devices or 90 to 240 for virtual reality games.

The engine and game developers do their best to update the game world and render images at a constant time interval, but there are always small variations in frame render times. That's why the engine provides us with this delta time value, making our motion independent of our framerate.

At the bottom of the script, define the function:

func _process(delta):
    rotation += angular_speed * delta

The f