putianyi888
Terrarian
It is (well?) known that developers have had 'fixed' the infinite-loop caused by teleporters connected to weighted pressure plates. However, the way the developers used is too naive so that another glitch arises. Let me show the glitch before explaining it.
The schematic is quite simple.
If the player stands on the left one and switches the switch on the middle teleporter, then the player will be teleported to the middle teleporter and trigger the weighted pressure plate. Although the blue wire wants to teleport the player to the right, the developers say "No" and leave the player on the middle teleporter. This is what has been described by the developers.
However, if the player switches the left switch at the begining, it will be teleported twice between the left two teleporters and end up on the left teleporter. This result is confusing and I didn't know why until I read the source code.
This thread is to explain why this glitch happens so that we can predict or even utilize this glitch. I think this is a new discovery since the pinned thread agrees that we didn't know this issue very well.
I would be happy if the pinned thread can add a reference to this thread.
When a wire is activated
A traversing process is called, running a BFS algorithm from the source of activation to traverse all tiles connected by the wire. FYI, the order of searching directions of the BFS algorithm is down-up-right-left.
Throughout this process, the game takes down the locations of the first teleporter tile and the last teleporter tile that are traversed. Then the game calls the teleportation process.
The teleportation process
Let's assume that the game has decided to teleport between teleporters A and B. Normally we believe that A and B are the same and hence interchangable, but they are not. Let A denote the first teleporter tile and B denote the last teleporter tile.
The teleportation fails in the first place if the teleportation zones of A and B overlap and the position of A is not lower than B. This prevents teleportation between two tiles of the same teleporter but also allows it when one of the tiles is halfbrick.
The teleportation has 4 steps:
Step 1: all players on A are teleported to B.
Step 2: all NPCs on A are teleported to B.
Step 3: all players on B are teleported to A.
Step 4: all NPCs on B are teleported to A.
You must have a bunch of questions now. Let me add some notes.
Note 1: every time a player or an NPC is teleported, the property field
Note 2: after all 4 steps of a teleportation (not including the failed case), the
Note 3: every time a player is teleported, the game checks if this teleportation triggers any weighted pressure plate(s). If so, a public static variable
Note 4: as long as
Note 5:
Now everything should be clear. BTW, all players and NPCs are teleported in the same order as how they stay in the player array and NPC array, if you are curious.
Let's check the glitch at the beginning. Assume that the player stands on the left teleporter and triggers the left switch.
So this glitch is a common issue for programmers, when different process share the same variable. In this case, the shared variables are
That's it. Hope you enjoy.
Applications
Now we can teleport NPCs on different teleporters together, which was impossible before. Showcase
The schematic is quite simple.
If the player stands on the left one and switches the switch on the middle teleporter, then the player will be teleported to the middle teleporter and trigger the weighted pressure plate. Although the blue wire wants to teleport the player to the right, the developers say "No" and leave the player on the middle teleporter. This is what has been described by the developers.
However, if the player switches the left switch at the begining, it will be teleported twice between the left two teleporters and end up on the left teleporter. This result is confusing and I didn't know why until I read the source code.
This thread is to explain why this glitch happens so that we can predict or even utilize this glitch. I think this is a new discovery since the pinned thread agrees that we didn't know this issue very well.
I would be happy if the pinned thread can add a reference to this thread.
When a wire is activated
A traversing process is called, running a BFS algorithm from the source of activation to traverse all tiles connected by the wire. FYI, the order of searching directions of the BFS algorithm is down-up-right-left.
Throughout this process, the game takes down the locations of the first teleporter tile and the last teleporter tile that are traversed. Then the game calls the teleportation process.
The teleportation process
Let's assume that the game has decided to teleport between teleporters A and B. Normally we believe that A and B are the same and hence interchangable, but they are not. Let A denote the first teleporter tile and B denote the last teleporter tile.
A teleporter tile is 1/3 of a teleporter. It can be either the left, middle or right tile. different tile has different teleportation zone highlighted below:
If the tile is (rectangular) halfbrick, then the teleportation zone will be half a tile lower. For triangular halfbricks, the zones remain the same.
If the tile is (rectangular) halfbrick, then the teleportation zone will be half a tile lower. For triangular halfbricks, the zones remain the same.
The teleportation fails in the first place if the teleportation zones of A and B overlap and the position of A is not lower than B. This prevents teleportation between two tiles of the same teleporter but also allows it when one of the tiles is halfbrick.
The teleportation has 4 steps:
Step 1: all players on A are teleported to B.
Step 2: all NPCs on A are teleported to B.
Step 3: all players on B are teleported to A.
Step 4: all NPCs on B are teleported to A.
You must have a bunch of questions now. Let me add some notes.
Note 1: every time a player or an NPC is teleported, the property field
teleporting
of the player or NPC is set to true
. As long as a player or an NPC has true teleporting, it will not be teleported.Note 2: after all 4 steps of a teleportation (not including the failed case), the
teleporting
of all players and NPCs are set to false
.Note 3: every time a player is teleported, the game checks if this teleportation triggers any weighted pressure plate(s). If so, a public static variable
blockPlayerTeleportationForOneIteration
is set to true
before the activation of the pressure plate.Note 4: as long as
blockPlayerTeleportationForOneIteration
is true
, Step 1 and/or Step 3 will be skipped.Note 5:
blockPlayerTeleportationForOneIteration
is set to false
at the end of each iteration. the concept of iterationNow everything should be clear. BTW, all players and NPCs are teleported in the same order as how they stay in the player array and NPC array, if you are curious.
Let's check the glitch at the beginning. Assume that the player stands on the left teleporter and triggers the left switch.
- The left teleporter is regarded as A and the middle teleporter is regarded as B, because the left teleporter is traversed first.
- Step 1 teleports the player to B and set the player's
teleporting
totrue
. - The player triggers the weighted pressure plate and set
blockPlayerTeleportationForOneIteration
totrue
. - Since the blue wire is activated, the associated wiring process is inserted.
- A teleportation between the middle teleporter and the right teleporter happens, but the player is not teleported because
blockPlayerTeleportationForOneIteration
istrue
. - At the end of the teleportation, the player's
teleporting
is set tofalse
. - At the end of the blue wire iteration,
blockPlayerTeleportationForOneIteration
is set tofalse
.
- A teleportation between the middle teleporter and the right teleporter happens, but the player is not teleported because
- Return to the A-B teleportation.
- Nothing happens in Step 2 since there is no NPC involved.
- In Step 3, the player is teleported back to A because both
blockPlayerTeleportationForOneIteration
andteleporting
arefalse
. - The player triggers the weighted pressure plate again, but it does't matter. (It does matter if an NPC is with the player at the beginning.)
- Nothing happens in Step 4 since there is no NPC involved.
- The left teleporter is regarded as B and the middle teleporter is regarded as A, because the middle teleporter is traversed first.
- Step 1 does nothing because there is no player on A.
- Nothing happens in Step 2 since there is no NPC involved.
- Step 3 teleports the player to A and set the player's
teleporting
totrue
. - The player triggers the weighted pressure plate and set
blockPlayerTeleportationForOneIteration
totrue
. - Since the blue wire is activated, the associated wiring process is inserted.
- A teleportation between the middle teleporter and the right teleporter happens, but the player is not teleported because
blockPlayerTeleportationForOneIteration
istrue
. - At the end of the teleportation, the player's
teleporting
is set tofalse
. - At the end of the blue wire iteration,
blockPlayerTeleportationForOneIteration
is set tofalse
.
- A teleportation between the middle teleporter and the right teleporter happens, but the player is not teleported because
- Return to the A-B teleportation.
- Nothing happens in Step 4 since there is no NPC involved.
So this glitch is a common issue for programmers, when different process share the same variable. In this case, the shared variables are
blockPlayerTeleportationForOneIteration
and teleporting
.That's it. Hope you enjoy.
Applications
Now we can teleport NPCs on different teleporters together, which was impossible before. Showcase
Last edited: