Skip to content

Instantly share code, notes, and snippets.

@rsubtil
Last active August 29, 2021 12:15
Show Gist options
  • Save rsubtil/01067153db5608d48773719fa63ab2b8 to your computer and use it in GitHub Desktop.
Save rsubtil/01067153db5608d48773719fa63ab2b8 to your computer and use it in GitHub Desktop.
GSOC 2021 Final Report


  • Project: Implement a DAP backend for debugging Godot projects with external editors
  • Student: Ricardo Subtil (@ev1lbl0w)
  • Mentors: Fabio Alessandrelli (@faless) & Joan Fons (@jfons)
  • PRs:

Project description

This project aims to add support for the Debug Adapter Protocol (DAP) for Godot. The DAP is a protocol specified by Microsoft to allow for debugging projects from external text editors/IDEs in a platform-agnostic way. With this, people will be able to use any DAP-compliant tool for working with Godot, without the need for special plugins and/or configs.

What's implemented

Most of the basic funcionality expected in a debugging environment is implemented, so it's already possible to reliably debug Godot projects with external tools:

  • Launch or attach to a debuggee, as well as terminate it.
  • Pause and continue.
  • Stepping over code lines and in function calls.
  • Setting breakpoints.
  • Exceptions from bad code, such as syntax or runtime errors.
  • Stacktrace and scope information, along with variable values.

Also, some more advanced functionality is supported:

  • Detailed variable description from Godot's Variants
  • Sync breakpoints in-between Godot and the external tool
  • Expose Godot's internal communication protocol through DAP
  • Debug from native platforms (Android and/or Web)

How to use

Basic usage

The DAP is a platform-agnostic protocol. All that's needed is a compatible text editor/IDE to use it.

The backend is implemented on the Godot editor, so an editor instance must be open. After that, setup your tool to connect to the local DAP port, which by default is 6006 (it can be changed in Godot's settings).

For VSCode, here's a sample config you can use (needs godot-vscode-plugin installed, otherwise it complains about "type": "godot"):

{
	"version": "0.2.0",
	"configurations": [
		{
			"name": "Launch (DAP)",
			"type": "godot",
			"request": "launch",
			"project": "${workspaceFolder}",
			"port": 6007,
			"debugServer": 6006,
			"address": "local://127.0.0.1"
		}
	]
}

Expose Godot's custom communication

To enable this feature, a client must supply in a launch request the following config as well:

interface LaunchRequest extends Request {
 	...

 	/**
 	 * If Godot's custom communication should be forwarded. Defaults to false.
 	 * Note: some events aren't forwarded, as they're already handled by other DAP requests/events.
 	 */
 	godot/custom_data?: boolean;
 }

Any message payload is forwarded as is to the DAP tool in a new event:

interface GodotCustomDataEvent extends Event {
	event: 'godot/custom_data'

	body: {
		/**
		 * The message string.
		 */
		message: string;

		/**
		 * Any extra data that may exist. This array exists even if there's no extra data (in which case is just an empty array)
		 */
		data: any[];
	}
}

The client can also send internal messages as well. A new request was made for it:

interface GodotPutMsg extends Request {
	command: 'godot/put_msg'

	arguments: GodotPutMsgArguments;
}
interface GodotPutMsgArguments {
	/**
	 * Message to pass to the debugee.
	 */
	message: string;

	/**
	 * Extra data needed. Supply an empty array even if there's none.
	 */
	data: any[];
}

The response is just an empty ACK body:

 interface GodotPutMsgResponse extends Response {
}

Debug native platforms

Godot supports debugging native platforms from DAP as well. Ensure the intended platform is properly configured before. After that, use the following configurations during a launch request:

interface LaunchRequest extends Request {
	...

	/**
	 * Platform for debugging. Defaults to 'host'
	 * Values:
	 * 'host': Same platform the editor is running under (Windows/macOS/Linux)
	 * 'android': Android devices
	 * 'web': Web platform
	 */
	platform?: 'host' | 'android' | 'web';

	/**
	 * Device index to use if there is more than one. Only used for Android platforms. Defaults to 0.
	 */
	device?: number;
}

Detailed list of implemented features

Here's a more thorough list of what has been implemented, along with any existing caveats or in-depth explanations.

During GSoC and also at the time of writing, the specification followed was up to version 1.48.x.

  • Events
    • breakpoint
    • continued
    • exited
    • initialized
    • output
    • process
    • stopped
    • terminated
  • Requests
    • attach (note this only works when launching the project under the Godot editor; the DAP cannot connect to an instance launched from outside the editor, due to how Godot's debugging protocol works)
    • breakpointLocations
    • configurationDone
    • continue
    • disconnect
    • evaluate (only for mouse hovers)
    • initialize
    • launch
    • next
    • pause
    • restart
    • scopes
    • setBreakpoints
    • stackTrace
    • stepIn
    • terminate
    • threads (DAP enforces this, but Godot doesn't support debugging threads, so any thread information is hardcoded to a single main one)
    • variables
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment