Hi, right now I’ve become interested in chess engines and I’m trying to make one in Godot. Unfortunately, my code is messy to the point of unreadability. I came to Godot from Python, so I’m wondering if there’s anyway to link GDScript files like Python modules? For example, I have a lot of functions that just help with legal move generation-I want to know if there’s anyway to bundle them into a Move.gd file and then call something like
Move.IsCheckmate(position)
instead of having to call just
IsCheckmate(position)
, just so that my main programming file isn’t a bloated mess of function definitions.
I’m sorry if I phrased this a bit oddly, but hopefully it’s understandable
You can also make an Autoload and keep your utility functions there.
If you set up a Move autoload, that has a func IsCheckmate(position), you can then call it from anywhere Move.IsCheckmate(position), similarly to how @gentlemanhal mentioned with the static func.
Is there any reason why it would be better than just having it saved as a class_name? With the class_name you don’t need to remember about preloading it in every script you want to use it, seems more convenient to me.
class_name makes a global identifier, this could collide with other global identifiers.
If you are creating an addon you may want to avoid global identifiers. For example: you are making a in-editor music player, you shouldn’t use the class_name Player as it’s very common for game creators (your users) to have a class name Player of their own. You could tack on extra words or prefixes, or use preload and guarantee you aren’t polluting the global namespace.
I extended my first script as an Object just two days ago while I have been investigating procedural generation.
class_name CaveGenerator
extends Object
And I used it like this:
var CAVE_GENERATOR: CaveGenerator
Then in _ready():
CAVE_GENERATOR = CaveGenerator.new()
Then everything in cave generator was open to me. ie later in that script I use it to generate the grid data for a tilemap chunk.
var new_grid: PackedByteArray = CAVE_GENERATOR.generate_cave(grid_origin, grid_size)
I thought this was amazing! I loved it and wish I’d known about this for my last game. I am still excited about what can be done with this. I would guess for a chess engine this would be great for putting lots of that functionality that you need and yet keep it in a standalone modular kind of fashion, and out of the way as well. (I was also amazed at how efficient using packed byte arrays were too).
I get the point about polluting the namespace though, and it was interesting to see you can still do this but without the class name and just loading the script. I will definitely be trying that out. In my last game I had so many nodes that did nothing really except hold a script with some functions. Extending objects is amazing! And I feel fine about preloading it into wherever I need it too. (It also makes testing feel easier too).
With the preload without using the class_name I think you won’t get any autocompletion in the function and variable definitions, isn’t that correct? This means you can’t keep your code properly type-safe this way.
And the argument about not polluting the global namespace seems to make sense only in case of plugins. If I’m working on my project alone (or even with a team, shouldn’t matter), I don’t see a reason to hide classes if it means additional inconvenience of having to preload it every time and have no autocomplition.
I very much prefer using the class_name + a static func for this usecase mentioned here, but it’s good to know about the advantages of preload if I ever need it.
You could achieve exactly the same with a class_name + static func, but much more conveniently, without having to declare anything in the calling script
Any reason you wouldn’t want to do that instead?
Ah, you preload it as a class definition, not just as an object, I get it now. Thanks for clarifying.
Still it seems less convenient, but not as bad as I thought initially
I have never used the static function before and I am not sure I understand it fully yet. It seems it acts like a singleton. I will definitely be testing this shortly, but for now if I declare a class and use a static function I am amazed that it works without any declaration or instantiation. That is going to be extremely useful.
However I am not sure about the limitation that static functions cannot access anything of the instance. I don’t know how much of an issue that is as I suppose you can just pass them as args anyway (which I have been trying to do with my public functions anyway as I have run into trouble with assuming scripts have certain properties set.)
However, right now I think class_name and static functions are the way to go (except in the case of plugins to keep namespaces clear of course). In fact I can really see use cases (that I am going to try out this morning) where this is going to really help clean up lots of my code even more.
Thank you. I feel like I have learned something really important! (Such huge gaps in my knowledge).
As for the chess program, I think this is the answer for @steammake3 question about python like modules. You need utility scripts with class names and static functions.