• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Room appearance change?(just curious)

R

rawket

Guest
So in a game I'm working on right now, I have a set of rooms that will at one point change from their normal look to a burnt look, and I wanted to know how would you go about doing that? I have my own way and it works but I was wondering if their is a better way because the way I'm doing it just really seems like it could be done way better. I'm currently just running a set of checks every time at room start and seeing if it's this room or that hide this tileset layer, show this other tileset layer, delete these objects, and so on. I feel like that is really inefficient but Idk if there is a better way. I'm sure there are probably loads of different ways it can be done as with most things but I just don't know them.
 

Yal

🐧 *penguin noises*
GMC Elder
GMS2 has a system that lets rooms inherit from each other, where you can import and/or override things from a different room essentially on a per-instance, per-tile basis. The manual's example of what it can be used for is a castle that's destroyed as you progress through the game, which sounds like exactly your use-case.

Whether it's better is a bit debatable, though - if you have a lot of references to the room in cutscenes and doors, it might be a lot of extra work to reroute them to the destroyed room once you've reached that progress marker. Changing the room dynamically is more work for the change, but has the advantage of only 1 room existing, which cuts down on bookkeeping.
 
R

rawket

Guest
That's about it. It causes no serious problems.
Hmm alright, just seems like it would effect performance having like double layers but I don't really understand what effects performance in gm either so :p
 
R

rawket

Guest
GMS2 has a system that lets rooms inherit from each other, where you can import and/or override things from a different room essentially on a per-instance, per-tile basis. The manual's example of what it can be used for is a castle that's destroyed as you progress through the game, which sounds like exactly your use-case.

Whether it's better is a bit debatable, though - if you have a lot of references to the room in cutscenes and doors, it might be a lot of extra work to reroute them to the destroyed room once you've reached that progress marker. Changing the room dynamically is more work for the change, but has the advantage of only 1 room existing, which cuts down on bookkeeping.
I basically currently am disabling many objects and hiding not needed layers, just seems like the sort of thing that would turn into an unneeded pile of codes and hidden stuff that never gets touched again and that really bothers me. I'd rather replace the sprites and tile sets but I'm having trouble getting it to work like that
 

TheouAegis

Member
Do you know how to access the ROM directly? I doubt it. That means you have three four five viable methods at your disposal when using Game Maker:
  1. Create everything in the IDE and then disable all layers not required initially (or disable all layers entirely and then activate as needed). Con: Eats up a ton of RAM
  2. Store all tile mapping in arrays; leave rooms blank. In a Room Start event, loop through an array and add the tiles in. Con: Eats up RAM, requires writing the arrays, slow
  3. Store all tile mapping in binary files; leave rooms blank. In a Room Start event, load a file into a buffer, loop through the buffer and add the tiles in. Con: Even slower, but less RAM
  4. Make a script return an array of the desired tile mapping; leave rooms blank. In a Room Start event, call the script then loop through the passed array. Con: Slow as 2, but less RAM
  5. Or, you know, just make duplicate rooms and go to the burnt-out room when the game-changing event has occurred. Con: Eats as much RAM as 1, but fastest option
I'm used to GM8 and GMS1 more than GMS2, so point 4 never occurred to me until now. That may actually be the best option if you want to generate the tiles every time you visit the room. The thing to keep in mind here is the difference between conserving memory and conserving time. The more RAM something requires, such as putting all variants of the room into one or more rooms using the IDE, the faster it's going to be to make those changes. Multiple rooms is far and away the fastest option, since deactivated instances and layers still get processed to a degree, so multiple rooms cuts out that facet of multi-layering event outcomes. Using binary files is the slowest method due to having to first read the file into RAM, copying the RAM into the buffer, then reading the buffer (which is on par with reading an array if done properly). Point 4 is the ideal array method if you are using GMS2, since the array data will only be temporary and thus not linger in the RAM. Since points 1 and 4 are viable only in GMS2, it seems clear to me that they're the best alternatives shy of point 5.

In any case, all 5 points share one thing in common -- they all require an unneeded pile of codes and hidden stuff that never gets touched again. Whether it's data stored in the PROM itself, inside external files, in an array, or just pre-existing rooms, it's all hidden and unused data that only gets touched when it needs to get touched.
 
R

rawket

Guest
Do you know how to access the ROM directly? I doubt it. That means you have three four five viable methods at your disposal when using Game Maker:
  1. Create everything in the IDE and then disable all layers not required initially (or disable all layers entirely and then activate as needed). Con: Eats up a ton of RAM
  2. Store all tile mapping in arrays; leave rooms blank. In a Room Start event, loop through an array and add the tiles in. Con: Eats up RAM, requires writing the arrays, slow
  3. Store all tile mapping in binary files; leave rooms blank. In a Room Start event, load a file into a buffer, loop through the buffer and add the tiles in. Con: Even slower, but less RAM
  4. Make a script return an array of the desired tile mapping; leave rooms blank. In a Room Start event, call the script then loop through the passed array. Con: Slow as 2, but less RAM
  5. Or, you know, just make duplicate rooms and go to the burnt-out room when the game-changing event has occurred. Con: Eats as much RAM as 1, but fastest option
I'm used to GM8 and GMS1 more than GMS2, so point 4 never occurred to me until now. That may actually be the best option if you want to generate the tiles every time you visit the room. The thing to keep in mind here is the difference between conserving memory and conserving time. The more RAM something requires, such as putting all variants of the room into one or more rooms using the IDE, the faster it's going to be to make those changes. Multiple rooms is far and away the fastest option, since deactivated instances and layers still get processed to a degree, so multiple rooms cuts out that facet of multi-layering event outcomes. Using binary files is the slowest method due to having to first read the file into RAM, copying the RAM into the buffer, then reading the buffer (which is on par with reading an array if done properly). Point 4 is the ideal array method if you are using GMS2, since the array data will only be temporary and thus not linger in the RAM. Since points 1 and 4 are viable only in GMS2, it seems clear to me that they're the best alternatives shy of point 5.

In any case, all 5 points share one thing in common -- they all require an unneeded pile of codes and hidden stuff that never gets touched again. Whether it's data stored in the PROM itself, inside external files, in an array, or just pre-existing rooms, it's all hidden and unused data that only gets touched when it needs to get touched.
Um idk what ROM or IDE are, but it sounds like whatever option I go with I'm going to be forever irked by my mild ocd
 

TheouAegis

Member
Um idk what ROM or IDE are, but it sounds like whatever option I go with I'm going to be forever irked by my mild ocd
The best method is to make separate rooms for the two states. That is the fastest method without intensive RAM overhead.
 
R

rawket

Guest
The best method is to make separate rooms for the two states. That is the fastest method without intensive RAM overhead.
Does having essentially duplicate rooms not cause a performance problem? If not that sounds like the easiest option as well
 

TheouAegis

Member
Rooms are only in memory when you visit them. A room is nothing more than empty data until it is the active room (unless you set them to persistent, which is a total memory hog). If you don't want a room to take up any memory, then don't design one. As soon as you design a room, you take up ROM data. When you visit that room, all that ROM data gets dumped into the RAM. ROM data is only a problem if you're trying to fit your game onto media like a CD or if the person trying to download your game has an ancient hard drive; RAM data is only a problem if you're really sloppy and writing for an old system.

Every game you've ever played requires ROM and RAM data -- you're probably not going to reinvent the wheel, so your OCD-ness boils down to just arguably unnecessary micromanaging. You'll get some savings here and there offset by additional costs elsewhere, but a one-time-per-room optimization isn't going to make any noticeable changes. Focus on optimizations that yield long-lasting, noticeable cumulative gains. Don't dwell on micro-optimizations, but just make note of them when you find them and incorporate them as you go. Like, if you're routinely using "if i>=0" and one day discover "if i | 1" is faster, don't waste your time going back through all your old code changing every instance of "if i>=0" over to "if i | 1", but just start using "if i | 1" moving forward. (BTW, I don't know if "i|1" is faster than "i>=0" and I doubt it'd yield significant gains). On the other hand, if you have, say, a movement code that is utter trash and you learn of a better way, then by all means re-write your project around the better code. If there's such a thing as perfect code, you're likely never going to find it. Super Mario Bros; Legend Of Zelda; Castlevania; and even most versions of Tetris have bad code in them, and yet nobody cares.
 
Last edited:
R

rawket

Guest
I gotta set most if not all of my rooms to persistent cuz I need them to progress and stuff
 

TheouAegis

Member
Ah, but do you need the entire room to progress? Or do you just need a few key elements to progress? Do you need to save every aspect and every single individual facet of every instance's existence? Or do you really only need a minute amount of data actually saved between visits to the rooms? As soon as you say, "I gotta set... my rooms to persistent," you've opened up a whole new level of macro-optimization that should give any OCD person anxiety. Suddenly you're going from using 500kb of RAM all the way up to nearly an entire GIGABYTE of RAM (or more). Next thing you know, your game will start to lag and the user might even start getting "virtual memory low" errors all because you dind't optimize your room states.

Just saying...
 
R

rawket

Guest
o-o I thought I was just imagining that frame loss. Maybe I'm getting really off topic now but how do I save stuff in the room then? Wouldn't that take like a really huge, annoying to manage array?
 

TheouAegis

Member
Well, the size of the array depends on what all you actually need to save. "Annoying to manage" is a subjective phrase. But yes.
 

Yal

🐧 *penguin noises*
GMC Elder
Um idk what ROM or IDE are, but it sounds like whatever option I go with I'm going to be forever irked by my mild ocd
ROM = Read Only Memory, also used to refer to read-only data files (like your game executable / asset bundle, which I think TheouAegis was referring to)
IDE = Integrated Development Environment, a single program that has all the dev tools you need (e.g. GameMaker:Studio 2) instead of you using separate text editor, compiler etc.
 
R

rawket

Guest
Well, the size of the array depends on what all you actually need to save. "Annoying to manage" is a subjective phrase. But yes.
Dang... I guess I could section them off by region. Idk I'm sure there's an easier way of setting it up than i'm thinking that I just can't see right now
 

GMWolf

aka fel666
I think what I would do is have 2 sets of layers.
The undamaged layers and the damaged layers.
I would give each layer a suffix "_A" and "_B" for the undamaged and damaged layers respectively.
Then when I enter a room, loop through every layer and determine if it should be shown or not based on the name suffix.
(I might even have a script per room to return if a layer should be shown or not).

This would work great for background, tilemap and asset layers.
For instance layers you would also need to deactivate the instances in that layer (which might be a little weird because of room creation order).

The other option, as mentioned is to use room inheritance. If you do have a lot of instances to toggle that might be the better way.

[edit]
Reading up on room inheritance again, its deffenitly the way to go if you dont have too many different permutations.
If its just the two, then its a really quick and easy way to go: just have a script to determine which room to transition to.

However, If you have many permutations, a more custom aproach to toggle different layers on and off as outlined above may be preferable.
 
Last edited:
R

rawket

Guest
I think what I would do is have 2 sets of layers.
The undamaged layers and the damaged layers.
I would give each layer a suffix "_A" and "_B" for the undamaged and damaged layers respectively.
Then when I enter a room, loop through every layer and determine if it should be shown or not based on the name suffix.
(I might even have a script per room to return if a layer should be shown or not).

This would work great for background, tilemap and asset layers.
For instance layers you would also need to deactivate the instances in that layer (which might be a little weird because of room creation order).

The other option, as mentioned is to use room inheritance. If you do have a lot of instances to toggle that might be the better way.

[edit]
Reading up on room inheritance again, its deffenitly the way to go if you dont have too many different permutations.
If its just the two, then its a really quick and easy way to go: just have a script to determine which room to transition to.

However, If you have many permutations, a more custom aproach to toggle different layers on and off as outlined above may be preferable.
I don't want to have to do that for every room every time though. If I don't have it set to persistent I'll have to do that. I think what I might do (unless this is a bad idea) is have the rooms that get burned have duplicate rooms one untouched and one burned, and in the room leading into them I just put in the warp/door object to go to the right room based on a global variable. Then for specific instances have those change state as needed. I feel like that would take the least amount of time and management and maybe even ram? Would this work?
 
Top