kiriri / gd2cs.py

Regex based Python script that converts arbitrary gdscript code to C#
GNU General Public License v3.0
87 stars 12 forks source link

Upgraded the godot ui plugin to the latest stable v4.1 #7

Closed SirTobyB closed 1 year ago

SirTobyB commented 1 year ago

I'm new to godot, so i hope, i found all places, that needed to be changed. I've tested it successfully with Godot v4.1.stable.mono.official [970459615], but only with a small GDScript file.

@kiriri Nice project by the way! I'm hoping, you're improving it further 😄

SirTobyB commented 1 year ago

Should solve #5

kiriri commented 1 year ago

Thank you for your work! I personally don't really use Godot anymore, so further development from my side is unlikely. I've created a new godot4 branch, because the actual code conversion needs to change too. Godot 4 has a new type system, among other things. I'm not sure how useful the godot 4 version of this plugin will be without some tweaks to the python regex.

SirTobyB commented 1 year ago

Thank you for your work! I personally don't really use Godot anymore, so further development from my side is unlikely. I've created a new godot4 branch, because the actual code conversion needs to change too. Godot 4 has a new type system, among other things. I'm not sure how useful the godot 4 version of this plugin will be without some tweaks to the python regex.

Thanks for your feedback and the merge to a new godot4 branch.

Ah, i didn't know about the changes of the new type system. Maybe i will take the time to dig into it. Can you help me with some information, where can i find infos about the new type system and the relevant changes from godot 3 to godot 4? Where would you begin to change the (huge) python script? I'm a bit lost here. 😆

kiriri commented 1 year ago

Ooh boy, I forgot how complex this regex was :D.

So beginning at line 124, a lot of regex matchers are defined. These get reused in a lot of different replace operations later on, and are a good spot to start looking. If something doesn't translate from gdscript to c#, then it's likely not matched, and it's likely that one of these matchers doesn't work anymore.

At line 190, a c# code chunk that gets prefixed to the output file is defined. Very simple. Not sure if anything changed here.

At line 230, constant variable replacements are defined. I'm not sure how complete this is, and whether any of this changed for Godot4.

At line 267+ the true meat of the translation happens. The replacements object defines a nested application of regex match and regex replace operations. The first (and only) object inside the replacements array just matches the entire gdscript code. That's what [\w\W]* means. Then all of its children will get processed sequentially, based on the entirety of the matched string from the parent (In this case everything). Keep in mind that each child works on the processed string the previous child returned, and the first child works on the matched string of the parent. So order matters.

The following code is just more of the same. Eg. you might want to match parts of the code, say a function body. Then match even more, like a variable definition (in the function body). Then replace all those sections of the code that were found with the c# equivalent.

This hierarchical approach makes things a lot simpler to read. But I can see how the remaining regex is terrifyingly complex to read still. I used to use an online regex validator to help me check my regex syntax, but I unfortunately no longer remember which one it was. Do note however that not all regex parsers are made the same, and the python regex used in this project is the most powerful one I know of. So just because a regex checker says something doesn't work, doesn't mean it really doesn't.

Anyways, most replacement objects are paired with a short comment describing what they do. And none of the truly complicated nested operations will need changes afaik.

Some missing replacements I can think of of the top of my head are:

To debug a specific replacement operation, you can add something like this

"replacement_f": lambda v: print(v) or v

to the replacement object. That operation won't do anything but print the currently matched string to the console. There are commented out parts of the code that contain this if you're not quite sure where it should go. You can copy the resulting string into your regex syntax checker to get an accurate idea of what your new or modified regex replacement will do, in this specific context.

And that's it. It's complicated. As someone else pointed out when I started this project, regex isn't very suitable for this task. But it somehow works :) . And it doesn't have to work perfectly. Just well enough to save people's time as compared to doing these things manually. So if you or someone else can modify parts of the regex to work on gdscript4, and maybe learn or improve your own regex skills along the way, that would be wonderful. But if it's too complex and/or time intensive, don't sweat it. Based on your small test it still seems to work somewhat, and that may be good enough ;)

SirTobyB commented 1 year ago

Thank you for your time and the detailed answer. I made an issue for upgrading the conversion to godot 4. Maybe I'll take the time to do it, but I can't promise.

The current version works with Godot 4 and in my opinion it's still a help but i think you have to change more manually after the conversion then with Godot 3.