This is a detailed explanation of how I organise my code...it might look confusing because I'm being descriptive, but I've found this approach has been the most useful for me. And of course Pincho is spot on with the consistency, my letter for those kind of loops is always 'x', but to each his own.

Always good to be consistent without how you approach things to avoid confusing yourself later, "was that 'x' or was it 'z'?"
1. User Defined Types
Basically your UDT's can work like a database for your variables. Before I used them I'd have loads of different variables and arrays. With UDTs you're still dealing with the same data, but they're tidier.
For example:
type character
file as string
object as integer
collider as integer
health as integer
endtype
Steve as character
steve.file = "walkcycle.x"
steve.object = freeobject()
load object steve,file, steve,object
steve.health = 100
2. FreeObject(), FreeImage() etc
You will have spotted 'freeobject()' above. These sort of functions mean you're not keeping track of your object numbers, instead you'll just use the lowest free number and store it into a variable. You just need that variable, 'steve.object' is LOT more memorable than '364'.
3. Turn everything into a function.
I've completely eliminated all gotos in my code. But have some structure to your functions. I've taken some inspiration from XNA on this.
I try to section my main code out into section and each section is a function.
Intitialize()
I stick all global variables and arrays in here.
System()
I stick all system start-up stuff in here. Resolution, fullscreen, load options, fonts and I've even stuck shaders in here (I only load them once, so I don't make them a part of my main Load function)
LoadContent()
All of the content loading goes in here. So you 'load objects' and 'load images' and so on.
Update()
This is the game loop. You may wish to use functions inside of it to cut down the code. For example I use a separate function called 'UpdateCharacter(obj)', which keeps stats up to date and his control methods.
Then I have a function for managing scene cameras and other functions to keep the main loop code tidy.
Of course, I may introduce other functions to keep it tidy. For example I might have an inventory menu that calls a second loop and I want to return to the game, of course I could just call 'Update()' and put me back in that loop, but what if I wanted to reset a variable everytime I return to the update loop without looping? I just introduce 'Initiate' to go in between 'LoadContent' and 'Update'. You may wish to add more functions depending on how you've designed the game. But on start, the game just calls these functions:
Initialize()
System()
LoadContent()
Initiate()
Update()
Well, I actually have more, but that's just a structure to build from. Now, the advantage here is, you can use LoadContent() and the functions you use inside handle multiple levels in your game. So you can call these functions when you finish a level but with different variables. So you load a different scene, place different enemies in different places and so on.
4. Source File structure. I prefer to have multiple source files and each covers a specific purpose making it easier to point to each individual purpose of your game engine. A basic structure for me would be:
Source.dba -> this is your main
Purpose: make UDT's, call the game functions:
initialize(), System(), LoadContent(), Initiate(), Update() in that order.
GameManager.dba
Purpose: This is where your game functions (above) as stored) These functions will point to the different parts of your game engine, hence it is the 'game manager'.
Characters.dba
Purpose: to store all character data. This includes stats, which may be called in 'initialize()' or data to load, which may be called in 'LoadContent()'.
Scene.dba
Purpose: to set up the data for scenes/levels. This contains data for loading (LoadContent()) and things like 'LoadWayPoints'. I don't use this to set up individuals levels, these just contains things like:
Scene(object).map.num = freeobject()
load object scene(object).map.file, scene(object).map.num
The 'filename' for it is actually set up in a different function. This is where I stick a file called:
SetScene.dba
Purpose: This is where I create conditions for each individual scene and that's prepared for the 'LoadScene(obj)' function. So it could be:
if obj = bedroom
Scene(bedroom).map.file = "bedroom.x"
(you'll see that UDT is being used as an array. Just 'dim scene(number of scenes) as level' if you're unfamiliar with UDT's.)
An alternative approach is to have all of your data input via a script system, which requires more work, but it least it means not having to compile every time you change a variable.
My entire list of source files is fairly long, but that's because I've just built on top of that structure. But at least imeans I know what points to what and nothing is too generalised for it to not make sense later.
5. Comment your code
I find it's very important, particularly when things build in complexity. Whilst you can understand programming, you need notes to remind yourself what the purpose of each piece of code and why it's there. This means less stopping and asking yourself, "so what does this do again?"