1. Hey! Guest! The 36th GMC Jam will take place between February 27th, 12:00 UTC - March 2nd, 12:00 UTC. Why not join in! Click here to find out more!
    Dismiss Notice

Potentially thousands of global variables at the same time. Best to avoid it?

Discussion in 'Game Design, Development And Publishing' started by Khao, Feb 13, 2020 at 1:26 AM.

  1. Khao

    Khao Member

    Joined:
    Jun 22, 2016
    Posts:
    163
    Okay, so. I'm making a multiplayer game where each player can create their own profile to save their own control configurations, and keep track of their own stats and whatnot. Think Smash Bros, you create your profile by inputting a name, and everything you do while using that profile is stored into that specific profile so the game remebers your personal preferences and achievements. You can change or create profiles at any time, and up to 4 of them can be used at once (because there's 4 players in the game).

    I'm still adding features to these profiles, but between controls, statistics, character customization, gameplay settings and other minor features, I'm already looking at something like 200 variables per profile. As you probably already guessed, I'm storing all of that data as global variables.

    Invite your friends over. Have multiple profiles for different game modes or just to screw around with the customization. Before you notice, you're gonna have, let's say, 30 profiles saved in your game. With my current system... that's around 6000 global variables. And that's assuming you don't create more profiles, which is perfectly possible. Create 100 profiles (my current maximum) and the game is now tracking 20,000 global variables!

    Now, worth to have in mind. All of those variables are not being constantly checked. You load up your profile and the game checks a bunch of the profile values to assign them to the active player, but otherwise? The game mostly just checks for player names to draw them on the UI.

    But with all that in mind...

    Is this... you know... bad for the game?

    Performance? Memory? Are there any drawbacks to using such a humongous amount of variables? Right now the game works perfectly fine enough, but I haven't really tested it on older PCs, so it's hard to tell for sure. Should I worry about it?

    I'm asking because it's not too late to go back. Just now, I'm starting to actually code a proper saving system, and it's the perfect opportunity to go back and delete all those global variables, while making it so the game only loads variables as needed. It's a lot of extra work, but if this can potentially become an issue, I'm more than up for it.

    However, if the impact on performance is like... insignificant, I'm not going to bother. Especially since I feel like it's easier to work with the global variables than having to save and load constantly whenever I want to access them. But again, if performance can be affected, then it's a must.

    So yeah, anyone had any experience dealing with thousands of global variables, or know of any potential side-effects? I've tried to google an answer and responses are kind of... mixed.
     
    Last edited: Feb 13, 2020 at 1:34 AM
  2. danzibr

    danzibr Member

    Joined:
    Aug 27, 2019
    Posts:
    9
    I see 0 problem with this. Presumably when you go to select a profile, you just access the names I imagine, then when you select one, you fetch the info for that particular profile. I don't see how this would strain a system (but I'm not a performance guru).

    Here's how I'd do it:

    Make your globalvar profile_preference or something.

    Have a limit on the number of profiles. I know Smash Bros has this (I filled it up). Say 100.

    Then I'd macro the profile stats. So NAME for 0, LIGHTATTACK for 1, whatever. 200ish of these.

    So when you go to select a profile, you're only fetching the max 100 names. And when you actually select a profile, you just fetch the 200 preferences for that.

    And when you make a new profile, you only define 1 at a time.

    Never searching through the full 20,000 entries.
     
    Khao likes this.
  3. RefresherTowel

    RefresherTowel Member

    Joined:
    Jul 13, 2016
    Posts:
    1,227
    Also, I'd just use a global list with each list entry being a "profile" and the profiles are stored as ds_maps, or some combination thereof, instead of using a ton of global variables.
     
    Joe Ellis and Khao like this.
  4. Cpaz

    Cpaz Member

    Joined:
    Jun 20, 2016
    Posts:
    347
    In general, global variables are bad practice unless absolutely necessary.
    But in the end, I don't think it'll impact performance that much.
    I'd say it would probably be better to load that data into a control object of sorts, then just pull from that when you need it.

    There are more caveats to using global variables I'd recommend looking up. Some might be exclusive to GM, other might be general programming practice.
     
    Khao likes this.
  5. FrostyCat

    FrostyCat Member

    Joined:
    Jun 26, 2016
    Posts:
    4,870
    Do you actually have thousands of distinct global variables? Whenever I see that kind of setup, there's usually a problem with not using arrays/lists/maps when they're clearly warranted. The main problem with that isn't performance, it's organization and maintainability.
     
    Khao and Joe Ellis like this.
  6. samspade

    samspade Member

    Joined:
    Feb 26, 2017
    Posts:
    2,231
    There's nothing 'wrong' with it per se but as others have said it is definitely bad practice. First, globals exist once they're created until the game ends. There's no way to remove them. So if they are individual variables that is a lot* of resources that just stick around (it's not really that much). If you used a list or map as others have suggested that list or map would stick around but since it can change in size you can remove things in you need to.

    Additionally, it is way harder to debug a bunch, especially hundreds, of global variables than it is a list or map. Also, much harder to save or transfer that data.

    Here's an article that discusses other ways of dealing with globals as well: https://gloomytoad.weebly.com/.
     
    Khao and Cpaz like this.
  7. Khao

    Khao Member

    Joined:
    Jun 22, 2016
    Posts:
    163
    Yeah, when I say global variables I really mean a collection of about 60 global arrays. I'm not actually typing out 20000 variables manually, haha.

    I think I could very comfortably reduce them to about 9 global arrays total (I need at least 8 of them to be separate, cause they're tied into a separate system for palette customization. If they're on their own, the whole system is super automated and easy to manage). Sounds like the best compromise, I think.

    Either way, I think I got the answer I needed. No, they won't impact the game's performance. But they can be a pain in the ass to manage if you don't set them up properly as a list with numbered values, which is something I could do better. This helps a lot, thanks everyone!
     
  8. Yal

    Yal GMC Memer GMC Elder

    Joined:
    Jun 20, 2016
    Posts:
    4,214
    A non-string variable uses a double or less, which means 2 words = 8 bytes. 20,000 variables would use in the ballpark of 20 * 1000 * 8 = 160 * 1000 = 160 kilobytes. For comparison, a standard-quality 3 minute OGG file uses around 3 megabytes of memory when loaded. So you can use upwards of millions of variables before memory starts becoming an issue, especially if they're arrays (which means less GM bookkeeping metadata).
     
    Khao likes this.
  9. Khao

    Khao Member

    Joined:
    Jun 22, 2016
    Posts:
    163
    Quick question!

    Turning my 60-ish 1D arrays into a single 2D one, using enums.

    So I got this

    Code:
    enum Profile
    {
       Name,
       Activated,
       RightButton,
       LeftButton,
       UpButton,
       DownButton,
       JumpButton,
       SpecialButton,
       StrikeButton,
       ShootButton,
       UltimateButton,
       StartButton,
       TimePlayed,
       MatchesPlayed,
       MatchesWon,
    }
    
    And it goes on for a while.

    I know I can manually set values to each individual enum. But what happens if I do something like this?

    Code:
    enum Profile
    {
       Name,
       Activated,
       RightButton,
       LeftButton,
       UpButton,
       DownButton,
       JumpButton,
       SpecialButton,
       StrikeButton,
       ShootButton,
       UltimateButton,
       StartButton,
       TimePlayed = 50, <--------------
       MatchesPlayed,
       MatchesWon,
    }
    
    Will the values before TimePlayed be numbered as 0-11?

    And will the values after TimePlayed start from 51? Or from 12?

    I'm asking because I'll most likely want to add enum types sometime later, and it'd be nice to be able to add data types close to similar elements. Like, have all control options together. If values after TimePlayed start from 51, I could give myself a bit of space so that saved profiles don't break by having a new version of the game change the order of values. If not, I could still do the same manually, but it'd be nice to know.
     
    Last edited: Feb 14, 2020 at 8:28 PM
  10. Yal

    Yal GMC Memer GMC Elder

    Joined:
    Jun 20, 2016
    Posts:
    4,214
    I strongly prefer using macros instead of enums, that way you can set any value you want and be certain nothing weird happens behind your back. (Also they've got better syntax highlighting and scope, and aren't restricted to integer values - not that that matters for array indices).

    Not sure how compliant GMS2 is, but in C enums start at 0 and increments by 1 for each new enumeration, setting an enumeration to a specific value will change the internal counter to that value (so you'd get 51, 52 and so on in your example). (Only way to be sure is to set them explicitly, though... I've seen that being done in business code at my job)
     

Share This Page