AGK is a Structured Programming language, so you should stick to the best practices guidelines for this style of programming. Which is to say have a top-down approach, building a 'pyramid' of functions/procedures where the deeper down you go from the top, you get more granular and specific in your code. Preferably with no lateral horizontal dependencies (messy), only vertical top to bottom dependencies (clean-ish).
This will however only put you back to the main loop (usually some kind of start menu or similar) from where you first started to dig down to other procedures. You can exit the main loop, but this will quit the program. This is due to how - as the name implies - Structural Programming relies upon control structures (various conditional loops, like while, repeat until, for next, or an exit option in a do loop structure) rather than arbitrary jump in points. You will always return to from where you branched off by calling another function. In effect, you can only make jump out points. This have the advantage that it prevents much of the messy spaghetti goto or gosub commands create, as your code should nearly by magic become hierarchical all by itself. The disadvantage is, hmm, I can't really think of any...
This diagram is pretty typical of how you should plan your code:
In a typical program, like my latest effort -
a little score keeping app for a Twitch channel - the main loop code would look something like this:
// a lot of definitions of datatypes, arrays, and other terribly exciting stuff
// followed by...
/* *******************************************
*
* Main Setup
*
* *******************************************/
loadStart(maxTeams, folder$, image, sprite)
createBitSprites(sprite.bit0, subImage.bit_01, subImage.bit_40)
setupScreen(width, height, media)
/* *******************************************
*
* Main Loop
*
* *******************************************/
local menuChoice = 0
repeat
menuChoice = startMenu(screenGrid[33].x, screenGrid[33].y, maxTeams, folder$, width, height)
select menuChoice
case 1
countDownScreen(maxTeams, sprite, media, image, layer, width, height)
endCase
case 2
lowerThird(maxTeams, sprite, media, image, layer, width, height)
endCase
endSelect
until menuChoice = 99
It is however important to keep track of your assets - each screen you draw the needed bits and bobs, but when exiting you also need to clean it up, or else you may run into trouble. Most my 'Control Functions' consist of four distinct parts. 1: Declare local variables, 2: Draw screen, 3: Decisions loop, 4: Clean up screen. Like here from the same app:
function startMenu(xpos, ypos, max, dir$, w, h)
/* *******************************************
*
* Dependencies FROM main.agc:
*
* - team[]
* - screenGrid[]
* - image{}
* - media{}
* - layer{}
* - menuSprite{}
* - menuText{}
* - sprite{}
* - subImage{}
*
* *******************************************/
textSize = 40
spriteSpace = 48
menuExit = 0
selected = 0
setExit = 0
mChoice = 0
setBackground(image.background, layer.back, w, h, media.back1)
drawMenuSprites(xpos, ypos, spriteSpace, layer.front, menuSprite, subImage)
drawMenuLogos(screenGrid[1].x, screenGrid[5].x, screenGrid[1].y, layer.front, spriteSpace * 5, spriteSpace * 3, 1, 2)
drawMenuText(xpos + spriteSpace + 5, ypos, spriteSpace, textSize, media.font, 1, 2, menuText)
repeat
mouseX = round(GetPointerX())
mouseY = round(GetPointerY())
mouseHit = 0
if (getPointerPressed() = 1)
mouseHit = 1
endif
mChoice = menuSpriteHit(xpos, ypos, spriteSpace, mouseHit, mouseX, mouseY, menuSprite)
select mChoice
case 1
keyScan(menuText, mChoice, 3)
endCase
case 2
keyScan(menuText, mChoice, 2)
endCase
case 3
teamChange(1, max, dir$, sprite, menuText, h)
drawMenuLogos(screenGrid[1].x, screenGrid[5].x, screenGrid[1].y, layer.front, spriteSpace * 5, spriteSpace * 3, 1, 2)
endCase
case 4
teamChange(2, max, dir$, sprite, menuText, h)
drawMenuLogos(screenGrid[1].x, screenGrid[5].x, screenGrid[1].y, layer.front, spriteSpace * 5, spriteSpace * 3, 1, 2)
endCase
case 5
menuExit = 1
selected = 1
endCase
case 6
menuExit = 1
selected = 2
endCase
case 99
menuExit = 1
selected = 99
endCase
endSelect
sync()
until menuExit = 1
// save changes
saveStart(max)
// Cleanup
clearSprite(menuSprite.timeSet, menuSprite.closeApp)
clearSprite(sprite.logoStart, sprite.logoStart + max - 1)
clearText(menuText.time, menuText.teamBSet)
endFunction selected
(I like to keep track of all my dependencies, so where there are any, I collect them in a comment-box at the top of the function. That way I can easily and at a glance see what a specific function use should I make any changes. Such dependencies I strive to have less and less of - ideally none - the further down the pyramid I go. This function however is only on tier 2 of the pyramid, so there is quite a few of them. My naming convention is having brackets[] for an array, and a curlybrace{} for a data-type. discrete globals I avoid like the plague. They can easily grow too numerous to keep track of. I am also no fan of the Exit command, as it encourages multiple paths to exit a function, rather than having just the one entry point - as defined by the command 'function' - and only the one exit point - as defined by the command 'endfunction')
As for your second question, I'm not sure what to say. I can hardly type in a single line of code without having to revisit it to fix a typo or whatever that the compiler balks at