largest room size

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

Previous topic - Next topic

lafouine88

Quote from: Khris on Sun 28/07/2024 12:25:21Regarding your code, I assume you put this in a function? Which one?

I put it in a custom function that is called on the edges (leaveroom.bottom/top...), along with the overlays changes(and I ll also add here the walkbehinds and hot spots with the same method)

lafouine88

Hey guys
So I'm back from vacations and had time to think about a solution. Unfortunately, none of my not-so-brilliant ideas made it work. So I had to resort to the non elegant solution for walkable areas, which is : create many walkable areas and remove/restore theme according to the current map background. The reason I didn't want to use that is it creates many areas with various intersections (2^n -1, n being the number of parts of your map). So for my map that uses 4 different parts I have to manage 15 walkable areas, which is the maximum.
walkbehind areas will work the same, although by far not as tedious.

Thanks to everyone for suggestions and maybe in the future, a new version of the software will makes things easier :grin:  :grin:

lafouine88

Hello again "^^ "^^

This topic is running in all directions, I can change the title if needed.
Since it's the first time I try it (I first wanted to create a viable system for the rooms) I've just realized such a  huge walkable area slows down the game insanely. Do you guys have any piece of advice to smooth it? Like things I could do or should avoid doing when drawing the mask? When the whole map is covered in walkable area it's fluid, but it seems adding edges makes the system overload.

Thanks

Khris

The shape of the area shouldn't matter but composing it anew each frame will very much make a difference. However the whole point of doing this was to not have a massive room in the first place.

What exactly are you doing? Can you show relevant code?

lafouine88

You're right, it becomes hard to follow.

So, the idea was to build a big world in which the character can navigate on isometric view, like in Diablo. The map I created was 5200*16000 px for one area and I wanted to have as few "loading screens" as possible (to not break to much the rythm).
This room's size was too much for AGS limits so I first thought I would use smaller maps and use "setscreentransitioninstant" to navigate between each other. Problem was this created a lot of small pauses when you go from one room to the other, and this is not good for the pace of the game.
That s when I started this topic.

Initial idea you guys gave me was to use overlays to extend the size of the map. It's very good, there is a small loading pause, but it is very short, so acceptable. I thought a good balance between room size and the number of room changes was to divide the map in 4 2700*8200px rooms(a bit larger for the room edges to overlap the next one).
I created one room this size, 4 edges and this code (shortened version, the real one is more generic) :

