Nah, they were introduced with 2.0. Planning and prototyping is how I manage to keep my code in check. First, I plan out a feature as best I can. This will always fall far short of what I actually end up needing, but it really helps to have some sort of baseline to refer to, especially when you come to segments of code that might actually conflict with each other, your original plan might have some aspect that helps you decide which direction to go in. After I've done the planning, I code out the thing in an empty prototype environment. This means starting a completely new project and only adding what I specifically need for that specific thing (for instance, in my combat section, I've recoded complete prototypes maybe 4-5 times and only went ahead adding it to my actual production version when I was happy with the prototype). This is where you'll often encounter the problems that lead to sloppy code and negative influences on your project.
For instance, let's say you have a knockback feature planned. Everything seems cool, you add it to your project, and then you realise that you need to account for when you knock an enemy into another enemy. You didn't plan for this and so you do a quick fix of the code just to get the combat working properly again. During this "quick" coding of the feature, you probably neglected to implement the code in the best way possible. Or perhaps you're newly coded knockback effect has run-on problems (maybe the second enemy is getting knocked into walls). So you do a quick fix of those knock on effects. Suddenly, before you know it, this minor problem that you didn't foresee has led to multiple quick fixes to your code and probably a much dirtier code base than if you had it planned out from the start, with podges and bandaid solutions here and there that, once you've added them in, are all too easy to simply move on from and hope the codebase doesn't break any more.
If you prototype things out in their own clean environment, you can encounter these problems, hodge-podge fix them and get the combat to a point where it works how you want but now you HAVE to code it again to put it in your main project, so now you can do that with foreknowledge of all the potential problems you'll have and a much better vision of how the code -should- look.
Beyond that, using data structures effectively (especially JSON in GMS, as that is the most readily accessible one) is an important point. Make sure that your game is drawing information from structures that you control, rather than a hodge-podge of different variables in different instances and objects (I mean, there's no problem with using variables in this way, but too often people neglect the benefits of central storage when it comes to some of this sort of stuff and end up implementing multiple storage/retrieval solutions for a (single) thing/s, when something could easily be written from the start that gives you a centralised storage container to hold these things in). This is especially useful when it comes to saving games. Much easier to have a central map/list structure at the start of coding and store the vital things that you'll need to save in there than having to go through your entire codebase later removing/editing code so that you can have properly save functionality when you're three quarters of the way into your project (this is, of course, if you are using JSON for saves, a lot of people prefer buffers for speed, but IMO it's personal choice unless you need to really squeeze every single bit of speed out of your code to make it function well).