largest room size

Started by lafouine88, Thu 18/07/2024 22:31:09

Previous topic - Next topic

lafouine88

Hi guys

I'm facing a room problem on my rpg game. I had planned to design large rooms, like in DIABLO, in which the player can feel the universe IS big. I initially thought this wouldn't be a problem for the AGS engine but after a few tries and discussions on the forum, I realized I was going to be limited by the room size.
I read in a very old post here that the max room size for a 640*400px game ( my resolution) is 2800px height and pretty much unlimited in width. I tried a few things and it is great for 2800*10000(it also works with 2800 width and 10000px height btw).
Thing is, I really had planned a 5600px high map, so I'm missing half of it with this limitation. I tried creating two different maps and setting an edge between them that teleports to the next map with eNextscreentransitioninstant, but there is a tiny pause that also breaks the character walk. The last part can be corrected with a load function I guess, but I couldn't remove the small loading pause, even with a blank room and nothing to load in it.

I guess I could go with it, it breaks a little the dynamic and maniability (which is important in this kind of game) but it's not a huge problem. But before I resort to that I would like to know if any of you already encoutered this kind of issue and if you found a trick :)

Thanks <3

Crimson Wizard

#1
I think i posted a reply to something very similar a while ago. (I cannot remember whether it was your question or someone elses).

The thing is, there's a difference between how AGS does the rooms and how "big world" games do their "rooms".

In AGS the room is a seamless bitmap for background. This is convenient in point and click games, but may be not convenient when you're making other kinds of games, such as arcades, or strategies, etc.

These games usually don't use a single background bitmap, instead they have scenes constructed of tiles dynamically (with some optimizations). These tiles may be of various sizes: small cells, or bigger chunks, - whatever is more convenient for a particular game and its art style. But in a very nutshell, they have the world in memory as some data, and generate the visuals as player walks around. When player passes a part of the world, its visuals got discarded from processing, and sometimes from memory. If the world is really big, they would not keep it whole data in memory, but load parts of it from file(s), and unload some parts when player is far away from them.

This system is doable in AGS, but you have to program it yourself in ags script, with some good forethought.

How much and what you will have to do depends on which AGS functionality are you planning to use. For example, for visuals, you may use room overlays to dynamically create visual parts of the world and displayed them in a tiled manner. If you need to use AGS pathfinding, then you will have to also dynamically update room masks as player moves to other places (the walkable mask is accessible using DrawingSurface).



In regards to the 2009th post about room sizes, I suggest to completely ignore that, because many things changed since.

There's no hard limit on a room size now, but there may be problems with some functions if your room exceeds 32k of size in any axis. That's because some parameters in game objects are represented as signed 2-byte numbers, meaning they will "wrap" to negative values if exceed 32k.

That said, I have no idea how well it would work if you make a giant seamless 32k x 32k room. Personally, I would recommend reconsidering this approach, and instead either split the world into multiple rooms, or think of methods that I mentioned above. But it's your choice what to do with your AGS game.

lafouine88

Quote from: Crimson Wizard on Fri 19/07/2024 09:34:26I think i posted a reply to something very similar a while ago. (I cannot remember whether it was your question or someone elses).

Yes, it was on an optimisation issue I had, and this topic came up^^.
I thought about your reply and I think I understand it. I would totally go for a dynamic sprite generated background map, I guess it would save considerable memory/RAM. But to do that it would be much easier to initally plant a huge room, on which you would define your walkable are mask, characters' positions etc. and then turn the background to a big black sheet, that you would continuously replace with the dynamic sprites as the character moves.
The problem is(and the second part of your reply makes me wonder why :confused: ) I tried to create a big plain room of 6k*10k but when I wanted to draw a walkable area, the program crashed. I thought I had excedeed the limits of ags but maybe that's not it.

I'll try again ^^

lafouine88



Oh yeah I forgot, this also happens (here the background is 6k*15k)

https://ibb.co/N3GPGYW

Khris


Crimson Wizard

#5
Quote from: lafouine88 on Fri 19/07/2024 12:40:50But to do that it would be much easier to initally plant a huge room, on which you would define your walkable are mask, characters' positions etc. and then turn the background to a big black sheet, that you would continuously replace with the dynamic sprites as the character moves.

No, the idea is to not create a huge room (like 6k x 15k) at all, but create a smaller sized room, like a smaller canvas, on which you place pieces of a larger background, objects, and walkable areas, corresponding to the current "active" area.

The thing is, it does not matter whether there's a valid background, or a blank background, it takes exactly same size in memory ("blank" pixels are still pixels). And masks also take memory. And objects and characters do. If you display all of that at once, that would require extra processing and memory.


lafouine88

Quote from: Crimson Wizard on Fri 19/07/2024 20:54:45The thing is, it does not matter whether there's a valid background, or a blank background, it takes exactly same size in memory ("blank" pixels are still pixels).
I thought the same but was explained that pictures are like divided into areas of the same exact colors. So if you have one huge area of a single color it takes almots no memory (my room sprite was 100 ko) while a picture with different colors on every pixel will take more, even a two colors grid (the map I drew was 18Mo and it's more than 4 times as small). Multiplied by the number of maps I thought it was worth saving a bit, maybe it's not relevant compared to the extra ram it would require to generate the tiles.

To get back to the main issue.. With your explainations, I don't really see how I could work that out. It seems out of my range and maybe should have been planned earlier.

Too bad then, I guess I'll go with the loading pauses. I'll do my best to smooth them out :s

Thanks for all the tips Crimson  :)  :)

Crimson Wizard

#7
QuoteI thought the same but was explained that pictures are like divided into areas of the same exact colors.

That's true for images saved with RLE compression (for instance). But bitmaps are uncompressed when loaded in AGS memory.
Textures created from room bgs may be compressed in their own way, although I do not know if they are or which compression they use (graphics driver is responsible for that).


lafouine88

Actually, Using overlays seems very promising and seems doable. I ll give it a try and keep you posted if it's works, or, more likely, if I need help😅😅

lafouine88

@Crimson Wizard Overlays indeed look quite promising. Still I can't figure out something. This function simply draws an object/image on the existing room. But it doesn't stretch the room limits. So eventually this comes back to the problem I meant yesterday, if I want a continuous large map, I still need a huge blank map the same size on which I would add the different pieces of map right?
Or do you mean that each time I add an overlay I should 'replace' all my coordinates to get back in the center of my room. A little like a treadmill?

Crimson Wizard

#10
Quote from: lafouine88 on Sat 20/07/2024 21:25:18Or do you mean that each time I add an overlay I should 'replace' all my coordinates to get back in the center of my room. A little like a treadmill?

Indeed, more or less so, that idea is to have a smaller room and keep visuals moving sideways.

This may be implemented in various ways. It may move all the time as player moves (in which case your room may be only bit larger than the screen), or it may replace bigger chunks of the room when player reaches certain threshold.

The choice depends on various factors, including whether you are using AGS own pathfinding (walkable areas in the room).
Note that this may be easier to do in the upcoming AGS 4 update, where there's a pathfinding API which allows to use custom sprites as masks, and not rely on room itself.

lafouine88

Wow this seems really cool oO, thanks again
When is AGS 4 update planned for then?  :grin:  :grin:

lafouine88

Hi guys

So, overlays work fairly well I you're planning on doing big maps. The delay is almots imperceptible and it allows to save a lot of memory.

Basically what I've done so far is :

-I have 4 sprites, one for each part of the map and all the same size, which is also the size of the room (maybe not optimal but much easier to create the different 'parts' of the room), the edges are defined with a demi screen margin (my resolution is 640*400 so it's 200px from top and bottom and 320 on ech side).
-I created a draft room(same size) on chich I change the backgrounds to set my characters placement, walkable areas masks, objects... This is also the room in which I teleport useless characters when the part of the map changes.
-Then I created a function ( still getting better so I'll share when I'm finished) thats moves objects and characters in and out of the map(using the settings from previous room, and storing useless things in the same room), changes the map overlay, and teleports the player to the other end of the room (chen I'm on top I get to the bottom-1). This function gets triggered in Room_leaveBottom/LeaveTop etc.


Still I don't get how I import my walkable areas masks on new overlays. @Crimson Wizard  spoke of drawingsurfaces, but I didn't find how to transform tha into a real walkable area, and also (though I guess it's going to be the same method) how to change the walkbehind areas and regions.
Could you guys give me a hand here ? I feel like I'm getting close to a nice resolution :)

Thanks



Khris

Just to make sure: you're using AGS 4, right?

Crimson Wizard

Quote from: lafouine88 on Wed 24/07/2024 16:46:15Still I don't get how I import my walkable areas masks on new overlays. @Crimson Wizard  spoke of drawingsurfaces, but I didn't find how to transform tha into a real walkable area, and also (though I guess it's going to be the same method) how to change the walkbehind areas and regions.

This is not done with overlays.
If you are changing areas in the room, there's GetDrawingSurface method for all of them:
https://adventuregamestudio.github.io/ags-manual/Hotspot.html#hotspotgetdrawingsurface
https://adventuregamestudio.github.io/ags-manual/Region.html#regiongetdrawingsurface
https://adventuregamestudio.github.io/ags-manual/Globalfunctions_Room.html#getdrawingsurfaceforwalkablearea
https://adventuregamestudio.github.io/ags-manual/Globalfunctions_Room.html#getdrawingsurfaceforwalkbehind

After getting a drawing surface, you may paint a new mask on them.

AGS 4 has slightly different functions.

lafouine88

#15
Quote from: Khris on Wed 24/07/2024 18:33:15Just to make sure: you're using AGS 4, right?
No I was still on 3.6.1, I hadn't seen 4.0 was already out. So I'll get it to start with "^^ thanks



Quote from: Crimson Wizard on Wed 24/07/2024 18:50:07This is not done with overlays.
If you are changing areas in the room, there's GetDrawingSurface method for all of them:
https://adventuregamestudio.github.io/ags-manual/Hotspot.html#hotspotgetdrawingsurface
https://adventuregamestudio.github.io/ags-manual/Region.html#regiongetdrawingsurface
https://adventuregamestudio.github.io/ags-manual/Globalfunctions_Room.html#getdrawingsurfaceforwalkablearea
https://adventuregamestudio.github.io/ags-manual/Globalfunctions_Room.html#getdrawingsurfaceforwalkbehind

After getting a drawing surface, you may paint a new mask on them.

AGS 4 has slightly different functions.

@Crimson Wizard, what do you mean by 'painting' on it? Am I able to somehow use the import mask option to directly apply the mask shape to the drawingsurface? Because I cannot draw it using rectangles and circles, the walkable areas I'm planning to use depend on the terrain and elements of the map so it makes it drawable with the pencil tool, but not really using drawingsurface functions.
Or am I not getting what you suggest at all?^^

Khris

It looks like you need to do the following:

First, import a png that has a part of the walkable area (any color for the area, everything else transparent) to define the shape. Repeat for every part of the walkable area.

In game,
1. create a dynamic sprite (1) from the imported shape sprite
2. create a second dynamic sprite (2) and fill it with DrawingColor [AreaNumber] by drawing a rectangle to it
3. use CopyTransparencyMask to copy the transparency from (1) to (2)
4. get the drawing surface for the walkable areas, clear it, then draw sprite (2) to it

You obviously do this in a custom function, passing the area number i.e. color and sprite slot into it.

Crimson Wizard

#17
Quote from: lafouine88 on Wed 24/07/2024 19:22:09@Crimson Wizard, what do you mean by 'painting' on it?

I mean - import your world mask pieces as sprites, and then use DrawingSurface.DrawImage function to paint these sprites over room as location changes.

Quick code example, only to illustrate basic idea:
Code: ags
DrawingSurface* ds = GetDrawingSurfaceForWalkableArea();
ds.Clear(0);
ds.DrawImage(MASK_SPRITE);
ds.Release();

Unfortunately, there's a missing functionality in AGS 3.*, where it does not let you import 8-bit sprites into 32-bit games and keep them 8-bit (it converts everything to 32-bit). So if you are in 3.*, then you likely will have to resort to some workaround.

Khris seems to have a suggestion, although I did not test that myself.

In AGS 4.0 this may be easier, as engine lets you import and keep 8-bit masks as sprites, and use them in game as 8-bit.

There of course may be a different approach. For instance, you could try generating walkable or non-walkable areas (walls) from the background somehow, or from a custom data which describes obstacles. But this largely depends on how do you define your levels.

lafouine88



Quote from: Khris on Wed 24/07/2024 21:49:55It looks like you need to do the following:

First, import a png that has a part of the walkable area (any color for the area, everything else transparent) to define the shape. Repeat for every part of the walkable area.

In game,
1. create a dynamic sprite (1) from the imported shape sprite
2. create a second dynamic sprite (2) and fill it with DrawingColor [AreaNumber] by drawing a rectangle to it
3. use CopyTransparencyMask to copy the transparency from (1) to (2)
4. get the drawing surface for the walkable areas, clear it, then draw sprite (2) to it

You obviously do this in a custom function, passing the area number i.e. color and sprite slot into it.

Hi again
So I've tried this method but for some reason i'm always getting an error message. This is what I wrote :

Code: ags
 DynamicSprite*ds2 = DynamicSprite.CreateFromExistingSprite(4177); ///sprite 4177 is a big rectangle the size of the room
 ds2.CopyTransparencyMask(4176); ////4176 is the shape i want for the walkable area

DrawingSurface* surfacewalk1 = GetDrawingSurfaceForWalkableArea();
surfacewalk1.Clear(0);
surfacewalk1.DrawingColor = 1;
surfacewalk1.DrawImage(0, 0, ds2.Graphic);
surfacewalk1.Release();
I get this error message https://freeimage.host/i/dIv9H42

Did I misplace a line or forget something here? It seems quite logic to me so I cannot find aything else^^



Khris

I wrote this from memory so I didn't realize the CopyTransparencyMask() method requires a slot.

Regarding your code, I assume you put this in a function? Which one?
Also, the error is the dreaded non-specific 0xC0000005 one, not sure what's causing this.

SMF spam blocked by CleanTalk