[Question]
  [
Minecraft has a fairly unique lighting system. Each block's light value is either one less than the brightest one surrounding it, or it is a light source itself. Your task is to write a method that takes in a 2D array of light source values, and then returns a 2D array with spread out lighting, where 0 is the minimum value.
**Examples**
```
Input1 = [
         [0, 0, 4, 0], 
         [0, 0, 0, 0], 
         [0, 2, 0, 0], 
         [0, 0, 0, 0]
        ]
Output1 = [
         [2, 3, 4, 3], 
         [1, 2, 3, 2], 
         [1, 2, 2, 1], 
         [0, 1, 1, 0]
        ]
Input2 = [
         [2, 0, 0, 3], 
         [0, 0, 0, 0], 
         [0, 0, 0, 0], 
         [0, 0, 0, 0]
        ]
Output2 = [
         [2, 1, 2, 3], 
         [1, 0, 1, 2], 
         [0, 0, 0, 1], 
         [0, 0, 0, 0]
        ]
```
**Notes**
You can assume:
1. Input will not be empty
2. The y axis will be the same length
3. All numbers will be integers; no nulls, doubles, or floats
4. All numbers will be between 0 and 15 (inclusive).
Rules:
1. Return a 2D array following the above mechanics
2. No value can be less than 0
3. If there are two highest neighbors, just subtract one from them
4. Light sources do not change, unless a surrounding block is brighter than it.
5. No standard loopholes
6. This is code golf, so shortest code wins!
  
[Answer]
# [BQN](https://mlochbaum.github.io/BQN/), 21 bytes[SBCS](https://github.com/mlochbaum/BQN/blob/master/commentary/sbcs.bqn)
```
(⊢⌈¯1+«⌈»⌈«˘⌈»˘)⍟(≠⥊)
```
[Run online!](https://mlochbaum.github.io/BQN/try.html#code=RiDihpAgKOKKouKMiMKvMSvCq+KMiMK74oyIwqvLmOKMiMK7y5gp4o2fKOKJoOKliikKCj7ii4jin5xGwqgg4p+oCjTigL804qWK4p+oMCwwLDQsMCwwLDAsMCwwLDAsMiwwLDAsMCwwLDAsMOKfqQo04oC/NOKliuKfqDIsMCwwLDMsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDDin6kK4p+p)
`«⌈»⌈«˘⌈»˘` computes the element-wise maximum of:
* `«` Push in 0's from the bottom
* `»` Push in 0's from the top
* `«˘` Push in 0's from right
* `»˘` Push in 0's from the left
Then substract 1 from this / add ¯1 (`¯1+`) and take the maximum with the input matrix (`⊢`).
`≠⥊` gives the number of element in the flattened matrix and `(...)⍟` iterates the function on the left that many times.
[Answer]
# [R >=4.1](https://www.r-project.org/), ~~377~~ ~~215~~ ~~182~~ 150 bytes
```
f=\(m,w=T,n=1:ncol(m),z=Reduce(pmax,Map(\(j){o=outer(m[p][j]-abs(n-i[j,1]),abs(n-i[j,2]),`-`);o*(o>0)},1:nrow(i<-which(p<-m>1,a=T)))))`if`(w,f(z,F),z)
```
I sure learned a lot.
Thanks to [June Choe](https://twitter.com/yjunechoe/status/1507344665514848258?s=20&t=27rn8zNl-36D-3ppsslAjw) for the `outer()` tip which enabled a significant optimisation, and then some cleanup.
Also thanks to [@pajonk](https://codegolf.stackexchange.com/users/55372/pajonk) for some additional savings, use of `Map`, and for introducing me to ['attempt this online'](https://ato.pxeger.com/run?1=nZHPSsNAEMbxmqfY44zMQhI9iGZ705uXEk9pINs0oRvcbEg3pFZ8DS9e6sGH0qdxTVpFxD84fAwzfDDzY-bhsd1unzpb8pPn-1LMQFMvYqpFcFrn5ho00kZMi0WXF9BouaZL2cAMKrw1wnS2aEEnTZpUKZfzFdRcJRUFKdJHF7ou4xmemUMwEx_vyI1uTQ8q4v1S5UtoIq4nAUkR41tkqsygpxI2dOG240j3ciC0LVY2YBFnWtpWrSEHn5jT8ZA99jVG3__JD3_xd8JhjdP8xsEzweLp1Tl63gAVfoJ6n3j0b6g_-t9BlTDeCvdVuLvi_tev)
[Answer]
# JavaScript (ES6), ~~99 94~~ 93 bytes
Modifies the input matrix in-place.
```
m=>{for(d=64;d--;m.map((r,y)=>r.map((v,x)=>r[x]=(q=~-(m[y+D%2]||0)[x+~-D%2])>v?q:v)))D=d%4-1}
```
[Try it online!](https://tio.run/##rY1dC4IwFIbv9yt2I@3gJsusi2J2479YXkhqKG4rC1H6@OtLiyiCICI4nMPD4X2fMmmS/boutgemTZrZXFglwmNuapKKWbBIGVsoTyVbQmragQjrOzS0HUC2sSA7cWFEyc6NHD8@nTjI1r2wASBslrt5AwCRSJ2Ajc82JwoLLBHGklPcT9DvmD6Zv7L/xo8/igGtjd6bKvMqsyHKK02hyWilR4BdfLsIvbj8R3by0cX/5fqie/qDC@wV "JavaScript (Node.js) – Try It Online")
### Commented
```
m => {                   // m[] = input matrix
  for(                   // repeat 64 times,
    d = 64;              // using d as a counter:
    d--;                 //
    m.map((r, y) =>      //   for each row r[] at position y in m[]:
      r.map((v, x) =>    //     for each value v at position x in r[]:
        r[x] = (         //       update r[x]:
          q =            //         q is the value of the neighbor cell
          ~-(            //         located at m[y + dy][x + dx],
            m[y + D % 2] //         using D as the current direction
            || 0         //         (-1 = North, 0 = West, 1 = South,
          )[x + ~-D % 2] //         2 = East), minus 1
        ) > v ? q        //         keep the maximum of q and the
              : v        //         current value v
      )                  //     end of inner map()
    )                    //   end of outer map()
  ) D = d % 4 - 1        //   set D to (d mod 4) - 1
}                        // implicit end of for()
```
[Answer]
# [MATL](https://github.com/lmendo/MATL), 24 bytes
```
Xz,G@+&fh]&1ZP-TYaX>GZye
```
[Try it online!](https://tio.run/##y00syfn/P6JKx91BWy0tI1bNMCpANyQyMcLOPaoy9f//aAMFAwUTBQNrBQMIBDGMYAwwjAUA) Or [verify all test cases](https://tio.run/##y00syfmf8D@iSsfdQVstLSNWzTAqQDckMjHCzj2qMvW/QXKES1RFyP9oAwUDBRMFA2sFAwgEMYxgDDCM5YoGCygYoyhCZcQCAA).
### Explanation
```
Xz       % Implicit input. Get nonzeros as a column vector (*)
,        % Do twice
  G      %   Push input
  @      %   Push iteration index: 0 or 1
  +      %   Add, element-wise
  &f     %   Two-output find: gives row and column indices of nonzeros
  h      %   Concatenate horizontally. Gives a 2-row matrix where each
         %   row contains the coordinates of nonzeros (first iteration)
         %   or of all entries (second iteration)
]        % End
&1ZP     % Cityblock distance between rows
-        % Subtract from (*), element-wise with broadcast
TYa      % Extend with two rows of zeros. This serves two purposes:
         % making sure that the maximum of each row is at least 0; and
         % making sure that each column has more than 1 entry, so that
         % the following function (maximum) operates along the first
         % dimension (compute maximum of each column)
X>       % Maximum along the first (non-singleton) dimension (**)
GZy      % Push input. Size
e        % Reshape (**) with the specified size. Implicit display
```
[Answer]
# C(gcc) 230 227 220 172 171 128 97 bytes
smaller thanks to @Muskovets an @engineergaming, and now @ceilingcat
```
i,j;f(n,x,y)int*n;{for(i=x*y;i--;)for(j=x*y;j--;n[j]=fmax(n[j],n[i]-abs(i%x-j%x)-abs(i/x-j/x)));}
```
[Try it Online!](https://tio.run/##hVBBboMwELzzilWqSLZjSppGvRj6kZSDYwIYEacC2hpFfL10bSKFpJUqWaud8eysPSoslBoftFH1R3aAuO0yfXosX4MbqtZ75EbNK5ETwy3vqTYdM@KcnxqiE8t6ocNQUAcrDyuEZlelSX6UlriOm51OQ7lviV7asFpaOoEIQWQppWIY0RWOUhviGtkUioMqZcOYA58UzgHAe4OXOVnsD4U2b2ZBRYBsxLC4qS@ddSUksBUXojzoouzmjGya3dNLitR5zQHP1te7s/lNDs6BRcG/q55vVm38qj@X3NvjWE5wiE/m/GI5/RHTBZ9Mn6wF9PF0h91qNUUzk1gnsbF3weaquAa4zDgsuH@ihRX0zItTKrxuCObaKWfHBsP4rfJaFu0Y1scf)
[Answer]
# [JavaScript (Node.js)](https://nodejs.org), ~~100~~ ~~98~~ 94 bytes
```
A=Math.abs
f=(a,i,j)=>a.map((r,y)=>r.map((c,x)=>1/i?t=t>(u=c-A(i-y)-A(j-x))?t:u:f(t=a,y,x)|t))
```
[Try it online!](https://tio.run/##dY3BCoJAEIbvPoXHWZg1i07CKj5ATyAepk1rxVzRMRR6dxsIu1TDMD/fxw/T0INGO7iedecv1brm5kR8i@g8BrUBQoeNMilFd@oBBlwEhjdYnAX2O5ex4RQmY3UOTi9KotGzUhknU1IDG8JFuk9WarW@G31bRa2/Qg1FEG5TxBjKHuWWGH75@Jc//PFb/2NL@fwC "JavaScript (Node.js) – Try It Online")
-4 byte from ophact
[Answer]
# [Python 3](https://docs.python.org/3/) with [numpy](https://numpy.org/), 93 bytes
```
f=lambda a,n=0:f(rot90(fmax(a,r_[a[1:],a[-1:]]-1)),n+1)if n<len(a)*4else a
from numpy import*
```
[Try it online!](https://tio.run/##VcXBCgIhEADQe1/h0dlmQdkuLe2XiMREDgk6ihm0X297jXd4de@vIssYvCXKjycpQtnMyrqVfjWaM301Ybs7cnb1SG4@8rMFQDlbiKzkloJogukS0jsoOnErWckn113FXEvr06gtStesnTN48Pj34j3A@AE "Python 3 – Try It Online")
Each iteration spreads light upwards, then rotates the array by 90 degrees.
[Answer]
# [J](http://jsoftware.com/), 28 27 bytes
```
(>./@,((,-)=1 2)|.!.0<:)^:_
```
[Try it online!](https://tio.run/##y/qvpKeepmBrpaCuoKNgoGAFxLp6Cs5BPm7/Nez09B10NDR0dDVtDRWMNGv0FPUMbKw046zi/2ty@TnpKcSCVcQbaoMVKVvBVcVypSZn5CukKZgAoQrQTAMgbaAAZhhAGEYwBhhC1Kuro@qDqDFG0YfK@A8A "J – Try It Online")
Consider input:
```
0 0 4 0
0 0 0 0
0 2 0 0
0 0 0 0
```
* `(,-)=1 2)` 4 directions of movement:
```
 1  0
 0  1
_1  0
 0 _1
```
* `|.!.0<:` Rotate the input minus 1 in those directions:
```
_1 _1 _1 _1
_1  1 _1 _1
_1 _1 _1 _1
 0  0  0  0
_1  3 _1  0
_1 _1 _1  0
 1 _1 _1  0
_1 _1 _1  0
 0  0  0  0
_1 _1  3 _1
_1 _1 _1 _1
_1  1 _1 _1
 0 _1 _1  3
 0 _1 _1 _1
 0 _1  1 _1
 0 _1 _1 _1
```
* `>./@,` Prepend input and max reduce the 5 "planes":
```
0 3 4 3
0 1 3 0
1 2 1 0
0 1 0 0
```
* `(...)^:_` Repeat that process until a fixed point:
```
2 3 4 3
1 2 3 2
1 2 2 1
0 1 1 0
```
[Answer]
# Python 3, ~~207~~ 205 bytes
Once I first saw this challenge posted, I started having some ideas for python solutions bouncing around in my head. This solution turned out to be way longer than I would have hoped, but I did find away to do this without `numpy`, which the other python solution uses:
```
f=lambda x:[[eval(f"max(max({i*'x[i-1][j],'}{j*'x[i][j-1],'}{~i%len(x)*'x[i+1][j],'}{~j%len(x)*'x[i][j+1],'})-1,x[i][j])")for j in range(len(x))]for i in range(len(x))]
g=lambda x:x if f(x)==x else g(f(x))
```
[Try it online!](https://tio.run/##ZY7RCoMgFIbv9xSHYKRlsOhu0JOIF46pU8yixXDEenWnBW1jHA6H7@P/4QzP6da7JgTZWt5drhz8mVLx4BbJrOMepZ11kXuqq5pRw0j@ms3KkaJKvOijFQ55vPpyzy3m20dbrnlc1WRjhjMs@xEMaAcjd0qgrYBZ0vpfH9TnUQ9agoy6bT0IexegUEIc9rJClJ5IHEZ@bsMYPsMwajehQuPwBg)
I wanted to be able to fit this into one lambda, but I simply couldn't seem to get the conditional to work, so `g(x)` is the function that is actually called to get the result. The main bulk of the code is in the giant `eval()` statement, which basically calculates the highest adjacent block, subtracts 1 from that, and takes the the max of that and the blocks current value. The rest of the code just iterates that over each block, and then recursively does that until all light levels have been calculated.
[Answer]
# [Haskell](https://www.haskell.org), 107 bytes
```
r x=[0..length x-1]
f a=let(w,h)=(r$head a,r a)in[[maximum[a!!y!!x-abs(x-j)-abs(y-i)|x<-w,y<-h]|j<-w]|i<-h]
```
[Attempt This Online!](https://ato.pxeger.com/run?1=m708I7E4OzUnZ8GCpaUlaboWN7OLFCpsow309HJS89JLMhQqdA1judIUEm1zUks0ynUyNG01ilQyUhNTFBJ1ihQSNTPzoqNzEysyc0tzoxMVFSsVFSt0E5OKNSp0szTBjErdTM2aChvdcp1KG92M2JosIDO2JhPEhlgJtRnmAgA)
[Answer]
# [Charcoal](https://github.com/somebody1234/Charcoal), 22 bytes
```
ＩＥθＥι⌈Ｅθ⌈Ｅν⁻π⁺↔⁻ξκ↔⁻ρμ
```
[Try it online!](https://tio.run/##S85ILErOT8z5/z@gKDOvRMM5sbhEwzexQKNQRwFEZYKoiszc0lyEKIKbB@Rm5pUWaxToKATkAGnHpOL8nNKSVA2IcIWOQrampo4CmnCRjkKuJhKw/v8/OjraSEfBAIyMY3UUuBQUog1gAgZECMTG/tctywEA "Charcoal – Try It Online") Link is to verbose version of code. Explanation: Same algorithm as @alephalpha's PARI/GP answer.
```
 ＥθＥι                   Map over input array
      Ｅθ Ｅν             Map over input array
            π           Innermost value
           ⁻            Subtract
              ↔⁻ξκ      Absolute row difference
             ⁺          Plus
                  ↔⁻ρμ  Absolute column difference
     ⌈  ⌈               Take the maximum
Ｉ                       Cast to string
                        Implicitly print
```
Note that Charcoal's default I/O format is rather ugly so I've also written a 26-byte prettier version which unfortunately only works up to 9:
```
ＷＳ⊞υιＥυ⭆ι⌈Ｅυ⌈Ｅν⁻π⁺↔⁻ξκ↔⁻ρμ
```
[Try it online!](https://tio.run/##XYpBCsIwEEX3OcUsJzDCIO66cumiEPAEsRQTTNKQJrW3jylVFP9m/nvzB6PTMGlX69NYNwJeQiz5mpMNd5QSVJkNFgIrO6GazNjruIl9soEl6PVqffGf3y@GhjaUGSOBcu2eb/PkSh5x1yvBQ0qCP50IvPymq5X5xIJbBB/53ephcS8 "Charcoal – Try It Online") Link is to verbose version of code.
[Answer]
# [PARI/GP](https://pari.math.u-bordeaux.fr), 73 bytes
```
m->matrix(#m~,#m,i,j,vecmax(matrix(#m~,#m,k,l,m[k,l]-abs(k-i)-abs(l-j))))
```
[Attempt This Online!](https://ato.pxeger.com/run?1=m728ILEoMz69YMHiNAXbpaUlaboWNz1zde1yE0uKMis0lHPrdJRzdTJ1snTKUpNzEys0UCWydXJ0cqOBZKxuYlKxRrZupiaYkaObpQkEUAPbEgsKcio1chV07RQKijLzSoBMJRBHSSFNI1dTU0chOtpARwGITICktQKEbQBjGyGxoSgWqMUIxjPG0IGFHRsLdc2CBRAaAA)
\$output[i,j]=\underset{k,l}\max(input[k,l]-|k-i|-|l-j|)\$
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E/wiki/Commands), ~~22~~ 21 [bytes](https://github.com/Adriandmen/05AB1E/wiki/Codepage)
```
Δ<U4FøíXøíDUćaª‚øεø€à
```
Port of [*@Jonah*'s J answer](https://codegolf.stackexchange.com/a/245462/52210), so make sure to upvote him as well!
[Try it online](https://tio.run/##yy9OTMpM/f//3BSbUBO3wzsOr40AES6hR9oTD6161DDr8I5zWw/veNS05vCC//@jow10DHRMdAxidcAsAyjLCM6CiMUCAA) or [verify all test cases](https://tio.run/##yy9OTMpM/V@m5JlXUFpipaCkU3lotw6Xkn9pCZy/8v@5KTahh9aZuB3ecXhtBIhwCT3Snnho1aOGWYd3nNt6eMejpjWHF/yvra0Faj60zf5/dHS0gY6BjomOQawOmGUAZRnBWRCxWB2F6GiwoI4xmlJ0VmwsAA).
**Explanation:**
```
Δ           # Loop until the result no longer changes:
 <          #  Decrease each value in the matrix by 1
            #  (which will be the implicit input-matrix in the first iteration)
  U         #  Pop and store it in variable `X`
 4F         #  Loop 4 times:
   øí       #   Rotate the matrix once clockwise:
   ø        #    Zip/transpose; swapping rows/columns
    í       #    Reverse each inner row
            #   (which will be the implicit input-matrix in the first iteration)
   X        #   Push matrix `X`
    øí      #   Rotate it once clockwise as well
      DU    #   Store a copy as new value for `X`
        ć   #   Extract head; pop remainder-matrix and first row separated
         a  #   Convert all values in this row to 0 (with an is_letter check)
          ª #   Append this list of 0s as trailing row
   ‚øεø€à   #   Reduce the two matrices by maximum:
   ‚        #    Pair the two matrices together
    ø       #    Zip/transpose; creating pair of rows
     εø     #    Zip/transpose each inner pair of rows to pair of cell-values
       €à   #    Leave the maximum of each inner-most pair of cell-values
            # (after which the resulting matrix is output implicitly) 
```
]