![]() |
VOOZH | about |
An ender pearl cannon is a machine that fires an ender pearl to a precise position using explosions for fast player transportation. A 360 degree ender pearl cannon is an ender pearl cannon that can fire within a few blocks of any position in range, in any direction.
A typical ender pearl cannon consists of a few key components:
This article only covers the logic that governs the basket, since the other components are used in other devices and fit better in their own tutorial pages. This article assumes the reader already knows how to use redstone proficiently and only needs information about how to design a 360 cannon, not how to physically build one.
360 cannons are heavily reliant on linear algebra to work. An understanding of some basic concepts in linear algebra makes understanding 360 cannons much easier. If you are not familiar with linear algebra, it is recommended to skip this section. If you wish to become familiar with linear algebra, there are some fantastic introductory lectures by Gilbert Strang for free on YouTube.
The core game mechanic that makes it all possible is the fact that the velocity given by an explosion to an entity is always identical and is added to the entity's existing velocity. This allows us to treat velocities given by explosions as vectors:
Due to us wanting to hit any position in the 2-dimensional X-Z plane, it will be sufficient to use 2 different explosion positions (and their 2 opposites). Hitting any position in 3D space would require 3 different explosion positions (and their 3 opposites). This is a consequence of the behavior of bases that we will not get into in this article.
Now, assume that we have a basket with A explosions in one position and B explosions in another position. The velocity given to the ender pearl can be written as
where is the velocity given by each explosion in the first position and is the velocity given by each explosion in the second position. This formula can be expanded to
and finally written as a matrix multiplication.
This 3x2 matrix represents the transformation from explosion counts to ender pearl velocity. In general, we wish to do the opposite: given a target velocity , find the explosion counts that will produce it. This requires finding the inverse of the above matrix, which is not possible to do in general because it isn't square. However, it does have a Moore-Penrose pseudoinverse, which is a matrix such that is the solution for that gets closest to the target velocity (where distance is measured in the Euclidean sense). This means that you can compute the TNT-to-velocity matrix and its pseudoinverse once when first building a basket, and then it is easy to calculate the required TNT to achieve any target velocity by multiplying it by . It is usually recommended to calculate the pseudoinverse using a linear algebra package (it is usually called pinv; for example, pinv from the LinearAlgebra library for Julia, or numpy.linalg.pinv from the NumPy library for Python, or pinv from MATLAB) since the typical expression has significant roundoff error compared to the more numerically robust algorithms used in linear algebra packages. However, since we will need to turn the solution into integers anyway (since TNT comes in integer amounts), the roundoff error does not make a difference in the context of a TNT cannon.
One final technicality is that the pseudoinverse (and other methods for solving the linear least-squares problem) gives us real-valued TNT counts, but TNT can only be added in integer amounts. One immediate idea for turning the real-valued solution into an integer-valued solution is to round each TNT count, but that does not give the optimal counts in general. However, just checking the four combinations of rounding the two TNT counts (rounding each TNT count up and down) will find the optimal TNT counts in most practical cases if your basket is efficiently designed. More specifically, you can compute and check if the diagonal entries are the largest (in absolute value) in their row and column. If that condition is satisfied, then the optimal solution is guaranteed to be one of the four cases you get by rounding up or down. For more information on how this condition was derived and how to solve this problem in general if you don't meet the condition, see this document.
The most basic basket allowing 360 degree range has 4 possible explosion positions, but uses only 2 for any given shot. In the case of TNT it is easiest to align it into the corners of blocks.
Ideally the TNT should go as close to the ender pearl as possible. With this basket the pearl goes in the middle, and because of the ender pearl's collision checks with TNT, the closest the TNT can go is 0.79 blocks away from the center. Therefore the biggest block hitbox that can be used on the corners is 11 pixels (most notably flower pots, conduits, and walls with no middle column).
Lava is most commonly used to stop the explosions from destroying blocks. Water also works, but unlike lava it cannot be used in the Nether and changes the ender pearl's movement. It is common to hold up the TNT using fences under the lava because raycasts cannot hit the top part of the fences and obstruct the explosion (see Explosion#Edge cases for more about the exposure raycasts).
Each pair of TNT positions can reach only one out of the 4 quadrants of the world. With the pictured slime block layout, there is always one slime block that stays retracted and one that extends. To calculate TNT counts you need to first decide which quadrant the destination is in, and then use those two explosion positions for the rest.
The simple 4-corner basket has a major inefficiency: The two corners of TNT come from different sources. This means that, for example, shooting along a perfect diagonal uses at most half of the available TNT in the whole cannon. It would be more efficient if the total amount of TNT could be split in any ratio between the two corners. This is the concept of the "differential" basket. The name comes from the differential used in the drive of wheeled robots, specifically the "swerve" drive used commonly in FTC robotics.
In order to get the TNT in any ratio, the TNT enters the basket and is then separated using entity stack separation. This can be done using a trapdoor or fence gate activated by a pressure plate, but it's usually easier to use other TNT. Here is the required update order when using TNT:
There are many different possible ways to encode the TNT sources to produce TNT in the correct order. For ease of wiring, it is generally good to minimize the amount of TNT that needs to switch batches.
One way to encode a differential basket is to have a "variable bit". The strategy is based off of the assumption that one corner of the basket will always have an explosion count larger or equal to the other. By default, we assume that the early corner is always the smallest. This allows us to have 2 sides to the cannon: the "simple side" that has all its TNT on the late order, and the "complex side" that has some TNT in each order.
Notice that when the amount of explosions on each corner is less than half of the total TNT count, the simple side will be entirely late TNT and the complex side will be entirely early TNT. When more TNT is needed on the late corner, we can encode with the following strategy:
Now if we need more TNT on the early corner, we can swap the entire simple side to produce late TNT and use the same strategy:
(half the total TNT) - (required late TNT) early TNT, which is guaranteed to be less than half of the total TNT.This scheme requires 2 additional bits of information compared to a simple basket:
One important observation is that the "side swap bit" will only be on if the "variable bit" is also on. This allows both to be represented as a single ternary number: 0 if both corners have less than half the total TNT, 1 if more TNT is needed late, and 2 if more TNT is needed early. In total this means that encoding a cannon with 2^N TNT requires 2N + 1.5 bits of information.
Here is a table comparing the functionality of each bit in the encoding between a simple basket and a differential basket:
| Simple 4-corner basket | Differential basket | ||||
|---|---|---|---|---|---|
| Physical side | Bit in a normal cannon | Purpose | Physical side | Equivalent bit using variable bit strategy | Purpose |
| Side 1 | Bit 1 | Add 1 TNT to side 1 | Complex side | Bit 1 | Add 1 early TNT to complex side |
| Bit 2 | Add 2 TNT to side 1 | Bit 2 | Add 2 early TNT to complex side | ||
| Bit 3 | Add 4 TNT to side 1 | Bit 3 | Add 4 early TNT to complex side | ||
| Bit 4 | Add 8 TNT to side 1 | Bit 4 | Add 8 early TNT to complex side | ||
| Variable bit | Add all disabled TNT on the complex side as late TNT | ||||
| Side 2 | Bit 5 | Add 1 TNT to side 2 | Simple side | Bit 5 | Add 1 late TNT to simple side |
| Bit 6 | Add 2 TNT to side 2 | Bit 6 | Add 2 late TNT to simple side | ||
| Bit 7 | Add 4 TNT to side 2 | Bit 7 | Add 4 late TNT to simple side | ||
| Bit 8 | Add 8 TNT to side 2 | Bit 8 | Add 8 late TNT to simple side | ||
| Side swap bit | Change the order of the entire simple side from late to early | ||||
0.000390528979896351 in both X and Z.There is still another inefficiency in the differential basket. Acceleration is most efficient along each fixed velocity direction (e.g. putting all the TNT in one corner and shooting straight along the diagonal), but it is inefficient in other directions (e.g. shooting straight along a cardinal direction requires putting half the TNT in one corner and half in the other, which covers less distance than if the TNT was all in one position). It would be better if we could position every explosion in one place and be able to change freely where that place is, which would give a circular range instead of a square range.
However, putting every TNT in the same position is also inefficient. In order to have the same precision as a differential basket, there would have to be an entire cannon of TNT just to position the explosions accurately enough. This would end up doubling the amount of total TNT, where half is used to position the explosion and the other half explodes in that position. In the circle basket we find a better compromise.
The idea is to use the differential basket technology with 2 explosion positions, but choose the 2 positions freely from a grid of possible positions. In order for the explosion efficiency to be optimal the grid needs to be as small as possible. To achieve this we can use the same TNT-based TNT separation technology from the differential basket, but with multiple side acceleration TNT. Each one needs to give the main TNT the minimum possible motion to keep the grid small.
The size of the grid does not need to be very large to approximate a circle very closely. In the differential basket, 4 possible points gave a square. Here, a 3x3 grid gives an octagon, a 5x5 grid gives a 16-gon, a 7x7 grid gives a 32-gon, a 9x9 grid gives a 48-gon, and so on (these numbers are 8 times the totient sum function). See this desmos graph for a visualization of the true shape of the range.
Once the basket is set up, the encoding is done the same way as the differential basket. However, note that for most target destinations there are multiple pairs of explosion points that can reach it. You may decide if you want to consider all possible pairs; the most efficient (least required TNT) pair is always the two points whose velocities point closest to the target, but considering the other pairs gives you a chance to get higher accuracy at the cost of TNT efficiency.
The first step is to decide which explosion points will be used for the shot. If using a basic 4-corner basket, this means choosing which quadrant the destination is in. For more complicated baskets you may need to repeat this whole calculation (steps 1-5) for multiple pairs of points to pick the best one.
The second step is to write down the velocity given by each explosion point to the pearl. The easiest way to get the velocities is to use the carpet mod to print them using /log explosions full. This will let you click on the velocities in your chat and copy them directly, skipping this whole step. If you don't have the mod, the next best thing is to use the explosion entity influence calculator:
| Positions | |||
|---|---|---|---|
| Explosion X | 0.0 | Entity X | 1.0 |
| Explosion Y | 0.061250001192092896 | Entity Y | 0.0 |
| Explosion Z | 0.0 | Entity Z | 0.0
|
| Exposure | |||
| Entity width | 0.9800000190734863 | Entity height | 0.9800000190734863 |
| Layout | 3Γ3Γ3
|
Spacing | 0.33108108325802205 Γ 0.33108108325802205 Γ 0.33108108325802205
|
| Negative corner | 0.1621621665160441, 0, 0.1621621665160441
|
Positive corner | 0.8243243330320882, 0.6621621665160441, 0.8243243330320882
|
| Effect on the entity | |||
| Power | 4.0 | Exposure | 27 / 27 |
| Knockback multiplier | 1.0 | Eye height | 0.0
|
| Knockback resistance | 0.0 | Velocity X | 0.8731294800642211 blocks/tick |
| Speed | 0.8747657468328084 blocks/tick | Velocity Y | -0.053479181694784994 blocks/tick |
| Damage | 46.9375 | Velocity Z | 0.0 blocks/tick |
The easiest way to convert a target velocity into explosion counts is to use a matrix multiplication. We will call the matrix that transforms explosion counts into ender pearl velocity . It is always the same for the same 2 explosion points, and is computed by just using the explosion velocities as the columns; for two explosion velocities and , the matrix is given by:
Then the matrix that transforms ender pearl velocity into explosion counts is the pseudoinverse , which can be computed using a linear algebra library (it is usually called pinv; for example, pinv from the LinearAlgebra library for Julia, or numpy.linalg.pinv from the NumPy library for Python, or pinv from MATLAB). There is also a calculator below (see All in one calculator). Once the matrix is computed, you can just multiply it with the desired ender pearl velocity and it will output the TNT counts.
For example: here is the matrix for a 4-corner basket with a perfectly aligned pearl, being used to calculate the TNT counts to give the pearl velocity: From that calculation, you find that the TNT counts that get you closest to the target are 25 and 8 respectively.
| Ticking order | Acceleration, Drag, Position |
|---|---|
| Gravity | 0.03 (double) |
| Drag | 0.99 (float) |
| Terminal velocity | 2.97 b/t (59.4 m/s) |
| Maximum travel | 99 blocks per b/t of initial velocity |
{
"title": "Ender Pearl (entity)",
"rows": [
{
"field": "Acceleration, Drag, Position",
"label": "Ticking order"
},
{
"field": "0.03 ([https://en.wikipedia.org/wiki/Double-precision_floating-point_format double])",
"label": "Gravity"
},
{
"field": "0.99 ([https://en.wikipedia.org/wiki/Single-precision_floating-point_format float])",
"label": "Drag"
},
{
"field": "2.97 b/t (59.4 m/s)",
"label": "Terminal velocity"
},
{
"field": "99 blocks per b/t of initial velocity",
"label": "Maximum travel"
}
],
"invimages": [],
"images": []
}
There are multiple possible trajectories depending on how many ticks the pearl flies for. It is recommended to calculate the explosion counts for all of them and at the end select the one that best fits your needs (the one that gets closest to the destination, the one that arrives fastest, the one that uses the least explosions, etc).
The ender pearl's displacement refers to how far you want it to move from its starting position: .
The formula for the ender pearl's displacement after ticks starting with velocity is
with d = 0.9900000095367432 and a = [0.0, -0.03, 0.0].
Therefore, you can calculate the required velocity by inverting the above formula: You should now have a value for the initial velocity for each possible tick length . See the all in one calculator to have this done automatically.
Now that you have the initial velocity required to hit the target for every possible travel time, you can feed them into the matrix from step 3 and get explosion counts for each one. You will need to round the outputs of the matrix multiplication so that they represent a discrete amount of explosions.
Due to the limit for maximum calculations on a wiki page, no more than 30 ticks of data can be shown here.
| Computing the velocity to explosion count matrix | |||
|---|---|---|---|
| Explosion A velocity X | 0.6025927001541741 | Explosion B velocity X | 0.6025927001541741 |
| Explosion A velocity Y | 0.0 | Explosion B velocity Y | 0.0 |
| Explosion A velocity Z | 0.6025927001541741 | Explosion B velocity Z | -0.6025927001541741
|
| The result | |||
| X | Y | Z | |
| First position explosion count | 0.8297478543041549 | 0.0 | 0.8297478543041549 |
| Second position explosion count | 0.8297478543041549 | 0.0 | -0.8297478543041549 |
| Target displacement to hit | ||
|---|---|---|
| X | Y | Z |
| 1000 | -20 | 200 |
| Results | ||||||
|---|---|---|---|---|---|---|
| Starting velocity X | Starting velocity Y | Starting velocity Z | Explosions A | Explosions B | Distance to target | |
| 1 tick travel | 1010.1010003706325 | -20.17202000741265 | 202.0202000741265 | 1005.7549652813886 | 670.5033101875924 | 19.975765733398973 |
| 2 tick travel | 507.58843996476975 | -10.10669342248322 | 101.51768799295395 | 505.4045027444601 | 336.9363351629734 | 19.92306199553706 |
| 3 tick travel | 340.0898928337259 | -6.74159685353395 | 68.01797856674519 | 338.62663063795515 | 225.7510870919701 | 19.85485050997548 |
| 4 tick travel | 256.34484880777416 | -5.051520099708025 | 51.26896976155483 | 255.24190592636256 | 170.16127061757504 | 19.729643477618243 |
| 5 tick travel | 206.10120578463003 | -4.031421122512313 | 41.22024115692601 | 205.21443993453505 | 136.80962662302335 | 19.596297936871196 |
| 6 tick travel | 172.60826300659804 | -3.346285911360025 | 34.52165260131961 | 171.86560304740104 | 114.57706869826737 | 19.51000507890076 |
| 7 tick travel | 148.68714867159423 | -2.852537035790866 | 29.737429734318848 | 148.0474110956397 | 98.69827406375978 | 19.26452603092875 |
| 8 tick travel | 130.74842683590688 | -2.478385783525816 | 26.149685367181373 | 130.18587195210438 | 86.79058130140294 | 19.043033282815546 |
| 9 tick travel | 116.79796638178458 | -2.1839495398184394 | 23.359593276356915 | 116.29543439729856 | 77.53028959819905 | 19.131824680560374 |
| 10 tick travel | 105.6392886044749 | -1.9452987391950987 | 21.12785772089498 | 105.18476766556944 | 70.12317844371296 | 18.50146746273449 |
| 11 tick travel | 96.51099793360785 | -1.7472054798819905 | 19.30219958672157 | 96.09575214792552 | 64.06383476528369 | 18.132188974537808 |
| 12 tick travel | 88.90549729388843 | -1.5795178310183347 | 17.781099458777685 | 88.52297474344631 | 59.01531649563087 | 18.34581598583016 |
| 13 tick travel | 82.47137329931941 | -1.4352075365400265 | 16.49427465986388 | 82.11653404850642 | 54.74435603233761 | 17.642987067547622 |
| 14 tick travel | 76.95761636418577 | -1.3092544173985174 | 15.391523272837155 | 76.62650046490381 | 51.08433364326921 | 17.53309024324892 |
| 15 tick travel | 72.18015276964849 | -1.19797701289175 | 14.436030553929696 | 71.8695922647398 | 47.913061509826534 | 16.699877909524744 |
| 16 tick travel | 68.00092720536595 | -1.0986142314956253 | 13.60018544107319 | 67.70834813096924 | 45.13889875397949 | 16.655368677243537 |
| 17 tick travel | 64.31436794348656 | -1.0090546543427843 | 12.862873588697314 | 64.03765056599424 | 42.69176704399615 | 16.21997134918049 |
| 18 tick travel | 61.03836362131138 | -0.9276560708747374 | 12.207672724262277 | 60.77574149739416 | 40.517160998262774 | 16.91815529198205 |
| 19 tick travel | 58.108089461012106 | -0.8531220032350224 | 11.621617892202421 | 57.85807506079488 | 38.57205004052992 | 16.101964934628345 |
| 20 tick travel | 55.471685623434844 | -0.7844152733440057 | 11.09433712468697 | 55.23301454787855 | 36.822009698585696 | 14.84096881625181 |
| 21 tick travel | 53.0871703179611 | -0.7206962650947593 | 10.61743406359222 | 52.85875879782018 | 35.23917253188012 | 14.289209795472294 |
| 22 tick travel | 50.920194791498616 | -0.6612780241314646 | 10.184038958299723 | 50.70110684560629 | 33.80073789707086 | 14.310631873669498 |
| 23 tick travel | 48.94238397251924 | -0.6055930707286765 | 9.788476794503847 | 48.731805705575866 | 32.48787047038391 | 15.718671401636673 |
| 24 tick travel | 47.13009195408815 | -0.5531685094503587 | 9.42601839081763 | 46.92731120907691 | 31.284874139384605 | 12.884836744163795 |
| 25 tick travel | 45.46345616096729 | -0.5036071124903154 | 9.092691232193458 | 45.26784624108664 | 30.178564160724427 | 12.614054498471162 |
| 26 tick travel | 43.92566978584938 | -0.4565727683951777 | 8.785133957169876 | 43.73667630684302 | 29.157784204562017 | 11.979528107971083 |
| 27 tick travel | 42.50241590642985 | -0.41177916440407625 | 8.500483181285972 | 42.31954608367034 | 28.21303072244689 | 12.375765199106521 |
| 28 tick travel | 41.181422863107144 | -0.36898089400079925 | 8.236284572621429 | 41.00423671170012 | 27.336157807800085 | 11.343628568110589 |
| 29 tick travel | 39.952111627504244 | -0.32796640428232227 | 7.990422325500848 | 39.78021467961605 | 26.520143119744034 | 13.933132600526594 |
| 30 tick travel | 38.8053136972869 | -0.28855235385318556 | 7.761062739457379 | 38.638350933250784 | 25.758900622167193 | 12.099735162636794 |
Here are a few curated examples of 360 ender pearl cannons for various game versions and basket types. There is also a playlist on YouTube with all known 360 cannon videos on the platform.
| Name | Video/schematic link | Basket type | Game versions |
|---|---|---|---|
| 836 FTL v2 | On discord in TMC catalogue | Circle | 1.21.2+ |
| 836 FTL | On discord in TMC catalogue | Differential | 1.21.2+ |
| 360 FTL HEAVY | YouTube video | Simple 4-corner | 1.13.2~1.21.1 (version specific fixes in video description) |
| 360 FTL | YouTube video | Simple 4-corner | 1.12 |
| Cannon tutorials | |
|---|---|
| Related | |
| General Concepts |
|
| Combat | |
| Utility | |