[Solved] Check for diagonal neighbor on grid possible? Auto Tile now possible in GDevelop

I’m not sure if this will help but it’s all I have. When I played around with a classic pipe puzzle game, I found this technique to find the connected tiles. I made it work in Gdevelop. This is a simplified version that doesn’t check the pipe connectors or direction.

This would be more for the updating of broken rocks. BC there’s no reason to rescan the entire scene. It also demonstrates the ray cast. Use any or none of this project. It’s all I have on this at the moment.

Colliding with the blocks causes the adjacent blocks to be changed to red with the initial blocks that are collided with changing to red.

try it:

source:

1 Like

I did look into it but i have next to none knowledge how i could implement it into extension to find diagonal neighbor

If you could show me example of finding at least 1 diagonal neighbor i could do the rest myself

But until that moment i lack knowledge to do anything with it

Every time I read your code; I think I understand it a little more.

I think this works (I added the left-top)

As long as you remove the x and y checks below. Just leave the collision condition. It doesn’t seem to affect anything. It might be less efficient. Instead of removing them you might be able to add a check for the additional rows and columns. IDK

I don’t understand which texture is which. So, I tested it with the hue action and it turns the tiles which have another tile above and to the left.

The 16 would have to be set to a grid size. That bothers me a bit. IDK. It’s a start.

Edit: it’s tough because you can’t compare instances to instances. I’ve seen projects overcome that by adding a 2nd sprite in the same location as the target sprite. You can then use the extra sprite for reference or collisions testing. The only problem is you don’t want to cause a drop in the frame rate every time the tiles refresh. That’s why I thought the targeted update might be a good idea.

Have an initial complete conversion but then when a tile is changed or deleted, do a limited scan.

If i were to use it via events that would be awesome
But since it is for extension i would need to be able to either extension by size of one tile decide size of grid or let player set in extension that size of grid which you set to 16
If there is no other way i guess setting that size of grid will be last resort
And i am thankful for your input on this that is already some knowledge that i can find useful

BTW that is not my extension guy named Floki did it i just modified it to read images easily

So let me show you what i know and maybe that will help you help me
I mean i hope i understand it correctly

1st of all how this extension works

1 - here in setTile we have all you see in the center
2 - here it checks if from each tile there is another tile vertically or horizontally
Let’s take Y vertical layout as example
If there is one tile below origin tile then that tile below will get Y1 if there is one above then that tile that is above will get Y2
But if there are both then center tile will get Y3
That compare two numbers condition simply works as checking if something is on which side
This way you can change its image depending on how much neighbors it have
And next step would be add X to the mix but for now we are going with only Y
More or less it looks like this

3 - is simply adding to said variable 1 or 2 or 3 depending on number of colliding neighbors
We have X and Y variable so each X and each Y can be either 0 1 2 or 3

Now 2nd part

1 - In doStepPerEvents we have this in the center
2 - We check what is X and Y variable of said tile since it is 3 for X and Y we can already deduce it is center tile 5 of cross shaped tiles
3 - here depending on what X and Y is there we set proper frame to said tile

Here is how on spritesheet each tile is positioned and what number it have


So if you would use tool called sprite sheet slicer Sprite Sheet Slicer by isometric8
All your work as user who want to use this extension would be to download splice sheet slicer
Prepare all tiles on sprite sheet like you see on screenshot above
And add new animation to your sprite object and simply select them all as they were created/sliced out from sprite sheet
And that is all

So you can check that image/frame 13 is actually center tile which is full color square
Where image/frame 0 is single lone tile that have no neighbors
And so go on

Now what is the problem here?
Problem is that each tile which should have inner corners will have not because there is no way to check if there is diagonal neighbors to it
Example
Using above legend you can check that numbers of tiles match their image/frame

Only for first two i marked where corners are missing so i don’t spam whole screenshot but you can now clearly see the issue

Now imagine if i could check if there is any diagonal neighbor
Then i would be able to change that 1 tile which should have inner corners to match what it actually should be

I am trying to find a way to solve this problem for over half year
I sit everyday on gdevelop discord server solving other ppl problems in hope i will somehow have stroke of genius and find a solution but so far i found nothing

So if you have any idea that would get me closer to solution i would be in your debt

And my only problem is that i can find/check if there are any tiles in this position you see on the left on image below
But i addition to it i need to be able to find is there anything diagonally from center one which you see on right image indicated by ? marks

This is a long reply but I wanted to say everything at once.

I can see why it’s difficult. Most solutions require too many resources. I attempted using ray cast but it took way too long just to scan and I didn’t even get it to work. I was also trying to use an array, so I’m not sure what caused the most delay.

It would be 1 thing to make it for yourself but it’s another to make it easy for other people. You’re willing to use something that requires a complex setup or might have a bug but others won’t.

I didn’t test point is inside. But it’s more intense than a simple x,y check. Most of the work is done when the scene is started. Afterwards, it should just be minor changes to prevent lag. You wouldn’t need to check mire than a few pixels away from the tile but then the problem is that going through instances with a for each object prevents other instances from being checked. A workaround is to use a 2nd object but again. If it was your project a separate sprite would be easy to use.

I thought about the code from the pipe game bc that goes through all of the tiles without having to check diagonally. Each tile checks the 4 tiles around it. I still think something like that would work for quick updates.

The pipe game used a similar concept. I had 1 sprite with the unique pipe configurations. I rotated a few animations to create every combination of pipes.

My technique used binary. IDK if you know anything about binary. Each pipe opening was a bit position. So, 4 bits could represent any puzzle piece. I could also tell if one pipe could feed another pipe by checking certain bits. bit 1 was right, 2 was down, 4 was left, 8 was up. When combined, it represents every possible pipe configuration.

There’s only so many ways to detect nearby sprites. The x,y , ray cast, collision and storing the data in an array as a grid. That would also require a grid size property. You would use the position/ grid size as the arrays elements or column, row in a 2 dimensional array. Then it would be easy to check column 1, row-1. But again, that requires the grid size and processing time.

IDK if anything I said helped. If I think of something I’ll post it.

1 Like

Lets say i know something about it

This is my plan B i think i could use point inside object to check for diagonal adjacent tiles

+++++++
This is edited part
I remember i had problems with point inside object so i went with creating separate objects like 4 one pixel sprite objects and simply was creating them from each tile in all 4 directions
And each of that 1 pixel sprites was giving different value to colliding tile basically what you see on image above
Now i know i could go with 1 one pixel sprite and simply change it’s opacity to give different value to colliding tile depending on that
But this is what i am talking about below instead of point inside object
Explanation just to avoid confusion
+++++++

BUT that is no solution for extension so i could only make it as example
Or am i missing something?
Could i use 2 separate sprite objects for 1 extension?
So one would be for tiles and other that small object sprite which i would use to place inside other tiles?
Then i could simply change opacity of that small object depending on which side i am spawning it from origin tile
And so depending on the opacity it would add different amount of well value to variable of tile and this way i could find anything
I was able to do that with top down left right as you see from the link above but i am pretty sure i would be able to expand it to diagonal directions
But again i lack knowledge how to do it in extension
And about performance
For now i only care for it to work
A working AutoTile extension should exist for Gdevelop
And i can worry about solving performance problem later looking for other method of Auto Tille’ing

Option with determining grid size would also be not a problem if i could simply make it in extension so that user need to define what grid size he will be using
But again i have no idea how to do that in extension

So in short of it I perfectly understand what you are explaining to me yet i have no practical knowledge how to implement it into extension

Kinda like i know how keyboard works and when i press R i do not send R i send 82 which is then translated to R
But knowing that i still would not be able to program actual keyboard since i lack the knowledge

Ok, if you want to try the point is inside then put this anywhere in the setTile function outside of the for each tile. Since inside the for each you can’t reference more than 1 tile. I used the bounding box, so you wouldn’t need to know the tile size or where the points were and then added/subtracted 5 pixels just to be safe.

Again, I used random colors for testing. I enabled 1 event at a time.
red up-left, purple up-right, yellow down-left, cyan down-right (orange didn’t show well)
image

Edit: it seems to work and I didn’t notice any lag.

Cool idea, if some day it get into the extension store I will install it.

2 Likes

IDK what i’m doing wrong

I did try to enable them one at a time but none of them change color of tiles

I changed it so now you need to press Z to activate AutoTile and disabled it doing it’s thing at beginning of the scene

I copied my events to your newer project and it worked. It turns out that for your colors string, you have colons between the RGB numbers insted of semicolors. I changed them to semicolons and it seems to work fine. I usually use the color selecter to the right of the box.

image

2 Likes

1 - I once wasted half day with changing tint and recolorizer extension to change coins colors instead of making each coin animation separate color
Shoot some UFO’s

I ended up just recolorizing each coin animation in GIMP and importing it as separate animation

So i was aware abot semicolons instead of colons i simply forgot about it i even did not look carefully at your screenshot so 100% my fault

2 - I told you i only need to find one adjacent neighbor gd.games game build
Press Z to activate AutoTile
Q/E or mouse scroll to zoom in out
Any mouse button to drag camera
As soon as you move with WASD/arrows camera snaps to player
I wasted whole day to do it
If you care to check how it works here it is (everything with purple comments is stuff i added with your solution to AutoTile extension) Data package from May 3rd. - FileTransfer.io

3 - Originally this extension was made by Floki i then simplified it to read all tiles from singe animation imported as frames in exact order any spritesheet slicer would export them into separate images
(Floki went with making most tiles separate animation which if you had more tiles was time consuming to even add)
Floki also kinda abandon this extension not willing to go for that inner corners
Or more like moved to making it into work in conjunction with external map editor and/or something like Tiled or LDtl
So i gonna ask him will he publish it as his own extension or i will need to do it
No matter what will be his decision in both cases i would wish to list you as this extension creator since it is working only because your solution but i can’t make that decision for you
So i am asking do you want to be listed as creator of AutoTile or you don’t care?

4 - BIG THX i sit on gdevelop discord every day if you need anything and well if i can help feel free to @ZeroX4 with whatever you need i am really in your debt
Thx to you i can finally finish my MiniCraft clone

But 1st
Time to reduce lag or at least find a way to only update adjacent tiles when created/destroyed
Wish me luck

1 Like

@ZeroX4, could you share the extension in a website which doesn’t need an account to download?
Edit: created a temp email, that website asks to pay because it “expired”

Click it then click on GDCraft.zip and on far right you have download icon
Same goes for AutoTile

I paste here both extension and my project so you can test it and see how did i set it up
Actual image how to prepare tile is in GDcraft\assets\texture\terrain\TileStone\Stone.png
Then you just use spritesheet slicer on it Sprite Sheet Slicer by isometric8

Now if you wanna use it for your game you will have very bad time
It is far from perfect and it have issues listed above
I left it in state where it uses ObjectIsOnScreen extesion to update tiles
So if you zoom out too much it will lagspike on moving since update happens every few steps i think 20 or 50 pixels in any direction

Next thing is if you go to extension you have 2 other methods of updating tiles but which result in much more performance usage (it starts to lag faster) they are disabled but they don’t use ObjectIsOnScreen extension

But whatever works for you
I lost hope in this extension i believe only proper way to use it is to make it via events in game which is a lot of work but that is only sensible way
Extension is like half baked solution rabbit hole dead end you name it

You can’t have whole map build from tiles (well you can depend on map size) but that is eating a lot of performance which you can see from my post above
And you still need some performance for game itself
That’s why doing it via events looks like only proper way to do it

If you don’t understand how something works in AutoTile i will be more than happy to explain so do not be afraid to ask but if you really want to use in your project you will need to use a lot of tricks to reduce performance usage

For example 1st trick is to NOT have grass as tile or any object but just as color background you set in gdevelop
Then if you would dig grass with shovel to get dirt or use hoe to change grass into farmland you would simply need to spawn that kind of object in that grid cell
This way you save A LOT of performance instead of having grass as separate tiles which you simply destroy and replace with other tiles

I wish you good luck you will need it trust me

I have two questions:
1)Why does the original extension checks bottom/upper/left/right by position? Wouldn’t it be more performant if it were by bounding?. Nevermind, just read the topic
2) Wouldn’t it be better performant to delete all objects and which are outside of screen but store their position and important information? Then when the screen is on their position again, recreate them? It could be an extension, however what is important information to a game varies, so I guess it should be made per game. At least saving position should suffice? The problem with this approach may be the constant creation/deletation of objects…

ZeroX4, btw, thank you very much! Btw, my game is more Terraria-like, so I guess your suggestion won’t work, because I need players to be able to dig, remove and store the objects.

Btw, GDevelop tells me animation frames begin at 1, not 0, so the extension gets kinda buggy because it is defined as beginning at 0.

This is very powerful tool to rename multiple files at once Ant Renamer Portable (file renaming utility) | PortableApps.com
And do many many other stuff including numbering

So you for example have now file named Tile00.png
You can now add different numbers order to all files starting at whatever digit you want for example 01
So you would end up with file Tile0001.png
Now Ant Renamer have option to remove part of name of file either by what you determine
Or you can simply choose starting position and how many characters to remove

For example T i l e 00 01.png would be start from 5th position and remove 2 characters
And you end up with Tile01.png
And if you did all that batch renaming to your files you can set numbers as you wish

