Godot 3.5 => 4.0 migration notes
I recently finished converting Lancer Tactics to Godot 4.0, and thought it might be useful to share my notes on the hitches I ran into along the way. (I'm on Godot 4.0 beta 10)
-
Automatic conversion tool: it's a lot more helpful that I thought it would be, though is a little overzealous. The biggest class of changes I had to manually reject were substitutions for the word "on" and "off" for "checked" and "unchecked", even inside of strings and comments.
-
Hotkeys: Some unnecessary and annoying changes. Hopefully will be fixed?
- cmd+shift+O does different things in different contexts; if you have text in focus, it does a weird multicursor thing instead of quick-opening a scene.
- can no longer tab between editing properties in the inspector. (??? why ???)
- if you press enter to confirm an edited property in the inspector, it will start renaming something in your scene tree -- so if you hit cmd+S like a caffeinated squirrel, congrats you've just deleted a name.
-
New tween system: it's just better in every way. Chaining calls is sublime. You'll have to manually convert them though. ("is_active" is now "is_running")
-
GDScript 2.0: it's so much more picky about declaring and respecting variable types, which is good, but will throw a lot of errors at first for a new codebase and the compiler won't always guide you to the true problems.
- I found myself frequently chasing ghosts; one script says another class is invalid, you go to see what the error there is and there's just nothing. This usually ended up being a problem with my global autoloaded script AND needing to reload the project.
- This forced me to start paying attention to my console warnings and cleaning out the noise like "unused parameter". This is important because sometimes a warning will actually be important, like appending something to an array failing because it's now the wrong type.
-
Control nodes and UI: I had to redo almost everything.
- Fonts use a new system, so be prepared to remake them all as LabelSettings
- Labels lose all of their text alignment settings, and "percent_visible" has been changed to "visible_ratio" which broke a few of my animations. I also had to change "visible characters behavior" to "characters after shaping" to match 3.5 behavior in those animations.
- Renaming things is dangerous -- I renamed a LabelSettings and it hollowed out all the control nodes that used it. Reopening them in the editor and resaving them fixed some of them, others I had to reject the weird losses of chunks of text in git.
- Speaking of git, Control nodes are so so noisy. On saves, they frequently make changes to layout_mode, uids, and other junk that make no visual difference but generate a lot of noise in git.
-
Tilesets, Tilemaps, Terrain: It's a mixed bag. The tools and interface are MUCH improved, there are already video tutorials for the new stuff, but it has nosedived in stability for me.
- Setting up terrain makes a lot of sense and I saw more intelligent behavior while placing tiles. However, it's a LOT slower -- it's no longer possible to have it automatically autotile more than a few dozen tiles during runtime. I had to write my own micro autotiler to get any kind of acceptable performance.
- I started seeing crashes every one to two minutes while editing a tileset after adding custom data layers. I had to rush in, do one or two things, and save before my progress was lost. I haven't nailed down an exact repro trigger so have been unable to file an issue on github.
- Adding animated tiles is now a breeze, 5/5.
- The editor sometimes hiccups and clears out all terrain and custom layer data from tilesets, even when I'm editing something mostly unrelated. Terrifying. I need to keep a very close eye on my git changes to always revert them.
-
Misc notes
- .NET version: Make sure to install 6.0, not 7.0!
- Project settings: I had to disable "Allow hiDPI" on my retina monitor to make the game show up at a normal size by default again.
- Camera zoom has been inverted; to zoom in 4x it's now (4,4), not (.25,.25)
- all my input map controls were converted to "physical", had to rebind
- Vector2.angle_to_target got flipped, gotta do it backwards now
- could not enumerate over an external enum
- only way afaik to convert ints to strings now is str(x); stuff like x as String don't work
- @ tools work slightly differently, and risk crashing the editor on settings if there's even a chance of an infinite set-loop
-
"
!= null" now evaluates to false! aka freed objects are harder to distinguish from null.