Code: ags
function changement_zone(int j){
  // j exit direction (0 up, 1 down,  2 left 3 right)
 int s;
 int t;
if(j==0){ //up
  Zone_encours++; //some system to find the right sprite number for the next part of the map
 s=player.x;
  t=2599;
}
else if(j==1){ //down
  Zone_encours--; 
  s=player.x;
  t=201;
}
else if(j==2){//left
  Zone_encours+=2; 
   s=7871;
   t=player.y;
}
else{//right
  Zone_encours-=2; 
s=321;
 t=player.y; 
}

testmap=Overlay.CreateRoomGraphical(0,0,maptableau[Zone_encours].spritemap); ///the map sprite is found using an 
testmap.ZOrder=0;
player.x=s;
player.y=t;


So far everything is ok.
Problems started with the walkable areas. Pretty much everything is in the discussion. I cannot use drawing surfaces to import my walkable areas (maybe because of the 8/32bit transformation. I had to stay on 3.6 because changing to 4.0 meant changing a lot of the code I've already written, and this seemed really too much to correct, I've worked the last 6 months just to create the RPG functions :s)

So, after trying many things I decided to go back to drawing manually the walkable areas,with intersections, and to remove or restore them according to the part of the room, something like that :

Code: ags
function changement_zone(int j){
  // j exit direction (0 up, 1 down,  2 left 3 right)
 int s;
 int t;

/////remove all the walkable areas
for(int x=1;x<16;x++){
RemoveWalkableArea(x);
}

if(j==0){ //up
  Zone_encours++; //some system to find the right sprite number for the next part of the map
 s=player.x;
  t=2599;
///just restores the appropriate ones
RestoreWalkableArea(1);
RestoreWalkableArea(5);  ///since walkable areas (1,2,3,4) don't overlap, it creates a lot of intersections that need to be separate walkable areas (1//2 , 1//3, 1//4, 1//2//3,1//2//4, 1//3//4 and 1//2//3//4)
RestoreWalkableArea(6); //1//2
RestoreWalkableArea(7); //1//3
RestoreWalkableArea(8); //1//4
RestoreWalkableArea(9); //1//2//3
RestoreWalkableArea(10); //1//2//4
RestoreWalkableArea(11); //1//3//4
RestoreWalkableArea(12); //1//2//3//4
}
else if(j==1){ //down
  //...
}
}


That is when I drew my first walkable area, and when I tried it, the character started to lag a lot.

That was just for the background, but while writing this I realized the problem could come from a separate function I made. And it does "^^
So this is the problematic function : The idea was to make the player able to leave the left button down to move the character(and not click every second) :

Code: ags
function mouse_continous_down(){
  if(mouse.IsButtonDown(eMouseLeft)&&GUI.GetAtScreenXY(mouse.x, mouse.y)==null&&Character.GetAtScreenXY(mouse.x, mouse.y)==null&&Object.GetAtScreenXY(mouse.x, mouse.y)==null){ ///the exceptions are so you can still interact with the world
  Room.ProcessClick(mouse.x,mouse.y, eModeWalkto);   
}
}

function repeatedly_execute()
{ 
mouse_continous_down();
}

When I comment out this function, it's ok, so the problem isn't with the walkable areas, but with this function "^^it freezes the game when I click on a non walkable area. I tried adding an exception :
Code: ags
function mouse_continous_down(){
  if(mouse.IsButtonDown(eMouseLeft)&&GUI.GetAtScreenXY(mouse.x, mouse.y)==null&&Character.GetAtScreenXY(mouse.x, mouse.y)==null&&Object.GetAtScreenXY(mouse.x, mouse.y)==null){
if(GetLocationType(mouse.x, mouse.y) != eLocationNothing){
  Room.ProcessClick(mouse.x,mouse.y, eModeWalkto); 
}
}
}

But it blocks the continuous function. Any ideas?

And many thanks for your patience -_-




lafouine88

#25

Khris

You're basically telling AGS to find a walkable path 40 times per second. You can try to lower that number like this:

Code: ags
int frameCounter;

function repeatedly_execute()
{ 
  frameCounter = (frameCounter + 1) % 5;
  if (frameCounter == 0) mouse_continous_down();
}

This should reduce the lag but have little effect on the button processing.

Solving this in an optimized way probably requires completely custom walking / walk cycle code.

Crimson Wizard

Quote from: lafouine88 on Wed 21/08/2024 10:45:24I cannot use drawing surfaces to import my walkable areas (maybe because of the 8/32bit transformation.

So, I tried that and there seems to be a bug in the engine, when you try to draw non-8bit sprites on walkable surface it corrupts the game memory. This must be fixed first, and after that see again if it might work at all.

There's also a chance that this may be done differently, if DynamicSprite.CopyTransparencyMask works between sprites with different color depth. If it does then:
* create dynamic sprite from walkable area's drawing surface (the sprite should be 8-bit)
* fill the sprite with color 1
* use DynamicSprite.CopyTransparencyMask to copy only transparency from the imported sprite to 8-bit sprite
* paste 8-bit sprite back onto walkable area.


I will have to find some time and experiment with this.

eri0o

If you just need to click and hold have the character move in the direction that the mouse is, you don't need to use the pathfinder at all, you just draw a line and end it in the mouse or where there is no walkable area, whatever comes first, but you can only test the amount the character can walk in a frame, which are very few pixels. Then the only one using the pathfinder are the monsters and they can be pretty easy to limit since they won't be recalculating on every frame.

The other approach is to do something like this : https://ericoporto.github.io/public_html/surviving/v6/

Essentially when you click and hold it waits the character finish walking before telling it to walk again but you can click in the middle to interrupt the walk.

lafouine88

Thanks for your replies :)

Quote from: Crimson Wizard on Wed 21/08/2024 13:02:51* create dynamic sprite from walkable area's drawing surface (the sprite should be 8-bit)
* fill the sprite with color 1
* use DynamicSprite.CopyTransparencyMask to copy only transparency from the imported sprite to 8-bit sprite
* paste 8-bit sprite back onto walkable area.

Maybe I misunderstand, but the problem is the first step here. When I import the 8bit-mask (either fom a pixel art software or from an AGS exported mask) it puts it into the game as a 32bit file. Even if I untick the top left box when I import the sprite. I tried using transparency mask (I put the code a few messages above), it did seem like a promising solution but there was some problem I couldn't understand :/

Here are two videos I wanted to share (disregard graphics, sorry for the mixed walking view^^):
https://streamable.com/4vs8ht
Here, I have cut walkable areas, and as you can see at the end, it starts lagging when I click on the non walkable part. But for the rest (and the second video points it even more) it walks quite well.
https://streamable.com/ow9g6y
Here I just put a full walkable area and it's OK.

The idea is to feel a good handling of the character. that's why I think the second thing you suggest @eri0o is not appropriate here. For the first part : is this a suggestion to create a custom walking code? Or an explaination of how the ags engine works ? Because if ags doesn't calculate 40 times/second the path, I might leave it as is, otherwise I'll take @Khris code to divide this number by 8^^

@Khris I'll give the custom walking code a try, because it's true I feel this way is unelegant and suboptimal. It does work well on my computer but maybe on lower performance ones it would lag.



Crimson Wizard

#30
I made a mistake, CopyTransparencyMask does not work if sprites are of different color depth. Although I think that might be technically possible to do, but AGS does not support that at this time.

Drawing a 32-bit sprite over a 8-bit mask is still possible (after I fixed it to not cause memory corruption).
But the problem is that colors have to very closely match the game palette. This is necessary to make the engine convert 32-bit color to palette indexes correctly.

So when you draw your mask sprite you must have colors exactly as game palette colors from slots 0-15.

This works, sort of.

But then I met another problem. Color 0 (no area) cannot be achieved this way for some reason. Block color always gets converted to index 16, because index 0 serves a special meaning (transparency).

I tried to do this in two steps: choose certain different color to be the "non walkable" area, then try to remove it using RemoveWalkableArea(N) in script.
But calling RemoveWalkableArea causes room to completely restore its walkable area to original, overwriting anything that you painted over it.

It is apparent that this was not very well tested, and has a lot of limitations.

I added this ability because someone suggested, but I guess they never tried to work with this either.

eri0o

#31
@Crimson Wizard if the person is me, I just never used the masks drawing with loading a file, but I drew them in script. Also I needed more than it was possible by the number of walkable or whatever areas (I remember I had an issue on this at the time). In the end I just faked everything using regular dynamic sprites - which also gave me more bits.

@lafouine88 custom walking code is not as hard as it looks, it can be done, but you can also leverage walk straight I think. I have a module (controlz) that has keyboard walking, it may not be hard to use it as base for something that would move the player. If you are using ags4 it has also both exposed pathfinder but also a character can take a path (array of points) and move accordingly.

In your video it looks like you just need to make the character walk in the direction of the vector between the character and the mouse.

Btw do you have other solid characters or things that constantly change that you need to keep in check when moving the character or are other character/objects non-solid? I have a pathfinder plugin that is just the AGS plugin exposed but it gives the option to only generate the nodes once and then you calculate the path as you want.

AGS pathfinder in the engine (not in my plugin) will instead eat the entire walkable area mask every frame that you ask for a path (but only once per frame) to account to possible other solid objects and characters, that can also move, that's why it's not fast in your big map, it's not the actual pathfinding itself.

Here: https://www.adventuregamestudio.co.uk/forums/modules-plugins-tools/plugin-ags-pathfinder-experimental-0-1-0/

Crimson Wizard

#32
Quote from: Crimson Wizard on Wed 21/08/2024 23:34:48But then I met another problem. Color 0 (no area) cannot be achieved this way for some reason. Block color always gets converted to index 16, because index 0 serves a special meaning (transparency).

Alright, I found the way.

I had to do more fixing in the engine for this to work, not exactly related to room masks, but to DrawImage command when a sprite is of higher color depth than the surface. There will have to be a new 3.6.1 patch with this fix.
I might post a fixed 3.6.1 engine here if someone wants to give it a try:
https://www.dropbox.com/scl/fi/d3zjq91yrhddt9k3u7hrt/acwin-3.6.1-fixdraw32on8.zip?rlkey=yicgf48ixz7xzs2gnpfhrjweo&st=5egu0wqk&dl=0

Anyway, the solution is following:
1. Draw a bitmap in your paint software. This may be a 8-bit bitmap, or 32-bit bitmap. That does not matter in 3.6 because 3.6 converts everything to game's color depth, as been noted. So you might as well save it as 32-bit.
2. What is important: all the colors that you use in this bitmap MUST MATCH THE GAME PALETTE colors in slots 1-15. Check out your game palette in "Colours" tab in the editor. This must be done to make those colors match the walkable areas 1-15 when you will draw this sprite in script.
3. Another important thing: you cannot achieve "area" 0 on this sprite, unfortunately, because its treated as a "special palette color" by AGS when converting a sprite. Because of that the "walls" must be done as a transparent color instead: you should import this bitmap and tell to set the wall pixels as transparent pixels. They will become "magenta" after import, and that's fine.
4. If you followed these rules correctly, you will now be able to draw this 32-bit bitmap on a 8-bit room mask in 2 steps:
- clear the mask with color 0.
- draw the sprite on it.
The "clear" step is required because the sprite has "walls" as transparent color, so they won't be drawn.
Code: ags
  DrawingSurface *ds = GetDrawingSurfaceForWalkableArea();
  ds.Clear(0);
  ds.DrawImage(0, 0, SPRITE_NUMBER);
  ds.Release();


Quote from: eri0o on Thu 22/08/2024 00:15:28@Crimson Wizard if the person is me, I just never used the masks drawing with loading a file, but I drew them in script. Also I needed more than it was possible by the number of walkable or whatever areas (I remember I had an issue on this at the time). In the end I just faked everything using regular dynamic sprites - which also gave me more bits.

No, it was @Snarky originally who mentioned this, but maybe this was just an idea, and he did not need it for himself.

Crimson Wizard

#33
@lafouine88 What eri0o suggests is basically to try using player.WalkStraight instead of Room.ProcessClick(... eModeWalkto).

WalkStraight command should be much faster than regular Walk, because it does not search a path, but only tests the direct line in front of a character and stops if a wall is met. This works like "raytracing".
See https://adventuregamestudio.github.io/ags-manual/Character.html#characterwalkstraight

Other than that, you may replace AGS commands with your own that:
- Animates the character
- In rep exec moves the character into the direction pointed by the mouse by directly changing character.x,y properties with certain speed.
- Tests for a wall ahead.

That's not too hard to do, perhaps try that if WalkStraight did not solve the problem.

Snarky

Quote from: Crimson Wizard on Thu 22/08/2024 01:01:41No, it was @Snarky originally who mentioned this, but maybe this was just an idea, and he did not need it for himself.

I've no memory of this (and I'm not 100% sure exactly which feature you are referring to), but assuming I did it was probably either in response to some challenge another user had faced, or with the idea that it could be used for something interesting (possibly a module to edit walkable areas etc. in-game; in-game editing is something I've long seen as a promising avenue to explore). But no, I've never used it.

lafouine88

So, 'walkstraight' is much better yes, Thanks !! All my characters were already set to 'not solid' to help fluidity so this was a good first part  :grin:  :grin:

@Crimson Wizard Do I need to install the engine plugin you linked? I tried what you said, carefully following the steps but it still won't work. I'm not sure if it's my bmp colors that are not good or my coding (I just copied what you wrote) but something is wrong. I understand you tried it yourself, could you send me the .bmp you used ? If I can get it to work then it's just my image format that's not right :s

Crimson Wizard

Quote from: lafouine88 on Thu 22/08/2024 12:46:53@Crimson Wizard Do I need to install the engine plugin you linked? I tried what you said, carefully following the steps but it still won't work. I'm not sure if it's my bmp colors that are not good or my coding (I just copied what you wrote) but something is wrong. I understand you tried it yourself, could you send me the .bmp you used ? If I can get it to work then it's just my image format that's not right :s

That's not a plugin. I linked a patched engine executable, that should be used instead of the current one when compiling the game. If you like to use it, copy acwin.exe to the Editor's program files, overwriting existing acwin.exe (or rename existing one to have it as a backup).

Following my steps won't work without this patched engine, because there are bugs in the current official version that will prevent them from working correctly.

eri0o

Did the walk straight use work? Great to hear.

Shoot me a build of your game sometime - I am just curious and have no time for more than writing random bits of text in the forums, but still looks like you are making a nice thing to play.  :)

lafouine88

Quote from: eri0o on Thu 22/08/2024 16:08:12Shoot me a build of your game sometime - I am just curious and have no time for more than writing random bits of text in the forums, but still looks like you are making a nice thing to play.  :)
I will as soon as I'm done with the test map :)

@Crimson Wizard Sorry, I would love to close this thread but I still havent' managed to make things work. The plugin you sent gets deleted by antivirus and when it doesn't it still won't work. How did you make the colors the same as 8 bit palet ? You just need to copy RGB numbers right? Could you send me a bmp that works for you so I can try it ?

Thanks, almost there...I hope :)

Crimson Wizard

Quote from: lafouine88 on Fri 23/08/2024 13:12:04@Crimson Wizard Sorry, I would love to close this thread but I still havent' managed to make things work. The plugin you sent gets deleted by antivirus and when it doesn't it still won't work.

This is not a plugin!..
Can you tell what do you do, step by step, and what exactly happens as a result?

Quote from: lafouine88 on Fri 23/08/2024 13:12:04How did you make the colors the same as 8 bit palet ? You just need to copy RGB numbers right? Could you send me a bmp that works for you so I can try it ?

Yes, I copy RGB values from palette slots 1-15.

Here's an example of bitmap that worked for me:
https://www.dropbox.com/scl/fi/tc5fjtdx0gn8smuxgirq1/random.bmp?rlkey=qpnzknenm4osyekw9zhsgieq6&st=tkgqx7i5&dl=0
it has 2 colors: white and blue, should be imported telling that white color is transparent (for example - set transparent color from top-left pixel), then blue part becomes mask area 1.

SMF spam blocked by CleanTalk