Sorry idk what you mean by animation frame starts from 1 not 0 so this is one method to change numbers

Other thing well just add any frame to tile then simply add rest
First one can be like fake frame just to fill the spot
I hope you know you can ctrl A when selecting file to select all?

About your question of deleting objects of screen
You are right it should depend on game
You and me are making something like minecraft clones so it would work for us
But what if someone makes idk game with teleports?
Or somehow move camera to different part of map?
Or don’t have player to check does his position changed because he have level builder/editor?

That is kinda issue that could be solved with making separate methods for updating and allowing ppl to choose where most would be just confused WTF it even is because they would not understand it
Or it would need to be broken into 2 separate extensions
So i picked lesser evil
While creating deleting at smaller scale would not be a problem it would all narrow down to how much zoomed out camera player have
Trust me i did think about many scenarios and more i think worse it looks

Sorry idk what you mean by animation frame starts from 1 not 0 so this is one method to change numbers
.

1) It is set to change the animation frame to 0 when there isn’t any object around.
image

2) I supposed that but it is true according to your animation of StoneTile 0, supposing you thought animation frames were referenced by name and not by number:

3) It is a number, not a name.
image

4) But frames begin at 1, there is no such thing as animation frame 0, according to Piskel.
image

However your game actually works when a tile isn’t around others, so I believe 1) is false and I didn’t understand the code enough. However, I believe it shouldn’t anyever reference the animation frame 0, so at least it is confusing.

4) Could also be false, then it would be GDevelop’s fault

This is very powerful tool to rename multiple files at once Ant Renamer Portable (file renaming utility) | PortableApps.com

I believe Nautilus encompasses everything you said, so I don’t need it, but thanks : )

Other thing well just add any frame to tile then simply add rest?

You and me are making something like minecraft clones

I don’t think I’m really doing any Minecraft-like game, maybe I am, but I guess the resemblance is a Dig and Create.

But what if someone makes idk game with teleports?

Recreate tiles based on player’s position?

Or somehow move camera to different part of map?

If there isn’t teleport in the game, set it recreate based on camera, and if player/falling object is out of camera, stop their movement.

Or don’t have player to check does his position changed because he have level builder/editor?

What? If you ask about level editor, make it focus on the camera as above.

Or it would need to be broken into 2 separate extensions

Seems like a tempting idea

While creating deleting at smaller scale would not be a problem it would all narrow down to how much zoomed out camera player have

In games like Mario Maker, I don’t believe the camera ever need to zoom out too much, in games like Terraria idk, but I know their zoom is can be hugely out.

You are confusing file naming by 3rd party program with what gdevelop takes as frame number 1

You could go with file names StoneA.png StoneB.png StoneC.png and so go on
And names would not matter
Only thing that matters is in which order you add them

For all you should care that first file could be called Stone_blablabla.png
Or Stone_999.png or even abortME.png

File name does not matter
It matters in what order you add them as frames

You even could have fully reverse file names
My method of preparing sprite sheet splits it into 48 files (0 is first 47 is last)

First frame could be named Stone_47.png 2nd could be Stone_46.png 3rd Stone_45.png

As long as image fits what you need and you added it in correct order it does not matter i hope you get it now

Also look my method is meant to work like this
You prepare sprite sheet then you cut it with sprite sheet slicer
And now you have all your files and all you need to do is this
After i click on Stone_9.png (just random file i could click any) i hold CTRL and press A to select all files
Then i hold CTRL and click on Stone.png to un select it (which is whole sprite sheet)
And then i just click open and all files are added in perfect order
2023-07-03_19_32_EBe0g5UU81_GDevelop

You are confusing file naming by 3rd party program with what gdevelop takes as frame number 1

So 4) is false.

You could go with file names StoneA.png StoneB.png StoneC.png and so go on
And names would not matter
Only thing that matters is in which order you add them

Yeah, but supposing 4) is true, as the tile images guide you, I supposed you implied frame 0 exists. Well, it little matters now as the problem is explained.

Also look my method is meant to work like this
You prepare sprite sheet then you cut it with sprite sheet slicer
And now you have all your files and all you need to do is this
After i click on Stone_9.png (just random file i could click any) i hold CTRL and press A to select all files
Then i hold CTRL and click on Stone.png to un select it (which is whole sprite sheet)
And then i just click open and all files are added in perfect order

Oh, I knew about Control + A, but I didn’t know GDevelop could import more than a frame at a time.

BTW, thank you very much! : )