Inner Classes
2025/12/27
- Type
- Learning Resource
- Format
- Glossary Article
- Version
- General
- Subject Tags
- Created
- Updated
- 2026/02/16
- 2025/12/27
Godot has two ways of creating new classes:
class_name keyword).class keyword in a script. It creates an inner class.Here's an example with two inner classes:
class Person:
var name := ""
var age := 0
class Superhero extends Person:
var power := ""Inner classes have a limitation compared to creating scripts: you cannot instantiate them from the editor, so you can't use them for nodes and resources that you'd like to interact with in the editor. You can only use them for data containers and helper classes.
But inner classes offer at least two benefits:
In this example, I define an inner class with a leading underscore, _Power to share code between the Flight and Fire classes and hide it from the outside world:
class_name Powers:
class _Power:
var name := ""
class Flight extends _Power:
var duration := 10
class Fire extends _Power:
var strength := 5With a script like this, anywhere in the project, you can call Powers.Flight.new() to create a new instance of Flight.
Grouping related classes together like this is something we call "namespacing". It compartmentalizes the code and helps to avoid naming conflicts. Imagine that you want a power named Fire and that you also need to define the magical element Fire in your game.
Because the Fire power is an inner class, you access it as Powers.Fire, and you can have two inner classes named Fire in the same project without conflicts.
Another feature of inner classes is to create well-typed objects to store data. Suppose I have a complicated function to get user properties for a web server connection. I could return a dictionary:
func get_connect_properties() -> Dictionary:
return {
"user_name": "AzureDiamond",
"password": "hunter2",
"server_ip": "localhost",
"port": 3000,
"role": "moderator"
}But then to know what keys are available, I need to look at the function's documentation or the source code. If I try to access a nonexistent key, I won't get any error until the game runs. It's a common source of bugs.
Instead, you can use an inner class to define the data structure:
class ConnectionProperties:
var user_name: String
var password: String
var server_ip: String
var port: int
var role: String
func get_connect_properties() -> ConnectionProperties:
var properties := ConnectionProperties.new()
properties.user_name = "AzureDiamond"
properties.password = "hunter2"
properties.server_ip = "localhost"
properties.port = 3000
properties.role = "moderator"
return propertiesNow, when someone uses get_connect_properties(), they get a well-typed object with autocompletion and error reporting in the editor.
Don't stop here. Step-by-step tutorials are fun but they only take you so far.
Try one of our proven study programs to become an independent Gamedev truly capable of realizing the games you’ve always wanted to make.
Get help from peers and pros on GDQuest's Discord server!
20,000 membersJoin ServerThere are multiple ways you can join our effort to create free and open source gamedev resources that are accessible to everyone!
Sponsor this library by learning gamedev with us onGDSchool
Learn MoreImprove and build on assets or suggest edits onGithub
Contributeshare this page and talk about GDQUest onRedditYoutubeTwitter…