(solved) Please help. I can't figure out my trigger collision issue

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

What does the physics debug show? Does it give you any clues?

Unfortunately, it doesn’t. :frowning:

My guess is maybe the messages are coming out of order since some collisions can occur at the same time so the last one is “winning”

See here it with the debugger.

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 :frowning:

@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

Is it possibly related to message order? the one came first and checked while the other one was not in final state

That’s what I’m guessing right now. It’s really weird though. And I don’t know how to test for message order.

Do you update “top_tile” to “title” right after it is put down?
Could you show a little bit code more?

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. :slight_smile:

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.

4 Likes

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.

It is important that I at least get the exit message. Doesn’t matter what order it comes in. Right now it doesn’t appear to be getting sent.

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

Also if I delete the no_garden collisionobject on my tile source the message exit works again.
image

So either I’m not using the tile source collisionobjects properly (very possible) or it is a bug IMO.

How many collision objects are you allowed to have in a tile source? Is there anything special I have to do if I’m allowed to use more than one?

Do I need to change my mask? to include the groups assigned in the tile source (tile & no_garden)?

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.

1 Like

That’s what I was thinking when asking you this (solved) Please help. I can't figure out my trigger collision issue - #9 by Chung_Xa =))

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

1 Like