Duskers

Duskers

Not enough ratings
In depth look into the teleporter
By Weeroy the wisp
This guide is intended to provide some insight into the inner workings of the *teleport* module and some basic decompilation of Dusker's source code. Inspiration for this was the 2021-05-05 daily challenge, where a scrap was tucked away in a neat little corned, fiercely protected by a destroyed drone. Despite their brave attempts, my fellow Duskorians failed to retrieve this piece of space-gold. As an academic exercise I will end this guide with a calculation of my success chances on that day.
   
Award
Favorite
Favorited
Unfavorite
Introduction
During the making of this guide, my dear friend Ronny shed its mortal coil. He took three ship upgrades and a teleporter with him.

That was when I made up my mind; No more drones shall die for my curiousity. So I put on my programming-hat, and started the process of unearthing Dusker's many secrets. With a little help of vindicar's guide, the internal workings of my drones and their upgrades became transparent.

For this guide I used Visual Studio Code with the amazing ILSPY plugin.
Under the hood of the teleporter
With Assembly-CSharp.dll decompiled, our journey starts in the TeleporterUpgrade class that can be found under the global namespace (denoted as {}). Inside we find the function ExecuteCommand that contains the code executed when teleporting drones.

As is common in programming, the code generally resembled a pile of spaghetti that is miraculously held together by nothing more than pure power of will. Despite the this method taking up over 130 lines of code, only one line is really of interest to us, with most of the other lines being spend on the error-handling of edge-cases.


if (!room.PickSafeLocationForDrone(drone, out safePos))
{ SendConsoleResponseMessage($"No safe place found in room {room.Label} to teleport '{drone.DroneName}'", ConsoleMessageType.Warning);
}

This line can roughly be translated to: 'find a position in the room to teleport our drone to. Store this position in the safePos variable. Print an error message if no position can be found'.

So we head over to the place where the magic starts at the definition of the PickSafeLocationForDrone function found in the Room class once again under the global namespace.

The process, in simple terms
Here we once again have a bunch of code that roughly describes the teleporter's preferences as follows:

teleport to room center > teleport to room top left > teleport to room top right >
teleport to room bottom left> teleport to room bottom right > 'try 96 different random locations in the room'


Now well that doesn't explain a lot; if it tries to teleport to the left side of the room, shouldn't getting the scrap be easy? Well... in attempt to make the teleportation look more organic, the room positions are actually offset by 1.25 units, while the random positions in the room are only offset by 0.5 units. As a result you can actually reach deeper into the room using the 'random' locations than the predefined locations.

*Now I do have to concede here, you may have noticed the teleporter drone does not always teleport to the center of the room. I have not figured out why this is, perhaps some invisible target is there sometimes. experimentation with my dear Ronny revealed that this step was inconsistent, while the the other steps were consistent
*The effect of rotation (new)
A keen observer who goes by the name LB noticed that teleportation may also be affected by rotation of the drones. Though the effect is subtle, rotation does indeed effect the collision between various objects in Duskers. Moreover, the collision checking is done using a cube surrounding the robot for both the teleportee as well as other drones in the room.


Above shows the bounds using slime as a collider, notice that the box is axis aligned, and therefore the rotation affects whether there is a collision. The line responsible for this is:

`new Bounds(safePos, drone.GetComponent<Collider>().bounds.size);`

which computes the intersection bounds for the teleportee. Interestingly, for drones in the room that may block the teleportee, rather than using `bounds.size`, the bounds is used directly. This still yields the same axis-aligned behavior, since the bounds themselves are axis-aligned https://docs.unity3d.com/ScriptReference/Bounds.html
What where the odds during the 2021-05-05 daily challenge
Now to put my university fees to good use, I masterfully stole a screenshot from Matthtias's attempt (as I didn't record my own), and did some calculations on it.

First off we assume the room has the minimum height, which should be equal to 2 according to the DungeonGenerator class. We also (unfounded) assume that a drone has a total radius of 1. This leaves about a length of 1.5 units to the left of the destroyed drone that can be teleported into, and a length of 40 units to the right (28 squares * 1.5 per square - 2 drones). This roughly gives a chance of 41.5 / 1.5 = 0.036, or about 1 in 27 attempts should succeed.


By my own calculations I spend about 200 teleports to get this scrap, 100 of which were into the room. Using binomial formula, we find that the odds that it took at least this many teleports to be 2.6%. While feasible, especially since my strategy was not 100% optimal at the time, there is a good chance that this final calculation is still somewhat off, (or I overestimated the number of teleports made :D)
2 Comments
Chromblitz11 Jul 5, 2022 @ 4:13am 
Interestingly, the teleportation error where the drone can't teleport into a room if there's no safe location for it also seems to apply to teleportable objects that don't have any collision, like sensors. It might just be a bug on my end (I notice quite a few when I play, like ship upgrades disappearing sometimes when they cease functioning), but for rooms where a drone can't teleport, I've noticed that I can't port a sensor to that location either. I just noticed it the other day, so I'll see if I can replicate it, but it might be worth testing to see if the game first runs a check to see if it can place a drone down, then only moves the sensor to that room after a success, disregarding the sensor's lack of collision.
Weeroy the wisp  [author] May 8, 2021 @ 9:49am 
Feel free to add suggestions for improvements in the comments. I made this guide as an excuse to try out decompiling, and to practice using draw.io