Skip to content

Running games from GMEdit

Vadym Diachenko edited this page Apr 4, 2024 · 7 revisions

UPDATE 2: For GameMaker 2023 and newer, you should be using Constructor plugin instead of builder.

UPDATE: For GameMaker Studio 2, you can run the compiler from external software. Here's a plugin for GMEdit that allows you to compile and run your game without the IDE: https://github.com/YAL-GMEdit/builder/

GameMaker: Studio does not allow external software to call its compiler directly, but you can have a small AutoIt script that hits F5 ("run game" keyboard shortcut) in the associated GM window when you hit F5 in GMEdit:

$bound = false
$suffix = " - GMEdit"
$suffixLen = stringLen($suffix)
const $debug = false
hotKeySet("{PAUSE}", "doExit")
autoItSetOption("SendKeyDelay", 25)
autoItSetOption("SendKeyDownDelay", 25)
while 1 ; bind/unbind the hotkey as we switch to/from GMEdit
    $title = winGetTitle("[ACTIVE]")
    $newBound = (stringLen($title) > $suffixLen and stringRight($title, $suffixLen) == $suffix)
    if (not $bound and $newBound) then
        hotKeySet("{F5}", "onF5")
        hotKeySet("{F6}", "onF6")
    elseif ($bound and not $newBound) then
        hotKeySet("{F5}")
        hotKeySet("{F6}")
    endIf
    $bound = $newBound
    sleep(250)
wend
func doExit()
	Exit(0)
endfunc
func findGMS2($rxBase)
	local $rx = "^" & $rxBase & " - GameMaker"
	if ($debug) then consoleWrite($rx & @CRLF)
	return winGetHandle("[REGEXPTITLE:" & $rx & "]")
endfunc
func findGMS1($rxBase)
	local $rx = "^" & $rxBase _
		& "\.project\.gmx" _
		& "\*?" _ ; * if modified (opt.)
		& ".+" _ ; ... - Super Enterprise Edition
		& "\(v[\d.]+\)" _ ; (v1.4.1804)
		& "\s*$"
	if ($debug) then consoleWrite($rx & @CRLF)
	return winGetHandle("[REGEXPTITLE:" & $rx & "]")
endfunc
func sendToGM($key)
	local $orig = winGetHandle("[ACTIVE]")
    local $title = winGetTitle("[ACTIVE]")
    local $titleLen = stringLen($title)

    ; check that it's still GMEdit just to be really sure:
    local $newBound = ($titleLen > $suffixLen And stringRight($title, $suffixLen) == $suffix)
    if (not $newBound) then exit

	local $name = stringLeft($title, $titleLen - $suffixLen)
	local $hwnd = findGMS1($name)
	local $gms2 = false
	if ($hwnd == hwnd(0)) then
		$gms2 = true
		$hwnd = findGMS2($name)
	endif
	if ($hwnd == hwnd(0)) then exit
	if ($debug) then consoleWrite("name='" & $name _
		& "' hwnd=" & $hwnd & @CRLF)

	;Send("{F5}")
	if ($gms2) then
		winActivate($hwnd)
		hotKeySet("{F5}")
		hotKeySet("{F6}")
		$bound = false
		send($key)
		if ($debug) then consoleWrite("keys='" & $key & "'" & @CRLF)
	else
		$out = controlSend($hwnd, "", "", $key)
		if ($debug) then consoleWrite("title='" & WinGetTitle($hwnd) _
			& "' out=" & $out _
			& " error=" & @error _
			& @CRLF)
	endif
endfunc
func onF5()
	sendToGM("{F5}")
endfunc
func onF6()
	sendToGM("{F6}")
endfunc

Better workflow:

Syntax extensions:

  • `vals: $v1 $v2` (template strings)
  • #args (pre-2.3 named arguments)
  • ??= (for pre-GM2022 optional arguments)
  • ?? ?. ?[ (pre-GM2022 null-conditional operators)
  • #lambda (pre-2.3 function literals)
  • => (2.3+ function shorthands)
  • #import (namespaces and aliases)
  • v:Type (local variable types)
  • #mfunc (macros with arguments)
  • #gmcr (coroutines)

Customization:

User-created:

Other:

Clone this wiki locally