Any sufficiently large code base needs documentation. Documentation tends to come in all sorts of shapes and sizes. Among them are high-level architecture and design docs, class and method interface documentation, and inline comments to explain optimized or complex algorithms so the reader doesn’t have to parse the logic in their head (often, this is future you reading your own code six months later).
Following best practices and clean coding conventions go a long way in making code more understandable. Both also help minimize the need for documentation (that is a Good Thing™). Well-written code reads like poetry, bridging the gap between mathematical algorithms and plain, human-readable instructions. In most situations, documentation should focus on the “why” instead of the “how.” Code already tells you what it does, the documentation helps to understand better why it works that way.
Code exists to solve problems. After all, software developers aren’t just writers or typists, they’re problem solvers first and foremost. The problem that code eventually solves usually also has documentation and it comes in just as many formats: PRDs, GDDs, User Stories, Issue tickets, etc. Whatever the format is, refining the problem statement can also have a huge impact on clarity; often, half of the solution is understanding the problem better. The requirements format mostly depends on which industry you’re in, which development methodology is used, and how big the company is. The larger the company, the more difficult it is to track requirements, work in progress, and roadmaps. Some companies build out entire Product Management organizations, and even larger ones employ Program Management to coordinate Product Management and its interdependency and sequencing challenges — all of which come with overhead. It takes a lot of time and communication to achieve cohesion and alignment. It takes even more overhead if you want to measure how things are going using KPIs and OKRs, but I digress. Hence: If you want to go fast, go alone; if you want to go far, go together.
Code usually doesn’t exist in isolation, either. It has to fit into an ecosystem of libraries, modules, packages, addons, plugins, or extensions, which, when combined, solve larger, complex problems and can provide compelling solutions. Each unit of code has interfaces for what it needs and provides.
So far the takeaway should be that documentation is a necessary evil. If code is the solution, documentation is overhead. Any time spent on creating documentation is not spent on solving a problem. It’s also easily outdated, thus inaccurate, misleading, and can result in wasted time and effort. Ask anyone in a larger organization that uses tools like Confluence and JIRA. It’s not necessarily the tools’ fault. Atlassian makes fine solutions. The problem is that, the farther documentation lives from the code base, the less accurate it is, and the faster the two diverge. In my experience, the unspoken rule in more than one company was that “Confluence is where documentation goes to die.”
Including documentation as part of a code base is not new. Javadoc, JSDoc, PHPDoc, RDoc, etc have existed for decades. In many cases, the “insert language here”-doc formats are used for API documentation. While that’s helpful, it’s often not what developers are looking for. If I want to learn, let’s say, Vue.js, I don’t start with the API docs. I look for the guide instead, because it explains the concepts, use cases, best practices, and other reasons why code is written the way it is. Both types of documentation have their place, of course. The API is about cold, hard facts, while a guide provides more philosophical answers. Code and API docs tell you the what and the how. Guides explain the why.
Frankly, when I seek documentation, I’m typically more interested in approaches and the lens through which a problem is observed, decomposed, and solved. I expect my IDE to provide the API documentation as part of its syntax completion and static analysis tooling.
And I have to say, that’s something I enjoy about using GDScript: The GDScript documentation comments syntax supports everything I’d expect from a documentation system. The ability to reference code through BBCode along with the built-in documentation browsing capabilities in the Godot editor makes it incredibly convenient to look up information quickly. The only thing on my wishlist is the ability to use the “Open Documentation” button in the property inspector to open custom scripts. Unfortunately, it only opens the built-in class the script is based on. I suspect this is related to the limitation of the
Object.get_class()
method.
Sometimes, though, it’s nice to be able to generate external documentation. JavaScript has the JSDoc generator, for example.
For Godot 3 (and Godot 4, it seems), GDQuest’s gdscript-docs-maker is a tool to generate markdown-based documentation from GDScripts. It uses the more or less undocumented
GDScriptLanguageProtocol
singleton to extract the definitions, which are converted to Markdown with the help of a Python script. However, accessing the GDScriptLanguageProtocol is somewhat buggy, per GitHub issue #86132 (Cannot access the
GDScriptLanguageProtocol
in GDScript).
The eh_DocsExporter is based on GDQuest’s gdscript-docs-maker but works entirely within Godot (3), which means no more dependencies on Docker or Python.
More recently, Godot got a built-in docs exporter, but it’s not as easy to use:
GitHub issue #79497 (Palindrome, woo!): –doctool –gdscript-docs doesn’t work with preload or global class names.
Fixed by PR #76490: Dump API docs from inline GDScript comments using –doctool –gdscript-docs PATH
GitHub issue #84579: Attempting to use –doctool –gdscript-docs gives error Class “class name” hides a global script class.
Partially (?) fixed by PR #82116: Fix
--gdscript-docs
tool failing when autoloads are used in the project.
I couldn’t make it work until I noticed this comment in issue #84579: The TL;DR is that rather than running “
godot --doctool docs/ --gdscript-docs addons/my_addon
“, the gdscript-docs argument should be specified in
res://
format, due to a potentially difficult-to-fix bug.
So to generate the documentation for an entire project (and saving it in docs/classes) is:
godot--doctooldocs/classes--gdscript-docsres://
That will generate documentation in the XML-based class reference format as described in Godot’s class reference primer. From there it’s easy to ETL into your final format. For a documentation site, you could use XSLT/Python/Godot to turn it into JSON, and then use that, for example, in a data-driven, searchable Nuxt Content site.
Hugo-Dz created Super Godot Galaxy: https://github.com/Hugo-Dz/super-godot-galaxy, which he announced in this Reddit post. It uses the 3D Starter Kit from Kenney and shows how to achieve the effect of applying gravity toward the center of a small spherical planet.
A new version of the Inventory System is available. This version requires Godot Engine 4.3 and includes many refinements. New Drag and Drop system The Drag-and-Drop component has received a major overhaul. The previous system was quite complex and the separation of the classes that implemented the click-and-drag and click-and-release approaches had so much overlap …
A new version of the Inventory System is available with more multiplayer-related features. The Multiplayer Interaction Demo can now run in multiple modes, through two separate implementations of the Character scene: The simple character scene leverages the MultiplayerSynchronizer and can either let the client have authority and move the character, or have the client send …
Ever had the problem where you’re firing a bullet or some kind of projectile at high speeds, and it just goes right through the collision object, instead of hitting it? Here’s a weapon that fires a bullet at random velocities, to demonstrate the issue: The bullets impact the character in various places, rather than at …
Generating documentation for GDScript
Any sufficiently large code base needs documentation. Documentation tends to come in all sorts of shapes and sizes. Among them are high-level architecture and design docs, class and method interface documentation, and inline comments to explain optimized or complex algorithms so the reader doesn’t have to parse the logic in their head (often, this is future you reading your own code six months later).
Following best practices and clean coding conventions go a long way in making code more understandable. Both also help minimize the need for documentation (that is a Good Thing™). Well-written code reads like poetry, bridging the gap between mathematical algorithms and plain, human-readable instructions. In most situations, documentation should focus on the “why” instead of the “how.” Code already tells you what it does, the documentation helps to understand better why it works that way.
Code exists to solve problems. After all, software developers aren’t just writers or typists, they’re problem solvers first and foremost. The problem that code eventually solves usually also has documentation and it comes in just as many formats: PRDs, GDDs, User Stories, Issue tickets, etc. Whatever the format is, refining the problem statement can also have a huge impact on clarity; often, half of the solution is understanding the problem better. The requirements format mostly depends on which industry you’re in, which development methodology is used, and how big the company is. The larger the company, the more difficult it is to track requirements, work in progress, and roadmaps. Some companies build out entire Product Management organizations, and even larger ones employ Program Management to coordinate Product Management and its interdependency and sequencing challenges — all of which come with overhead. It takes a lot of time and communication to achieve cohesion and alignment. It takes even more overhead if you want to measure how things are going using KPIs and OKRs, but I digress. Hence: If you want to go fast, go alone; if you want to go far, go together.
Code usually doesn’t exist in isolation, either. It has to fit into an ecosystem of libraries, modules, packages, addons, plugins, or extensions, which, when combined, solve larger, complex problems and can provide compelling solutions. Each unit of code has interfaces for what it needs and provides.
So far the takeaway should be that documentation is a necessary evil. If code is the solution, documentation is overhead. Any time spent on creating documentation is not spent on solving a problem. It’s also easily outdated, thus inaccurate, misleading, and can result in wasted time and effort. Ask anyone in a larger organization that uses tools like Confluence and JIRA. It’s not necessarily the tools’ fault. Atlassian makes fine solutions. The problem is that, the farther documentation lives from the code base, the less accurate it is, and the faster the two diverge. In my experience, the unspoken rule in more than one company was that “Confluence is where documentation goes to die.”
Including documentation as part of a code base is not new. Javadoc, JSDoc, PHPDoc, RDoc, etc have existed for decades. In many cases, the “insert language here”-doc formats are used for API documentation. While that’s helpful, it’s often not what developers are looking for. If I want to learn, let’s say, Vue.js, I don’t start with the API docs. I look for the guide instead, because it explains the concepts, use cases, best practices, and other reasons why code is written the way it is. Both types of documentation have their place, of course. The API is about cold, hard facts, while a guide provides more philosophical answers. Code and API docs tell you the what and the how. Guides explain the why.
Frankly, when I seek documentation, I’m typically more interested in approaches and the lens through which a problem is observed, decomposed, and solved. I expect my IDE to provide the API documentation as part of its syntax completion and static analysis tooling.
And I have to say, that’s something I enjoy about using GDScript: The GDScript documentation comments syntax supports everything I’d expect from a documentation system. The ability to reference code through BBCode along with the built-in documentation browsing capabilities in the Godot editor makes it incredibly convenient to look up information quickly. The only thing on my wishlist is the ability to use the “Open Documentation” button in the property inspector to open custom scripts. Unfortunately, it only opens the built-in class the script is based on. I suspect this is related to the limitation of the
Object.get_class()
method.Sometimes, though, it’s nice to be able to generate external documentation. JavaScript has the JSDoc generator, for example.
For Godot 3 (and Godot 4, it seems), GDQuest’s gdscript-docs-maker is a tool to generate markdown-based documentation from GDScripts. It uses the more or less undocumented
GDScriptLanguageProtocol
singleton to extract the definitions, which are converted to Markdown with the help of a Python script. However, accessing the GDScriptLanguageProtocol is somewhat buggy, per GitHub issue #86132 (Cannot access theGDScriptLanguageProtocol
in GDScript).Engine.get_singleton('GDScriptLanguageProtocol')
broke in 3.4 in 2021 and has been kicked down the road since: GDScriptLanguageProtocol singleton not properly recognized as identifier #52162.The eh_DocsExporter is based on GDQuest’s gdscript-docs-maker but works entirely within Godot (3), which means no more dependencies on Docker or Python.
More recently, Godot got a built-in docs exporter, but it’s not as easy to use:
--gdscript-docs
tool failing when autoloads are used in the project.I couldn’t make it work until I noticed this comment in issue #84579: The TL;DR is that rather than running “
godot --doctool docs/ --gdscript-docs addons/my_addon
“, the gdscript-docs argument should be specified inres://
format, due to a potentially difficult-to-fix bug.So to generate the documentation for an entire project (and saving it in docs/classes) is:
That will generate documentation in the XML-based class reference format as described in Godot’s class reference primer. From there it’s easy to ETL into your final format. For a documentation site, you could use XSLT/Python/Godot to turn it into JSON, and then use that, for example, in a data-driven, searchable Nuxt Content site.
Related Posts
Super Godot Galaxy Concept
Hugo-Dz created Super Godot Galaxy: https://github.com/Hugo-Dz/super-godot-galaxy, which he announced in this Reddit post. It uses the 3D Starter Kit from Kenney and shows how to achieve the effect of applying gravity toward the center of a small spherical planet.
Inventory System v1.16 available
A new version of the Inventory System is available. This version requires Godot Engine 4.3 and includes many refinements. New Drag and Drop system The Drag-and-Drop component has received a major overhaul. The previous system was quite complex and the separation of the classes that implemented the click-and-drag and click-and-release approaches had so much overlap …
Inventory System v1.14 available
A new version of the Inventory System is available with more multiplayer-related features. The Multiplayer Interaction Demo can now run in multiple modes, through two separate implementations of the Character scene: The simple character scene leverages the MultiplayerSynchronizer and can either let the client have authority and move the character, or have the client send …
Projectiles going through collision objects
Ever had the problem where you’re firing a bullet or some kind of projectile at high speeds, and it just goes right through the collision object, instead of hitting it? Here’s a weapon that fires a bullet at random velocities, to demonstrate the issue: The bullets impact the character in various places, rather than at …