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.

Wicklog 32: Refactors, race mode (again), and Loomapalooza


Wicklog 33: Officially hitting 1.0