How to call an event on all tiles of one type ? call or emit?

Hello,
I'd like to call an event all all tiles named "star" for instance.
I guess tell "star" to call "myEvent" does not work, but emit "myEvent" works.

Alas, I'm afraid emit is a costly function that calls myEvent on all items, not just the star tiles.

Any idea ?

1 Like

One might hope that the event listeners are stored in a hashmap or some sort of constant-time lookup structure and thus that wouldn't really be a concern. No idea though.

Do you have a code example of swapping one tile with another using emit? I can't think of a way to do it without using tell to capture all instances of a certain tile, since there's no way to loop through every tile in a room.

Edit: I actually figured out a way to do it, but it requires both tiles being swapped to be a Sprite tile, since they each need to have a function that does the swapping and can be emitted from the Player script. Since one of the tiles being swapped needs to be passable and you can't have a script on a regular World tile, it might not be possible to swap back and forth between a solid and passable tile.

Follow-up to this: Found some information regarding the behavior of emit here.

Hello everyone.
I'm still having problems using tell + call insetad of emit.

Are there specific places the code must be placed for this to work?

I've tried using tile names and tileIDs. The functionality I'm looking for never works.

Yes, I'm struggling to understand the value/use case of either of these listed in the tell docs given call doesn't seem to work.

tell tileId to 
  ... 
end

tell "tileName" to
  ...
end

Related quote in emit docs:

You should use call with tell instead of emit if you already know exactly which tile(s) you want to handle the event.

@shaun Since I've seen your name on quite a few threads related to emit and performance concens, maybe you could clarify how one would use these without call (or using call properly).

From my testing there does seem to be a difference between doing this from player versus game, but I'm not sure exactly what the difference is (or why).

Specific error I'm seeing:

Error: Fatal: Tried to swap tile on a tile prototype in the "confirm" event callback of "player", use tell x,y to target a specific instance of a tile

Your error is down to the difference between a tile prototype and a tile instance.

When you create a tile down in the tile list in the editor, that's the prototype of the tile. It's an abstract existence, ready to be used in the game but not actually in the game.

When you actually place (or swap) a tile into a room, that creates an instance of the tile. Each instance exists in a room at specific coordinates and you can have multiple instances of the same tile (prototype). One tile exists in the tile list, but it can be instantiated or placed multiple times into rooms. Each is a separate instance of the tile.

When you call tell with a tile id or tile name, that targets the prototype of the tile.

If you instead call tell with coordinates e.g. tell 12,7 to that targets a specific instance of a tile - whichever is at those coordinates in the current room.

A lot of things can only be done to instances of tiles. Like swap in your case, it only makes sense this should happen to an actual instance of a tile placed in a room, not the abstract prototype that only lives in your tile list.

What emit does is call an event on every tile instance in the current room by looping through all of the rooms coordinates. An event called on a tile with emit is practically equivalent to using tell with coordinates.

Using tell with coordinates obviously only makes sense if you know what coordinates the tile instance you want to call an event on is placed at. If instead you want to call an event on all instances of a tile in a room, like in the posts above, you will want to emit an event.

If you think that sounds like tell is generally much more useful using coordinates rather than tile id or name, then I agree! Most of the time I use tell it is with coordinates. There are use cases for using tell with a tile name to call an event on the tile prototype (and some would be equivalent with id too, although I think name is definitely more readable in your code!), for example I have used it to avoid duplicating the same code across multiple tiles.

(Apologies if I laboured any points there, I figure it's better to overexplain than underexplain!)

1 Like

I understand.

(Apologies if I laboured any points there, I figure it's better to overexplain than underexplain!)

No worries.

A lot of things can only be done to instances of tiles.

To clarify then, a defined customEvent can work when called via tell 12,7 but not work with tell tileId or tell "tileName" because the event contains actions that can't be performed on a tile prototype?

And that's likely why others here have reported not being able to use call successfully?

Calling the custom event should work in either case, but if calling the event on a tile prototype it will throw an error on any command that doesn't make sense not on a tile instance. Subtly different to what you said above perhaps, but effectively the same :slight_smile: