How to plan and manage code for larger projects

Discussion in 'Tutorials' started by tagwolf, Aug 23, 2019.

  1. tagwolf

    tagwolf Member

    Joined:
    Aug 6, 2016
    Posts:
    59
    Game Development Code Planning

    GM Version: ANY (and not just for GameMaker, however this will be GMS2 "centric")
    Target Platform: ALL
    Download: N/A
    Links: N/A

    Summary:
    This tutorial will go over code and object planning for game (and application) project development to minimize re-coding and optimize your organization and planning from day 1. This is not "How to write a GDD (game design doc), but rather how to plan an outline for your objects and what they are actually going to handle. In this tutorial we will plan out a clicker game, but again, this is not for a clicker game, this methodology applies to your project too!

    Tutorial:
    I'd like to start by stating that my main job in real life is not game development, but infrastructure architecture and workflow optimization. I code and make tutorials for gamemaker in my spare time. You might be surprised how much process and workflow optimization apply to all systems, not just computers, not just coding games, all systems have a way of optimizing them. How you optimize your project is up to you, but this should give you a good foundational knowledge on how to "think like a computer" while adapting your code and objects to be optimized and maintainable for a human.

    I said before this is not a tutorial on how to write a game design document and it isn't. However this low-level summary (I know that sounds weird) planning should be a part of your GDD. Which if you haven't written a GDD before, there's a litany of templates that exist out there of various quality. Point being, if you are serious about a project, make sure you fully understand the game you want to make beforehand and document that. This includes things like, what does each screen look like, how does the player control and interact with things, what are the win/lose conditions, how many objects do you need and what are they, etc.

    That last one, objects, is critical and way too often overlooked by people starting out in GameMaker.

    I'm going to suggest something here that you won’t see mentioned a lot or gone over in many tutorials for GMS unfortunately (although for whatever reason the Unity programmers do practice design more often this way, that’s likely due to the nature of C#). My suggestion is this, start thinking about the objects that won’t have a sprite or be visible on your screen at all, start thinking about controller objects.

    What is a controller object exactly? Well imagining our clicker game we’re going to plan out here (or your platformer game, rpg, or whatever you are making). For something as basic as how many times we have clicked a button, let’s say we have 2 objects so far:
    • obj_button – The button object you click on to increment your score
    • obj_ui_score – The UI object that displays your score

    Which one of these would you store the number of times you clicked in?

    Think about that as we go forward here, we’ll work out the answer together as we go.

    Let’s consider a less esoteric example. We’re making a platformer game similar to Super Mario Bros. in GMS2. We have the following basic objects so far:
    • obj_player
    • obj_enemy
    • obj_ui
    • obj_floor

    Where would you track how many lives a player has left? (well the player duh.)
    What about how much health they have? (player definitely)
    What about how much time is left in a stage? (hmmm, toss this into the ui object?...maybe the player?)
    What about what stage they are on? (probably just leave that up to the current room right?)
    What about handling keyboard and controller inputs? (player..I think)

    Look, none of these are invalid, but they present a few problems. For one, they make our project pretty rigid. It makes us have to think back and remember where something is. What about when our player dies and we want to destroy the player object…what happens to the data regarding their lives remaining? What if we want the player to do more damage when they reach a certain score? Now we’ve got to figure out logic between the player and the score and maybe the enemies too. What pieces of that are we going to put where?…How about when we want to add new mechanics, we are going to have to figure out where to put something and how that works with our current code and objects. This gets out of hand FAST for small games and can completely sink bigger ones to the point where I’ve seen people have to blow up the project and start coding from scratch multiple times.

    There’s a lot of solutions to these sorts of problems as a project scales, but the best ones I’ve found are the following:

    Track ephemeral states, evaluations, and changes that only involve a particular object directly in that object

    Examples:
    Is our player jumping?
    What’s our current position on screen?
    Are we on the ground?
    Are we touching an enemy?​

    Track states we need to retain, game setup, and general coding logic/evaluations that involves multiple objects or states that need to be retained if an object disappears or not in controller objects.

    Examples:
    How many lives do we have left?
    How much time is remaining on this level?
    How many enemies should spawn at this difficulty?
    What are the keyboard and gamepad controls?
    What level should we load next?
    Has the player reached a checkpoint and which one?​

    This list of things a controller object handles can go on forever and that’s the beautiful thing about it. We always know where all our crap needs to be tracked.

    Back to our clicker game. We are missing a few objects here. First, lets think about what we want our game to do.
    • Count and track button clicks and stats (money, points, whatever)
    • Track the game state, lets say we want to have new buttons and stats “unlock” when we reach a certain level of progress
    • Display stats to our player
    • Etc, etc, etc.

    I want you to start thinking about 3 things for ALL of your objects based on your game design.

    INPUTS – What information will my object be able to receive? Either from player controls (keyboard/mouse/gamepad/etc), other objects (collisions, distance, variables, etc), or the engine itself (current room, alarms, etc).

    PROCESSING – What should this object do to process this information? Is this the right object that should be processing this information or should this function I’m writing be centralized using controllers and scripts (Scripts is a lesson in itself that is beyond the scope of this document, but you should look into using them more. Especially for functions you write that more than one other needs to utilize. Ultimate rule of thumb for code is DON’T REPEAT YOURSELF!)

    OUTPUTS – What information that was processed or passed-through do I need to send out from this object? Is another object going to initiate the request for information or should I send it out? Should this be centralized in a controller?

    The 2 questions you should be asking yourself constantly while coding are “Does this go here?” and “Should I centralize this?”

    Now this is always going to be a balancing act. Because you can go too far down the other path and put everything into a controller object which while that does centralize things, might make stuff you need to do frequently on an object not make much sense there as you needlessly pass information back and forth. There is a sweet spot and it’s different for almost every project. You’ll figure out what works for you.

    Also, figure out your naming convention and stick with it for “like” objects and inheritance. Some examples are below from my high-level object plan.


    I’ll leave you with the notes that I put together when I was creating a object plan for my networking “internet clicker” game. A clicker game where you are trying to make the biggest and best ISP you can by buying new areas on a network map and sending packets back and forth to earn income.

    obj_controller_counter
    • tracks count of all stats
    • information for ui display / stats
    • receives stats changes from buttons, automation, and event results
    obj_controller_state
    • checks counter at some interval
    • changes game state based on counter progress
    • enables and disables buttons, ui, and stats elements
    obj_controller_map
    • handles map objects
    • handles map object input and purchases (however counters track the cost, etc.)
    • receives inputs from buttons and other objects and events to display animations and packets moving
    • sends information back to counter / state when applicable
    obj_ui_stats_X (collection of ui display objects like clicks, money, bandwidth, etc)
    • collection of ui objects and stats objects
    • queries counter and state to determine which elements to display and what their values are
    obj_ui_menu_X (collection of objects like new game, options, etc)
    • main menu interface objects
    • handles menus events and captures mouse/keyboard input
    obj_map_X (collection of objects on the network map playfield)
    • collection of objects that displays animations, network map, and playfield map ui elements
    obj_button_X (collection of clicker button objects like ping, traceroute, etc)
    • sends increments to counter controller
    • captures mouse / keyboard clicks and input
    • triggers click related ui elements? (maybe this should be a separate controller for the map?)

    If you’d like to see more examples, search for my other project tutorials such as coding a match 3 game. You can see in that project how I split out objects, controllers, and scripts to do things like create a playfield, keep score, move pieces around, check for matches, etc.

    Also if I ever finish this clicker game I'll do a more in depth dive of it and the specific design, planning, and layout.

    I hope this helps someone out there a bit. I know it’s not whitepaper quality, I wrote it at 3am on a workday because I couldn’t sleep. But maybe it’ll give you a different perspective.


    The main thing is to do what works for you and evolve. The more you do this, the more you’ll learn to optimize. It’s what humans were built to do. Good luck, have fun!
     
    Last edited: Aug 23, 2019
    damon, KPJ and HayManMarc like this.
  2. chance

    chance predictably random Forum Staff Moderator

    Joined:
    Apr 22, 2016
    Posts:
    790
    The topic is approved, so members can discuss it.

    I thought about moving this to Game Design forum, and that may be the right place. Topics about design, planning and organization generally belong in Game Design, whereas programming topics belong here in Tutorials.

    Of course, planning and execution must overlap at some point, and this topic is an example of that. So we'll leave this here, unless there are compelling reasons to move it.
     
    tagwolf likes this.

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice