Wood Lighting Explained

See also:
Micro Refined Wood Light Setups
Micro Improved Wood Light Setup (outdated, listed for comparison)
Wood Light ‘Visualize’ Map
A New Wood Light Standardization Idea with No Vanila Disparity (hey i’m noticing nobody is clicking through this link but if you have the patience to read through this very long analysis i’m sure you will be able to understand the beauty behind this idea so mind if you check it please?)


In this thread, I will go through:

  • The basic behavior of lava and fire
  • Detailed walkthrough on certain setups:
    • Analysis data from simulations
    • How certain blocks affect the wood light
    • What you should do differently on certain situations[wip]
  • Brief instructions on how to create & test a new setup[wip]

¹ The process that flammable blocks catch fire from lava is called Fire Spread in the wiki, but it is both unintuitive and easily confused with the process air adjacent to flammable blocks catches fire from another fire, which works fundamentally different. I stand by my term from previous posts and in this post I am going to continue calling it Fire Generation.


1. The Basics

1.1 Lava

Chunks consist of one subchunk per 16 blocks of height, each one being a 16×16×16=4096 block cube. Subchunks are distributed vertically starting at the lowest y level. Every chunk tick, some blocks are chosen at random from each subchunk in the chunk. The blocks at those positions are given a “random tick”. Subchunks that do not contain at least one block that can react to random ticks are skipped. All blocks are a possible target of a random tick, including air.
In Java Edition, the number of blocks chosen from each subchunk is specified by /gamerule random_tick_speed (defaults to 3), and one block can be chosen multiple times in one chunk tick.
https://minecraft.wiki/w/Tick#Random_tick

In net.minecraft.fluid.LavaFluid.randomTick():

   public void randomTick(World p_207186_1_, BlockPos pos, FluidState state, Random random) {
      if (p_207186_1_.getGameRules().getBoolean(GameRules.DO_FIRE_TICK)) {
         int i = random.nextInt(3);
         if (i > 0) { // 'Popping'
...
         } else { // 'Heating'
...
      }
   }

You can see there are actually two ways that fire generates¹ from lava when it get random ticked. The first (I didn’t find any documentations on this so I had to come up with a name, which I chose ‘Popping’) happens \frac{2}{3} of the time; The second(I call ‘Heating’) happens the rest \frac{1}{3} of the time.

// 'Popping'
   BlockPos blockpos = pos;

   for(int j = 0; j < i; ++j) {
      blockpos = blockpos.add(random.nextInt(3) - 1, 1, random.nextInt(3) - 1);
      if (!p_207186_1_.isBlockPresent(blockpos)) { // checks if block is within loaded chunks, world border, etc. , unimportant
         return;
      }

      BlockState blockstate = p_207186_1_.getBlockState(blockpos);
      if (blockstate.isAir()) {
         if (this.isSurroundingBlockFlammable(p_207186_1_, blockpos)) {
            p_207186_1_.setBlockState(blockpos, AbstractFireBlock.func_235326_a_(p_207186_1_, blockpos));
            return;
         }
      } else if (blockstate.getMaterial().blocksMovement()) {
         return;
      }
   }

When it chooses to pop, the spark either pops for up to 1 or 2 blocks high with equal probability. Starting from the lava position, for each y layer it pops up, it moves to a uniformly random block in the 3x3 region above it. Then it checks if the spark is within an air block, if yes it checks if the air block is adjacent to a flammable(catches fire from lava) block. If yes, then the air block is lit on fire. Note that in this process what the flammable blocks are does not matter. In other words, lava lights blocks on fire per air, not per flammable block. Finally, if the block the spark is in meets blocksMovement()(which is to say it has any solid hitbox, including slabs, glass; excluding water, lava, cobweb), the spark immediately dies.

This means that sparks popped have to first go through one of the blocks in the 3x3, not light anything on fire, not get blocked by a block that has a solid hitbox, win a 50% chance, and then get to choose a block in the 3x3 above that, which is a 5x5 region with inequal probability.

\color{Red}{Red} = \frac{1}{9}_{\text{(chance of chosen)}}/\text{pop} \space or
\space \frac{1}{9} \times \frac{2}{3}_{\text{(chance of popping)}} = \frac{2}{27} /\text{random ticked} or
\frac{2}{27} \times \frac{3}{4096}_{\text{(random tick speed)}} = \frac{1}{18342}/\text{tick} = 18 \times \color{White}{White}.
Assuming that no blocks with a solid hitbox or is air adjacent to a flammable block are present in the first layer:
\color{Pink}{Pink} = \frac{1}{2}_{\text{(popping to second layer)}} \times \frac{1}{9}_{\text{(chance of being chosen in the second layer)}}
\times \frac{9}{9}_{\text{(chance of a block being chosen in the first layer can choose the final block)}} = \frac{1}{18} /\text{pop} = 9 \times \color{White}{White}.
\color{Yellow}{Yellow} = \frac{1}{2}_{\text{(popping to second layer)}} \times \frac{1}{9}_{\text{(chance of being chosen in the second layer)}}
\times \frac{6}{9}_{\text{(chance of a block being chosen in the first layer can choose the final block)}} = \frac{1}{27} /\text{pop} = 6 \times \color{White}{White}.
\color{Lime}{Lime} = \frac{1}{2}_{\text{(popping to second layer)}} \times \frac{1}{9}_{\text{(chance of being chosen in the second layer)}}
\times \frac{4}{9}_{\text{(chance of a block being chosen in the first layer can choose the final block)}} = \frac{2}{81} /\text{pop} = 4 \times \color{White}{White}.
\color{Cyan}{Cyan} = \frac{1}{2}_{\text{(popping to second layer)}} \times \frac{1}{9}_{\text{(chance of being chosen in the second layer)}}
\times \frac{3}{9}_{\text{(chance of a block being chosen in the first layer can choose the final block)}} = \frac{1}{54} /\text{pop} = 3 \times \color{White}{White}.
\color{Blue}{Blue} = \frac{1}{2}_{\text{(popping to second layer)}} \times \frac{1}{9}_{\text{(chance of being chosen in the second layer)}}
\times \frac{2}{9}_{\text{(chance of a block being chosen in the first layer can choose the final block)}} = \frac{1}{81} /\text{pop} = 2 \times \color{White}{White}.
\color{White}{White} = \frac{1}{2}_{\text{(popping to second layer)}} \times \frac{1}{9}_{\text{(chance of being chosen in the second layer)}}
\times \frac{1}{9}_{\text{(chance of a block being chosen in the first layer can choose the final block)}} = \frac{1}{162} /\text{pop} = 1 \times \color{White}{White}.
This exact color palette will be reused later as well, I also define
\color{Green}{Green} = 5 \times \color{White}{White} and
\color{Magenta}{Magenta} = 2 \times \color{Red}{Red} = 36 \times \color{White}{White}.

This works the other way around as well, where you can calculate the probability of every air block adjacent to a flammable block catch fire from any certain lava block this way:


Now let’s see the case that lava generates fire through ‘heating’:

// 'Heating'
   for(int k = 0; k < 3; ++k) {
      BlockPos blockpos1 = pos.add(random.nextInt(3) - 1, 0, random.nextInt(3) - 1);
      if (!p_207186_1_.isBlockPresent(blockpos1)) { // checks if block is within loaded chunks, world border, etc. , unimportant
         return;
      }

      if (p_207186_1_.isAirBlock(blockpos1.up()) && this.getCanBlockBurn(p_207186_1_, blockpos1)) {
         p_207186_1_.setBlockState(blockpos1.up(), AbstractFireBlock.func_235326_a_(p_207186_1_, blockpos1));
      }
   }

You can see despite only happening \frac{1}{3} of the time, it tries to generate fire 3 times, making this actually a slightly more effective way of fire generation. In each attempt, the game chooses a uniformly random block in the 3x3 region at the same level of the lava block(the block chosen can be the lava itself, in which case the attempt is wasted). Then it checks if the block chosen is flammable(can catch fire from lava), and has air on top. If yes, then the air on top of the chosen block is lit on fire.
This drastically increases the chance of an air block above flammable blocks neighbour of lava, like above the two blocks at lava level outside a wood light portal, Which is why they are extra important. Note that this doesn’t generate fire on the side of a block, so it cannot directly light the portal.
Note that the air blocks that can be lit on fire here is actually the same blocks that can be lit on fire in the first iteration in popping. This means that for both of these two ways that fire generates from lava, the air block that gets lit on fire are either in the 3x3 1 block above or the 5x5 2 blocks above the lava random ticked, and not at any other level, including the same level as the lava block or anything below. This is partially why pouring lava from the top of the portal turns out to be so inefficient, the lava on top is not really doing anything.

1.2 Fire

1.2.1 Fire ticks

In net.minecraft.block.FireBlock.tick():

public void tick(BlockState state, ServerWorld worldIn, BlockPos pos, Random rand) {
   worldIn.getPendingBlockTicks().scheduleTick(pos, this, func_235495_a_(worldIn.rand));
...
}
...
private static int func_235495_a_(Random p_235495_0_) {
   return 30 + p_235495_0_.nextInt(10);
}

Fire runs on schedule ticks. Instead of updating every tick, it registers another scheduled update in uniformly 30~39 ticks every time it gets ticked.

1.2.2 Aging & Extinguish

   BlockState blockstate = worldIn.getBlockState(pos.down());
   boolean flag = blockstate.func_235714_a_(worldIn.func_230315_m_().func_241515_q_());
   int i = state.get(AGE);
   if (!flag && worldIn.isRaining() && this.canDie(worldIn, pos) && rand.nextFloat() < 0.2F + (float)i * 0.03F) {
      worldIn.removeBlock(pos, false); // raining extinguish, unimportant
   } else {
      int j = Math.min(15, i + rand.nextInt(3) / 2);
      if (i != j) {
         state = state.with(AGE, Integer.valueOf(j));
         worldIn.setBlockState(pos, state, 4);
      }
      ...

\frac{1}{3} of the time, the fire ticked increases its age by 1, with max age of 15. Note that a newly generated fire starts with age 0.

      if (!flag) { // block below is not infiniburn
         if (!this.areNeighborsFlammable(worldIn, pos)) {
            BlockPos blockpos = pos.down();
            if (!worldIn.getBlockState(blockpos).isSolidSide(worldIn, blockpos, Direction.UP) || i > 3) {
               worldIn.removeBlock(pos, false);
            }

            return;
         }

         if (i == 15 && rand.nextInt(4) == 0 && !this.canBurn(worldIn.getBlockState(pos.down()))) {
            worldIn.removeBlock(pos, false);
            return;
         }
      }
   ...
   }

There are two ways that fire can naturally extinguish. The first is when no flammable blocks are adjacent to the fire block, and the block below the fire does not have a solid upside surface, then the fire is considered floating and extinguishes immediately. The second is when the fire reaches the age of 15, the block below the fire cannot burn, then there is a \frac{1}{4} chance every fire tick it gets removed.

Note that the minimum time a fire block can reach age 15 is 15_{\text{(times that it has to age)}} \times 1_{\text{(times of fire ticks for it to age in the worst case)}} \times 30_{\text{(minimum time of fire tick)}}
= 450 \space \text{ticks} or 22.5 \space \text{seconds}; the average time it reaches that is
15_{\text{(times that it has to age)}} \times 3_{\text{(times of fire ticks for it to age in the average case)}} \times 34.5_{\text{(average time of fire tick)}}
= 1552.5 \space \text{ticks} or 77.63 \space \text{seconds}, so this has very minimal effect to the process of wood lighting.

Also note that so long as a fire block is not at max age(which basically doesn’t happen in the context of wood lighting portal), has any flammable block adjacent, it will not extinguish in any other way, even if it doesn’t look like it visually. for example, a fire has an oak plank both above it and below it, visually it looks like the block below it is burning, but if that block burns out, the fire immediately switches to be attached to the bottom of the top block. In other words, fire burns per fire, and it extinguishes only if the fire has nothing more to burn. This makes preserving early fire possible like this:

1.2.3 Burn Out Blocks

      boolean flag1 = worldIn.isBlockinHighHumidity(pos);
      int k = flag1 ? -50 : 0;
      this.catchOnFire(worldIn, pos.east(), 300 + k, rand, i);
      this.catchOnFire(worldIn, pos.west(), 300 + k, rand, i);
      this.catchOnFire(worldIn, pos.down(), 250 + k, rand, i);
      this.catchOnFire(worldIn, pos.up(), 250 + k, rand, i);
      this.catchOnFire(worldIn, pos.north(), 300 + k, rand, i);
      this.catchOnFire(worldIn, pos.south(), 300 + k, rand, i);
      BlockPos.Mutable blockpos$mutable = new BlockPos.Mutable();
......

   private void catchOnFire(World worldIn, BlockPos pos, int chance, Random random, int age) {
      int i = this.func_220274_q(worldIn.getBlockState(pos));
      if (random.nextInt(chance) < i) {
         ...
      }
   }

Every fire tick the fire tries to burn out all six blocks adjacent to it, with probability \frac{F}{B+k}. B is the basis factor of the side it tries to burn, with east, west, north and south being 300 and up, down being 250. k is the humidity factor, for some reason mojang decided that in humid biomes (including jungle, bamboo jungle, swamp, frozen peaks, and mushroom fields) blocks burn out even faster, presumably to control the fire. And finally, F is the flammablility of the block being burnt(the ‘burn out odds’ shown on wiki), which you can see that they really are odds, blocks with twice the burn odds really do burn out 2 times faster.
Here’s a table for the burn probability per fire tick in a non-humid biome:

Side Vertical
Oak Log(F = 5) \frac{1}{60} \frac{1}{50}
Oak Planks, Carpets(F = 20) \frac{1}{15} \frac{2}{25}
Leaves, Wool(F = 60) \frac{1}{5} \frac{6}{25}
Grass, TNT(F = 100) \frac{1}{3} \frac{2}{5}

Note that a block that can burn out can have multiple blocks of fire adjacent to it, in which case it burns out faster because every fire will try to burn it. This is why even overworld planks have the same burn odds as carpets, carpets seems to burn out faster simply because it spreads fire to more faces of itself.

      BlockState blockstate = worldIn.getBlockState(pos);
      if (random.nextInt(age + 10) < 5 && !worldIn.isRainingAt(pos)) {
         int j = Math.min(age + random.nextInt(5) / 4, 15);
         worldIn.setBlockState(pos, this.func_235494_a_(worldIn, pos, j), 3);
      } else {
         worldIn.removeBlock(pos, false);
      }

      Block block = blockstate.getBlock();
      if (block instanceof TNTBlock) {
         TNTBlock tntblock = (TNTBlock)block;
         TNTBlock.explode(worldIn, pos);
      }

If a block is decided to burn out from this process, it then decides whether it spawns another fire in its position with probability \frac{5}{A+10}, where A is the age of the fire that burnt it. If it does, then the fire spawned is chosen to be with age A with \frac{4}{5} chance or A+1 with \frac{1}{5} chance, capped at 15. Finally, if the block burnt is a tnt block, it explodes.

1.2.4 Spreading

      BlockPos.Mutable blockpos$mutable = new BlockPos.Mutable();

      for(int l = -1; l <= 1; ++l) {
         for(int i1 = -1; i1 <= 1; ++i1) {
            for(int j1 = -1; j1 <= 4; ++j1) {
               if (l != 0 || j1 != 0 || i1 != 0) {
                  int k1 = 100;
                  if (j1 > 1) {
                     k1 += (j1 - 1) * 100;
                  }

                  blockpos$mutable.func_239621_a_(pos, l, j1, i1);
                  int l1 = this.getNeighborEncouragement(worldIn, blockpos$mutable);
                  if (l1 > 0) {
                     int i2 = (l1 + 40 + worldIn.getDifficulty().getId() * 7) / (i + 30);
                     if (flag1) {
                        i2 /= 2;
                     }

                     if (i2 > 0 && rand.nextInt(k1) <= i2 && (!worldIn.isRaining() || !this.canDie(worldIn, blockpos$mutable))) {
                        int j2 = Math.min(15, i + rand.nextInt(5) / 4);
                        worldIn.setBlockState(blockpos$mutable, this.func_235494_a_(worldIn, blockpos$mutable, j2), 3);
                     }
                  }
               }
            }
         }
      }
......
   private int getNeighborEncouragement(IWorldReader worldIn, BlockPos pos) {
      if (!worldIn.isAirBlock(pos)) {
         return 0;
      } else {
         int i = 0;

         for(Direction direction : Direction.values()) {
            BlockState blockstate = worldIn.getBlockState(pos.offset(direction));
            i = Math.max(this.func_220275_r(blockstate), i);
         }

         return i;
      }
   }

Every fire block scans the entire 3x6x3 region to try light air blocks on fire, with up to 4 blocks above and 1 block below. Then it calculates l1 = getNeighborEncouragement() from the block scanned, which returns if the block is air and if yes the maximum value of the encouragement level of its adjacent blocks. So, having more flammable blocks around the air block does not speed up the spreading to it. If the block scanned has l1 > 0, which is to say it is air and has any block that spreads fire, then it calculates
i_2 = \lfloor\frac{l_1 + 40 + D \times 7}{A + 30}\rfloor, with D being the difficulty
(Peaceful = 0, Easy = 1, Normal = 2, Hard = 3), and A being the age of the ticked fire. If the fire block is in a humid biome, this factor i_2' = \lfloor \frac{i_2}{2} \rfloor gets further cut in half and rounded down.

If i2 > 0(which always happens in non humid biomes, minimum l_1 is 5 and maximum A is 15), then the scanned block has a p = \frac{i_2 + 1}{K_1} chance of lighting on fire, where K_1 is the space resistance factor that starts with 100 and adds another 100 for each layer higher above 2. Finally, the fire lit is chosen to be with age A with \frac{4}{5} chance or A+1 with \frac{1}{5} chance, capped at 15.

From here you can see that the correlation between the highest encouragement level of an air blocks’ adjacent flammable block l_1 and the probability that it ends up lighting on fire p is not at all linear, it has to pass through a heavy bias term (for difficulty hard that we use for wood lighting, that is 40 + 3 \times 7 = 61) a floor function that truncates decimal values, and another bias term (which affectively is equivillant to a bias of A + 30 in the first bias). In other words, the true odds is equivillant to be adding A + 91 to the encouragement value, which you can see pretty clearly why a block having encouragement of 60(like that of carpets) does not mean it spread 12 times faster than a block with encouragement of 5(like that of wood planks).
\color{Red}i_2 and Probability (\%) of lighting a block in the bottom 3 levels \color{Gray}p for l_1 = 5, x axis being A:


\color{Red}i_2 and Probability (\%) of lighting a block in the bottom 3 levels \color{Gray}p for l_1 = 60, x axis being A:

Now, fire does spread exponentially, so it is also wrong to say that carpets only spread fire max 1.6 times faster than wood planks, but certainly nowhere near 12 times faster.`

2 Likes

2. Wood Light Setups

2.1 Setup Principles & Very Rough Evaluations

Nether portals light if fire is placed anywhere inside its built portal frame. I have seriously considered the idea of building a 3x3 portal for better lighting odds, but ultimately decided that it is not worth it. In this post, we will be talking under the context of a 2x3 wood light portal.

A nether portal won’t light if there is any non-air block present inside the portal frame, so we can only ever light an air block inside the portal through a block adjacent that is on the side of it. As stated in the last chapter, an air block catches fire from lava so long as it is adjacent to a flammable block, and the speed it does that is constant(when it is random ticked), regardless of what the flammable block actually is or how many there are. An air block catches fire from another fire, the rate dictated by the block with the highest encouragement level adjacent to it, and more blocks that spread fire does not help the process as well. So in order to maximumly utilize the air blocks present in the portal frame, at least one flammable (and can spread fire for that matter) block needs to be present on either side of that air, but more does not help.

Of course, sometimes you cannot really fulfill this constraint, like wood lighting a magma portal or lighting with dead bush and hay blocks and stuff, but it is a good general rule of thumb and can even affect what you do in certain situations.

This only gives a very vague instruction on how a wood light setup should be like, but it is unfortunately the one of the two things that is simple in terms of wood light setups. The other thing that is simple is the process that lava generate fire directly inside the portal. This is mostly how a portal ends up being lit, and as we’ve shown in the last chapter, we can work out exactly how much a lava block contributes to a portal air block lighting. Unfortunately calculating that for the 5x5 second layer requires prior information on the structure of the 3x3 first layer, so such analysis can only be done after the setup is constructed.

For example, here are the heat maps of every block of lava can contribute to the total odds of directly lighting the portal after the setup is constructed for my Micro Improved Wood Light Setup for each layer, compared to where lava is actually placed in the setup:

The banners in the heat map just represents addition to the block below it, and the coloring conventions follow the definition from the last chapter. You can see there are two orange banners I placed in the construct map, which I also recommend you prioritize mining for slightly extra lighting chance if you have nothing better to do. (they are very kindly placed by the game if you are at a 2 deep lava pool.)

You can also see that very few blocks matter for directly lighting at the second layer, which the setup placed the two lava right where they should be, and anything above does not have any affect for that at all. You can visually see why placing lava on top for a lava waterfall is so inefficient. (But it doesn’t make them completely worthless, specifically lava from the third layer can light air on top of the third layer blocks, which will partially lead to some very interesting results as I will show later.)

But there are still a fair amount of portals that do not light from fire generation, but fire spread. Trying to work out analytically what every block does exactly in this context is just impossible in terms of computational efficiency, and the best way to verify is really to run simulations. There is a good first order estimate, that is to work out how much every air block catches on fire directly from lava.


For example, the air block in red stained glass takes chance to light \frac{2}{3} \times 4 \times \frac{1}{9} random ticks from the 4 blocks of lava popping in the 3x3 below it, \frac{1}{3} \times (\frac{4}{9} + \frac{2}{9}) \times \frac{1}{9} random ticks from the 2 blocks of lava popping in the 5x5 below it(the far lava will light the portal directly before it reaches it), and \frac{1}{3} \times 3 \times 4 \times \frac{1}{9} random ticks from the 4 blocks of lava through heating, adding up to \frac{62}{81} lights per random tick or ~1783.74 ticks per light.
As for the air block in blue stained glass, it takes chance to light \frac{1}{3} \times (\frac{2}{9} \times 3 + \frac{1}{9} \times 2) \times \frac{1}{9} random ticks from the 5 blocks of lava popping in the 5x5 below it, which is \frac{2}{81} lights per random tick, so in this sense the red air block is 31 times more important than the blue air block.

2.2 Data From Simulations

The Ninjabrain Simulator seems to be giving inaccurate results for setups that utilizes fire spread, which I encountered while simulating the wood light setups by doogile and Infume in their playoff match. So I made a datapack generator that simulates setups directly inside minecraft, which is slow and laggy and also crashes my game every time it hits ~5 minutes(which I suspect is related to the memory leak issue with nether portals in 1.16), but the results should be accurate.

link: WoodLight-Simulator-Datapack-Generator
It also has more features than the original simulator which I will explain later.


Let’s start with the original setup from pncakespoon:



Design Name Avg (s) Std Err Std Dev Samples
pncakespoon_2022_wood_light 16.5286 0.1173 12.8292 11958

Note that I used two different types of planks here, acacia planks for the two at lava level and oak for the rest. This of course is not to speed up the wood light itself, it’s because I configured in the datapack generator that acacia planks need to be replaced immediately upon burn out (otherwise the portal will be flooded); by contrast, oak planks are configured only to be replaced when they are turned into air, so if they are burnt into fire we keep it for it to spread.


But that isn’t the oldest setup, like this one I found from the demos from Ninjabrain’s simulator (named wood_back_front_lavaaugment2) which some people still do today with 2 planks added top front.



Design Name Avg (s) Std Err Std Dev Samples
pncakespoon_2022_wood_light 16.5286 0.1173 12.8292 11958
wood_back_front_lavaaugment2_fixed 16.3893 0.1134 13.0278 13197

Surprisingly, it actually turned out to be faster(within error range so doesn’t really mean anything) in the in game simulator. But it kind of cheated in order to achieve that, specifically, in order to not make the lava on the back flood everywhere(which makes the setup even worse), they mined a block back left(which is the same block that was mined in my micro improved setup, you can mine it in any setup as well), which makes a block of lava there can diretly light the portal. Combined with 2 extra lava that can light the air on top of the back top plank(which the Ninjabrain simulator handled poorly), it makes the setup barely better on paper. But obviously it takes longer for the lava to flow down so it is still just worse anyway.


Now here’s the micro improved setup I made:



Design Name Avg (s) Std Err Std Dev Samples
clearcoldwater_improved_wood_light_nf 14.0469 0.0946 10.9941 13496
pncakespoon_2022_wood_light 16.5286 0.1173 12.8292 11958
wood_back_front_lavaaugment2_fixed 16.3893 0.1134 13.0278 13197

I have already explained why it is good in the post I made about it. Note that there is a new type of wood plank here, birch planks, which is configured to do nothing when they burn out.


Fyroah’s wokelight (tested the last one):



Design Name Avg (s) Std Err Std Dev Samples
clearcoldwater_improved_wood_light_nf 14.0469 0.0946 10.9941 13496
fyroah_wokelight_fixed_2 15.5234 0.0924 11.0209 14241
pncakespoon_2022_wood_light 16.5286 0.1173 12.8292 11958

Despite being allowed to use 4 more planks, given a massive lava pool, taking 3+ seconds to setup, it is only 1 second faster on average than the pncakespoon setup.


doogile’s playoffs carpet light setup:



Note that white carpets are configured to be replaced with oak planks when they turn into air.

infume’s playoffs wood light setup:



Note that the top left plank is acacia because when it burns out lava can flood the portal.

Design Name Avg (s) Std Err Std Dev Samples
clearcoldwater_improved_wood_light_nf 14.0469 0.0946 10.9941 13496
doogile_carpet_light_playoffs 19.1589 0.1344 14.2557 11245
infume_wood_light_playoffs_fixed 21.0588 0.1672 15.9085 9057
pncakespoon_2022_wood_light 16.5286 0.1173 12.8292 11958

So Infume did get pretty unlucky for a 60 seconds light after setup complete, but that is also kind of his fault for making a sub-optimal setup that its PDF has such a long tail. doogile on the other hand definitely got pretty lucky, as his setup is still a lot worse than the og setup but got an insta-light.

So what has gone wrong for these two setups?

For doogile, his setup is built as intended, so it is just the setup itself being bad: the carpet on front covered an important air block that is above planks at lava level which has boosted chance of lighting through heating; in order to place the two carpets on the back, 3 blocks of important lava was sacrifised, and the lava remaining on the left has way less effect because there is no flammable block on the left anymore.

For Infume, he flooded his first portal, as a result 6 blocks of lava in range that can affect the wood light are turned into obsidian. This is not really a big issue as those blocks of lava are unimportant and probably has max .2 seconds affect in total on average. However, he turned a block of lava on the back of the portal into obsidian, which is a massive issue that losses him the chance of placing 3 blocks worth of important lava, despite this he just decided to place lava below the bottom planks level and lose himself another 1 important lava. He also built his portal back against a wall, which is especially worse for the setup he made that depends more on fire spread than direct lighting.


Carpet light that I believe is credit to edcr:


edcr carpets combined with my improvements:



The yellow carpet here has the same effect as birch planks, that is to not be replaced by anything when burnt out.

Design Name Avg (s) Std Err Std Dev Samples
clearcoldwater_improved_wood_light_nf 14.0469 0.0946 10.9941 13496
edcr_carpet_clearcoldwater_improved_wood_light 13.0375 0.0792 10.0045 15952
edcr_carpet_light 15.3544 0.1041 12.1261 13563
pncakespoon_2022_wood_light 16.5286 0.1173 12.8292 11958

It is only a 1.2 seconds improvement over the og setup and 1 second improvement over my improved setup, so I think it is not worth the potential extra explosive.


the important part that 99% of people care about is done :D
now i'm gonna procrastinate for another 5 hours to write the rest

1 Like

The important data part was out 2 days ago it looks like its not updated because edits don't count as activity please read

Important update: I was doing some calculations and found that the theoretical result just so happens to mismatch the actual results from the simulations by a factor of 2. Not too long after did I find this bug:

      if (randomTickSpeed > 0) {
         for(ChunkSection chunksection : chunkIn.getSections()) {
            if (chunksection != Chunk.EMPTY_SECTION && chunksection.needsRandomTickAny()) {
               int k = chunksection.getYLocation();

               for(int l = 0; l < randomTickSpeed; ++l) {
                  BlockPos blockpos1 = this.getBlockRandomPos(i, k, j, 15);
                  iprofiler.startSection("randomTick");
                  BlockState blockstate = chunksection.getBlockState(blockpos1.getX() - i, blockpos1.getY() - k, blockpos1.getZ() - j);
                  if (blockstate.ticksRandomly()) {
                     blockstate.randomTick(this, blockpos1, this.rand);
                  }

                  FluidState fluidstate = blockstate.getFluidState();
                  if (fluidstate.ticksRandomly()) {
                     fluidstate.randomTick(this, blockpos1, this.rand);
                  }

                  iprofiler.endSection();
               }
            }
         }
      }

Basically mojang somehow was able to mess this up so badly that lava gets random ticked both in blockstate.randomTick and fluidstate.randomTick, effectively doubling the random tick for lava. So all the numbers shown above in chapter 1.1 should be multiplied by 2.