Skip to content

Instantly share code, notes, and snippets.

@KnIfER
Last active March 10, 2026 13:01
Show Gist options
  • Select an option

  • Save KnIfER/53cb82058dcb3ed7035315b2e97c156b to your computer and use it in GitHub Desktop.

Select an option

Save KnIfER/53cb82058dcb3ed7035315b2e97c156b to your computer and use it in GitHub Desktop.
Godot_Launcher.ahk - Godot Automatic version selector
#SingleInstance Off
#NoTrayIcon
; Stores shortcuts to various Godot engines
global godotFolder := "C:\Softwares\GODOTS\"
; Pre-defined priority list (you can customize this order)
global priorityList := ["godot_voxel_4.1_x86_64.exe"
,"Godot_v4.4-stable_mono_win64.exe"
,"Godot_v4.3-stable_mono_win64.exe"
,"Godot_v4.2-stable_win64.exe"
,"Godot_v4.1.3-stable_win64_console.exe"
,"Godot_v4.0.4-stable_win64.exe"
,"Godot_v4.0.4-stable_mono_win64.exe"
,"Godot_v3.5.3-stable_win64.exe"]
projectPath := A_Args[1]
if (projectPath = "") {
MsgBox, Please provide a project path as an argument.
ExitApp
}
; 1. Check if the file is named project.godot
SplitPath, projectPath, fileName
if (fileName != "project.godot") {
MsgBox, The specified file is not project.godot
ExitApp
}
; 2. Check if parent directory\.godot\last_runtime.txt exists
SplitPath, projectPath, , projectDir
godotRuntimeFile := projectDir . "\.godot\last_runtime.txt"
godotPath := ""
if FileExist(godotRuntimeFile) {
FileRead, godotPath, %godotRuntimeFile%
godotPath := Trim(godotPath)
}
; 3. Check if godotPath is correct
if !FileExist(godotPath) {
; Read project.godot file
FileRead, projectContent, %projectPath%
; Extract config/features line and get version and mono info
version := "3.5"
isMono := false
Loop, Parse, projectContent, `n, `r
{
if InStr(A_LoopField, "config/features") {
; Look for version number like 3.5, 4.2 etc.
if RegExMatch(A_LoopField, "(\d+\.\d+)", versionMatch)
version := versionMatch1
; Check if it's a mono project
if InStr(A_LoopField, "c#") || InStr(A_LoopField, "mono")
isMono := true
break
}
}
if (version = "") {
MsgBox, Could not determine Godot version from project.godot
ExitApp
}
; Search for Godot shortcuts in C:\Softwares\GODOTS
godotPath := FindGodotExecutable(version, isMono)
if (!godotPath) {
version := version " " (isMono ? "(Mono)" : "")
MsgBox, Could not find matching Godot executable for version %version%
ExitApp
}
}
; MsgBox 4, Confirm, Found Godot: %godotPath% `n Open?
; IfMsgBox Yes
Run, "%godotPath%" "%projectPath%"
ExitApp
FindGodotExecutable(version, isMono) {
; Get all shortcuts in the folder
matchingPaths := ""
engines := []
Loop, %godotFolder%*.lnk, , 0
{
; Get shortcut target
; FileGetShortcut, %A_LoopFileFullPath%, target
; ; Extract version from shortcut name or target
; SplitPath, target, targetName
SplitPath, A_LoopFileName, shortcutName
if InStr(shortcutName, "odot") && InStr(shortcutName, version) {
;engines.Push(shortcutName)
; Calculate priority score (lower number = higher priority)
priorityScore := 999
for index, priorityVersion in priorityList {
if InStr(shortcutName, priorityVersion) {
priorityScore := index
break
}
}
eng := {}
eng.path := shortcutName
eng.score := priorityScore
engines.Push(eng)
}
}
; Sort candidates by score (lower is better)
; Bubble sort for simplicity
for i, eng in engines {
j := i+1
while(j<=engines.MaxIndex()) {
if (engines[j].score < engines[i].score) {
temp := engines[i]
engines[i] := engines[j]
engines[j] := temp
}
j++
}
}
for i, eng in engines {
shortcutName := eng.path
; Check mono requirement
if isMono {
if InStr(shortcutName, "mono")
return godotFolder . shortcutName
} else {
if !InStr(shortcutName, "mono")
return godotFolder . shortcutName
}
; Store as fallback
matchingPaths := godotFolder . shortcutName
}
; Return the last match if no perfect match found
return matchingPaths
}
@KnIfER
Copy link
Author

KnIfER commented Mar 10, 2026

20260310_205342_Concat.0.mp4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment