I just have a question, is GDscript compiled when you export your game? I know that it is interpreted in the editor but what about when you export a project? I have this question because I'm concerned about performance and privacy. If any GDscript files are just shipped in the package alongside its interpreter than that prevents the files from being private and can impact performance. Another thing is that with interpreted languages, the interpreter for that language needs to be included within the game package in order to run without the user needing to do anything, while with compiled languages the code is just converted to the raw binary for the target os/hardware. the fact that the interpreter must be included can also make the game bloated. I just wanna know how GDscript works. So if you know please explain to me.
Is GDscript compiled when exported?
- Edited
i'm responding to shove your thread to the top. i hear this question a lot, and it's not in the FAQ:
https://docs.godotengine.org/en/stable/about/faq.html#doc-faq-what-is-gdscript
the best answer i've gotten goes something along the lines of "GDscript is C++ under the hood". unfortunately, i dropped out, so you tell me what that means. i've only an artist's abstract idea of what that might mean.
GOOD SAMARITAN EDIT:
you sound worried your export might be bloated. i found this while looking for answers, it could help:
https://docs.godotengine.org/en/stable/contributing/development/compiling/optimizing_for_size.html#doc-optimizing-for-size
- Edited
packrat Thank you.
From what I understand, while the engine itself is compiled, your GDScript is interpreted. The page that you found, packrat, seems to be about rebuilding the engine, which isn't normally part of the export process for an individual game.
This is one of the reasons why Godot supports custom modules in C++, because this allows compiled sections which can be faster.
I'm sure that Godot will be a lot larger than a game written wholly "from scratch", using just low-level libraries and compiled down to the specific machine. But, it's worth thinking about whether that matters in context.
It vaguely looks to me like Godot adds about 20 MB in HTML5 or Android exports, at least. That's a lot compared to game in The Old Days, but for me it's a reasonable tradeoff for all the ease it provides. 20 MB for cross-platform audio alone is probably worth it, and this also gets you inputs, fullscreen options, and so on.
There's a lot of stuff about speed, optimizations, and benchmarking, but I tend to subscribe to "premature optimization is the root of all evil." Unless you have already made multiple games and know that you're going to need to do things that require every bit of the computer's native speed, you'll probably be better off starting with GDScript, optimizing if it starts to get slow, and finally moving specific logic to C++ if you find it's really causing you problems.
In summary - GDScript is interpreted and this does add "bloat", but computers are big and fast now, so don't assume this will definitely be a huge problem.
Of course, if you specifically want to program in constrained environments, there are also communities for things like games on the Raspberry Pi, Arduino, or the virtual PICO-8 console, which can give more of the older experience of having to track all your memory and count your bytes.
I hope this is helpful!
Hi @PizzaHutsAlat, so with Godot 4 what happens is that when you export your game, the GDScript .gd
files are compiled into what is called bytecode, and these will be in the exported game as .gdc
files. These files are faster to load because the engine does not need to re-parse the text-based code any longer and instead runs the bytecode operations. This is very similar to languages like Java.
In Godot 3.x, your GDScript code was compiled from the source .gd
into a bytecode format with the file extension .gdc
(short for GDScript Compiled). This byte code was then interpreted. The byte code avoids the tokenization step, and excludes comments.
In Godot 4.x, the .gdc
format has been temporarily removed. Your GDScript files are exported exactly as-is with no compile step, and interpreted from scratch at runtime including tokenization and discarding comments. The plan is to bring back this feature in the future.
aaronfranke In Godot 4.x, the .gdc format has been temporarily removed.
Why was it removed?
- Edited
If you're worried about code privacy, I'm pretty sure IL doesn't do much, at least with C#. C#'s IL was designed to be easy to de-compile back to C#, and this may be the same with GDScript. For code privacy, you can encrypt the PCK file when exporting with (I think) AES-256-CBC but I may be wrong on the algorithm. You just need to generate 256 random bits, preferably securely with a cryptographically secure random number generator. If you have access to DevTools in your browser, this snippet of JS can make a secure AES-256 key. Simply open a new tab page, open DevTools (usually ctrl+shift+i
) Click on console
, and copy-paste this in:
(async function (crypto) {
const key = await crypto.subtle.generateKey(
{
name: "AES-CBC",
length: 256,
},
true,
["encrypt", "decrypt"],
);
const exported = await crypto.subtle.exportKey("raw", key);
const exportedHex = Array.from(new Uint8Array(exported))
.map((byte) => byte.toString(16).padStart(2, "0"))
.join("");
console.log(`AES key generated using ${key.algorithm.name}`);
console.log(exportedHex);
navigator.clipboard
.writeText(exportedHex)
.then(() => console.log("Key written to clipboard."))
.catch(async () => {
console.log("Couldn't write to clipboard.");
if (
"canShare" in navigator &&
!navigator.canShare({
text: exportedHex,
})
) {
// Usually this has a copy button.
await navigator.share({
text: exportedHex,
});
return;
}
console.log("Web Share API unavailable. You must copy it yourself.");
});
})(
window.crypto ||
(() => {
if (!window.isSecureContext)
throw new Error("Not secure context. Cannot use Web Crypto API.");
throw new Error("Your browser doesn't support the Web Crypto API");
})(),
);
Technically, Godot only requires 256 random bits. While the above method does generate a real AES key, it is just 256 random bits. So here's a potentially easier method and probably faster:
(function (crypto) {
const key = Array.from(crypto.getRandomValues(new Uint8Array(32)))
.map((byte) => byte.toString(16).padStart(2, "0"))
.join("");
console.log("256 random bits generated:", key);
navigator.clipboard
.writeText(key)
.then(() => console.log("Successfully copied key to clipboard."))
.catch(async () => {
console.error("Failed to copy key.");
if ("canShare" in navigator && navigator.canShare({ text: key }))
await navigator.share({ text: key });
else console.log("Web Share API unavailable. You must copy it yourself.");
});
})(
window.crypto || /* this is premature optimization, yes. It is the root of all evil. Doing it this way on V8 (chromium/node), it is ever so slightly faster than checking in-function. */
(() => {
if (!window.isSecureContext)
throw new Error("Not secure context. Cannot use Web Crypto API.");
throw new Error("Your browser doesn't support the Web Crypto API.");
}),
);
While encrypting the PCK will have the key within the binary itself (so the engine can decrypt it) being in a compiled binary means that it isn't in a simple text file and requires at least some analysis on the binary to find the key. I don't know but maybe Godot obfuscates the key somehow, but you'd have to do your own research on how this actually works. By encrypting the PCK, you protect your game assets from being easily extracted, including your GDScript source code.