I’m at my wits end on this. I want to delete the bottom poly tile (the one already placed) if it’s covered up with another tile. If there is a rock or tree there it will delete the dropped tile. the tree/rock code works perfectly. The issue is with the triggers on the poly tile overlapping a poly tile.
I have a trigger setup and track when it enters. It appears to always work in trigger message.enter. But what appears to be off is the trigger message.enter == false. Sometimes it works and other times it doesn’t work. Here’s 2 videos to show you how it works sometimes and sometimes it doesn’t.
almost working:
And here it is broken.
In the videos you can see my print statements showing how I’m tracking where it is at.
I know my if can be cleaned up to one line (like the two at the start, but I want to try and pinpoint the issue.
To me it’s not registering the “exit” event consistently.
if message_id == hash("trigger_response") then
if message.own_group == hash("top_tile") and message.other_group == hash("tile") and message.enter then
self.delete_me = true
elseif message.own_group == hash("top_tile") and message.other_group == hash("tile") and message.enter == false then
self.delete_me = false
elseif message.enter then
if message.own_group == hash("top_tile") and message.other_group == hash("bottom_tile") and self.dragging then
print("I will delete this tile: " , message.other_id)
self.delete_other_id = message.other_id
self.delete_me = false
self.delete_other = true
end
elseif message.enter == false then
print("---------------------message enter is false...leaving trigger---------------------")
if message.own_group == hash("top_tile") and message.other_group == hash("bottom_tile") and self.dragging then
print("+++++++++++++++++++Now I passed the next IF after existing trigger++++++++++++++++")
print("*********I will NOT delete this tile:******** " , message.other_id)
self.delete_me = false
self.delete_other_id = nil
self.delete_other = false
end
end
end
I did get one to work 100% but it’s really random on when and why the pieces do this (I think). It’s probably something boneheaded I’m doing but for the life of me I can’t figure it out.
One more odd thing. I’m currently changing the tiles that are being dragged to be in group “top_tile”. Then when released they get set it to “bottom_tile” group.
But I need to have “top_tile” in the mask to even make that work. I don’t understand why that is. I never need a condition where top_tile touches top_tile as it will only exist in the tiles being dragged.
I’ve tried various permutations of making the initial setting Top_tile and Bottom_tile and default.
Is it possible to change the mask during runtime? I see we can change a maskbit, but not a mask. If I can change the mask I think I can make this work based on my testing.
Edit: It still does it…just not as often. I think the issue may be I have a flag getting set from a different script somehow. I’ll play some more and come back with an update
@britzl I re-wrote the code a bit. I no longer call it “bottom_tile” when placed. instead I call it tile. And then I fixed the logic on the tile part to determine if it’s the tilemap (tile collision) or the polyomino tile collision. And then set flags differently.
To me this make no sense why the other way didn’t work. Well it worked sometimes but not reliably. Anyway this code here appears to fix it. To me this sounds like a bug…or if it’s by design I have no clue what it is that is breaking for me.
So this is no longer critical for me, but it would be nice to know why it behaves this way as I’ve spent a lot of time on this and still don’t know why it happens.
if message_id == hash("trigger_response") then
if message.own_group == hash("top_tile") and message.other_group == hash("tile") and message.enter then
if message.other_id == hash("/tilemap") then
self.delete_me = true
self.delete_other_id = nil
self.delete_other = false
else
self.delete_me = false
self.delete_other = true
self.delete_other_id = message.other_id
end
elseif message.own_group == hash("top_tile") and message.other_group == hash("tile") and message.enter == false then
self.delete_me = false
self.delete_other = false
self.delete_other_id = nil
end
end
You should not really rely on message order at all. I think it is better to find a solution that is not dependent upon the order of messages. Perhaps collect all physics messages in a list and then sort and handle them in a way that makes sense for your specific game?
My point on testing message order was to determine if that is the issue because it really doesn’t make sense what I’m seeing (to me). Where is the not message.enter message going? It’s not showing up at all. Which to me would be a bug.
If I tried your suggestion I don’t know how the table wouldn’t have the same issue. I record the trigger on enter into a table, but then the exit message never occurs, so making a table won’t work either.
Would there be a way to do this with kinematic collisions? Can I test for a collision occurring after I release the mouse button that doesn’t rely on messages? That just gave me an idea.
I continue to see very odd behavior with triggers. As I’m testing things here’s another example of things not working as I’d expect.
I have this tilemap currently with 2 collision groups (no_garden and tile). The items outlined in white are currently not assigned a group. But if I assign them to a group my trigger messages don’t get sent.
Here’s a video of the current operation. I’m setting flags as the trigger enters and exits so that I know if the polyomino is on the grid or not. If it’s not on the grid it gets reset. You can see the print statements properly refelecting the enter and exit trigger of the grid. Keep in mind I’m actually tracking LEAVING the no_garden area so I know the entire polynomial is on the grid.
Now I add a 3rd collision group called “garden_grid”. I assign the tiles that make up the useable garden to it (outlined in magenta).
In this video you can see it doesn’t capture the exit and entrance of the trigger. I didn’t change anything but add another collision group to the tilemap and add the proper group mask to the polyominos. Only after I release the polynomial does and it goes back to start does it register the trigger. But I can’t place the polyomino because the proper flags were never set due to the trigger never firing.
BUT if I remove garden_grid from teh mask of the polynomial it works again. So is the issue you can have a trigger with only one mask? it appears that is what’s going on to me. If I use more than one mask I get unreliable results at best or it never works at worst.
If this is the case, I think I can just add more trigger collisionobjects to the tiles and polynomials and enable and disable them as needed. And that may fix this. But is this how it is supposed to work? Or is this a bug?
Coming at this from a different angle, I’m wondering if it’s not easier overall to do this without physics?
You would need to convert your screen positions into your grid space.
After that, you can use your grid space coordinates to check items in your grid.
I need the collision objects for other things as well. But I’d really like to know why this won’t work? I’ll need to use collisions in the game for other things as well and if collisions aren’t an option any longer I’ll need to reconsider even making the game in defold. I hate to switch again though…I really like defold.
Another question: is it important that you get the exit message before the wnter message?
Once you get an enter message you automatically know you’ve exited any previous tile.
I think I found the issue, but not sure I understand why this is happening.
I found that the message.other_group changes upon leaving the collision. Why is this? Shouldn’t the exit message be for the group that it’s leaving?
{ --[[0000020D5B1D5070]]
own_group = hash: [top_tile],
enter = true,
other_group = hash: [tile],
other_id = hash: [/tilemap],
group = hash: [tile]
}
DEBUG:SCRIPT: ==================== Delete this one url: [main:/collection0/single_tile1#single_tile]
DEBUG:SCRIPT:
{ --[[0000020D5CC79AE0]]
own_group = hash: [top_tile],
enter = false,
other_group = hash: [no_garden],
other_id = hash: [/tilemap],
group = hash: [no_garden]
}
if message_id == hash("trigger_response") then
if message.other_id == hash("/tilemap") then
pprint(message)
end
if message.own_group == hash("top_tile") and message.other_group == hash("tile") and message.enter then
if message.other_id == hash("/tilemap") then
self.delete_me = true
self.delete_other_id = nil
self.delete_other = false
print("==================== Delete this one" , msg.url())
else
self.delete_me = false
self.delete_other = true
self.delete_other_id = message.other_id
print("==================== do not Delete this one" , msg.url())
print("================delete: " , self.delete_other_id)
end
elseif message.own_group == hash("top_tile") and message.other_group == hash("tile") and not message.enter then
print("++++++++++++++++++do not delete: " , self.delete_other_id)
self.delete_me = false
self.delete_other = false
self.delete_other_id = nil
end
end
Good news I resolved the primary issue. I still don’t know what’s wrong with the tilemap stuff or if I’m using it incorrectly.
But I was able to work around the issue by not changing the polyomino tile group name when I drag and drop it. It appears to not work correctly with collisions…maybe the name change of the collision group doesn’t take effect quick enough. But by redoing the logic so that I don’t need to change the collision group name appears to have resolved my issue…and only using one collision group for the tile map.
I think it’s worth confirming if the issue is with the name change though. I may do some testing later to see how quickly that name change takes effect to be used by collisions.
It depends on the message queue and game processing other stuff I suppose. So when working with collisions, better only rely on collision messages, which can affect your object visual update