1. Are you planning to upload your awesome spell or system to Hive? Please review the rules here.
    Dismiss Notice
  2. Updated Resource Submission Rules: All model & skin resource submissions must now include an in-game screenshot. This is to help speed up the moderation process and to show how the model and/or texture looks like from the in-game camera.
    Dismiss Notice
  3. DID YOU KNOW - That you can unlock new rank icons by posting on the forums or winning contests? Click here to customize your rank or read our User Rank Policy to see a list of ranks that you can unlock. Have you won a contest and still haven't received your rank award? Then please contact the administration.
    Dismiss Notice
  4. Ride into the sunset with the 32nd Modeling Contest.
    Dismiss Notice
  5. This adventure has come to an end. Congratulate our heroes in the 16th Mini Mapping Contest Results.
    Dismiss Notice
  6. From the gates of hell, the 5th Special Effect Contest Results have emerged.
    Dismiss Notice
  7. Race against the odds and Reforge, Don't Refund. The 14th Techtree Contest has begun!
    Dismiss Notice
  8. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

[JASS/vJASS/Lua/Wurst] Perlin Noise

Submitted by Glint
This bundle is marked as approved. It works and satisfies the submission rules.
I haven't found any resources about Perlin Noise in Warcraft III, so I think this is a good start.

Perlin Noise is a type of gradient noise developed by Kenneth Perlin. For this resource, it uses his Improved Noise (2002). The source code can be found here.

This script is available for JASS, vJass, Lua, and Wurst.

Features

It features 1D, 2D, and 3D Perlin noise, the example maps only uses the 2D version.

It uses a permutation table. It represents as an array in JASS/vJass/Wurst and an integer table for Lua. As it follow Kenneth Perlin's implementation, the first 256 elements (0 - 255) contains random integer values ranges from 0 to 255. The elements from 256 - 512 only repeats the values of the first 256 elements. I think it is to avoid overflow?

You can modify the permutation table to satisfy your needs.

Popular sandbox games like Minecraft and Terraria uses a similar algorithm to create procedural generated terrain. This means you could now do the same in Warcraft III.

Screenshots


Sample Map
[​IMG]

Modified settings in Sample Map
[​IMG]

Application for custom maps
[​IMG]



The video below is an early version of the code, written in Wurst.

Video




For Wurst, you can now use Grill to add wurstNoiselib as a dependency to your project:

Code (Text):

grill install https://github.com/eGlint/wurstNoiselib
 
Requires
None (JASS/vJASS/Lua)
WurstStdlib2 (Wurst)

Optional
OctavePerlin (plugin for Perlin Noise, comes along with it, original source)

Code


JASS

Requires the following GUI variables:
  • Set NoisePermutation (integer array)

Code (vJASS):

//
//  Perlin Noise JASS v1.0.0
//
//  Port by Glint
//  Perlin Noise by Kenneth Perlin, https://mrl.nyu.edu/~perlin/noise/
//

function Floor takes real value returns integer
    local integer n = R2I(value)
    if value < 0 and value - n != 0. then
        set n = n - 1
    endif
    return n
endfunction

function RealTernaryOp takes boolean cond, real a, real b returns real
    if cond then
        return a
    else
        return b
    endif
endfunction

function Fade takes real t returns real
    return t * t * t * (t * (t * 6. - 15.) + 10.)
endfunction

function Lerp takes real t, real a, real b returns real
    return a + t * (b -a)
endfunction

function Gradient1D takes integer hash, real x returns real
    local integer h = BlzBitAnd(hash, 15)
    return RealTernaryOp(BlzBitAnd(h, 1) == 0, x, -x)
endfunction

function PerlinNoise1D takes real x returns real
    local integer X = BlzBitAnd(Floor(x), 255)
    set x = x - Floor(x)
    return Lerp(Fade(x), Gradient1D(udg_NoisePermutation[X], x), Gradient1D(udg_NoisePermutation[X + 1], x - 1)) * 2
endfunction

function Gradient2D takes integer hash, real x, real y returns real
    local integer h = BlzBitAnd(hash, 15)
    local real u = RealTernaryOp(h < 8, x, y)
    local real v = RealTernaryOp(h < 4, y, x)
    return RealTernaryOp(BlzBitAnd(h, 1) == 0, u, -u) + RealTernaryOp(BlzBitAnd(h, 2) == 0, v, -v)
endfunction

function PerlinNoise2D takes real x, real y returns real
    local integer X = BlzBitAnd(Floor(x), 255)
    local integer Y = BlzBitAnd(Floor(y), 255)
    local real u
    local real v
    local integer A
    local integer B
    local real lerpA1
    local real lerpA2
    set x = x - Floor(x)
    set y = y - Floor(y)
    set u = Fade(x)
    set v = Fade(y)
    set A = udg_NoisePermutation[X] + Y
    set B = udg_NoisePermutation[X + 1] + Y
    set lerpA1 = Lerp(u, Gradient2D(udg_NoisePermutation[A], x, y), Gradient2D(udg_NoisePermutation[B], x - 1., y))
    set lerpA2 = Lerp(u, Gradient2D(udg_NoisePermutation[A + 1], x, y - 1.), Gradient2D(udg_NoisePermutation[B + 1], x - 1., y - 1.))
    return Lerp(v, lerpA1, lerpA2)
endfunction

function Gradient3D takes integer hash, real x, real y, real z returns real
    local integer h = BlzBitAnd(hash, 15)
    local real u = RealTernaryOp(h < 8, x, y)
    local real v = RealTernaryOp(h < 4, y, RealTernaryOp(h == 12 or h == 14, x, z))
    return RealTernaryOp(BlzBitAnd(h, 1) == 0, u, -u) + RealTernaryOp(BlzBitAnd(h, 2) == 0, v, -v)
endfunction

function PerlinNoise3D takes real x, real y, real z returns real
    local integer X = BlzBitAnd(Floor(x), 255)
    local integer Y = BlzBitAnd(Floor(y), 255)
    local integer Z = BlzBitAnd(Floor(z), 255)
    local real u
    local real v
    local real w
    local integer A
    local integer AA
    local integer AB
    local integer B
    local integer BA
    local integer BB
    local real lerpA1
    local real lerpA2
    local real lerpB1
    local real lerpB2
    set x = x - Floor(x)
    set y = y - Floor(y)
    set z = z - Floor(z)
    set u = Fade(x)
    set v = Fade(y)
    set w = Fade(z)
    set A = udg_NoisePermutation[X] + Y
    set AA = udg_NoisePermutation[A] + Z
    set AB = udg_NoisePermutation[A + 1] + Z
    set B = udg_NoisePermutation[X + 1] + Y
    set BA = udg_NoisePermutation[B] + Z
    set BB = udg_NoisePermutation[B + 1] + Z
    set lerpA1 = Lerp(u, Gradient3D(udg_NoisePermutation[AA], x, y, z), Gradient3D(udg_NoisePermutation[BA], x - 1., y, z))
    set lerpA2 = Lerp(u, Gradient3D(udg_NoisePermutation[AB], x, y - 1., z), Gradient3D(udg_NoisePermutation[BB], x - 1., y - 1., z))
    set lerpB1 = Lerp(u, Gradient3D(udg_NoisePermutation[AA + 1], x, y, z - 1.), Gradient3D(udg_NoisePermutation[BA + 1], x - 1., y, z - 1.))
    set lerpB2 = Lerp(u, Gradient3D(udg_NoisePermutation[AB + 1], x, y - 1., z - 1.), Gradient3D(udg_NoisePermutation[BB + 1], x - 1., y - 1., z - 1.))
    return Lerp(w, Lerp(v, lerpA1, lerpA2), Lerp(v, lerpB1, lerpB2))
endfunction
 



vJass

Code (vJASS):

/*
    Perlin Noise vJASS 1.0.0

    Port by Glint
    Perlin Noise by Kenneth Perlin, https://mrl.nyu.edu/~perlin/noise/
*/


library Noise
 
    private module Init
        private static method onInit takes nothing returns nothing
            call permutationInit()
        endmethod
    endmodule

    struct Noise extends array
        readonly static string version = "1.0.0"
        static integer array permutation

        implement Init
 
        private static method floor takes real value returns integer
            local integer n = R2I(value)
            if value < 0. and value - n != 0. then
                set n = n - 1
            endif
            return n
        endmethod
 
        private static method realTernaryOp takes boolean cond, real a, real b returns real
            if cond then
                return a
            else
                return b
            endif
        endmethod
 
        private static method fade takes real t returns real
            return t * t * t * (t * (t * 6. - 15.) + 10.)
        endmethod

        private static method lerp takes real t, real a, real b returns real
            return a + t * (b -a)
        endmethod

        private static method grad1D takes integer hash, real x returns real
            local integer h = BlzBitAnd(hash, 15)
            return realTernaryOp(BlzBitAnd(h, 1) == 0, x, -x)
        endmethod

        static method perlin1D takes real x returns real
            local integer X = BlzBitAnd(floor(x), 255)
            set x = x - floor(x)
            return lerp(fade(x), grad1D(permutation[X], x), grad1D(permutation[X + 1], x - 1.)) * 2
        endmethod

        private static method grad2D takes integer hash, real x, real y returns real
            local integer h = BlzBitAnd(hash, 15)
            local real u = realTernaryOp(h < 8, x, y)
            local real v = realTernaryOp(h < 4, y, x)
            return realTernaryOp(BlzBitAnd(h, 1) == 0, u, -u) + realTernaryOp(BlzBitAnd(h, 2) == 0, v, -v)
        endmethod

        static method perlin2D takes real x, real y returns real
            local integer X = BlzBitAnd(floor(x), 255)
            local integer Y = BlzBitAnd(floor(y), 255)
            local real u
            local real v
            local integer A
            local integer B
            local real lerpA1
            local real lerpA2
            set x = x - floor(x)
            set y = y - floor(y)
            set u = fade(x)
            set v = fade(y)
            set A = permutation[X] + Y
            set B = permutation[X + 1] + Y
            set lerpA1 = lerp(u, grad2D(permutation[A], x, y), grad2D(permutation[B], x - 1., y))
            set lerpA2 = lerp(u, grad2D(permutation[A + 1], x, y - 1.), grad2D(permutation[B + 1], x - 1., y - 1.))
            return lerp(v, lerpA1, lerpA2)
        endmethod

        private static method grad3D takes integer hash, real x, real y, real z returns real
            local integer h = BlzBitAnd(hash, 15)
            local real u = realTernaryOp(h < 8, x, y)
            local real v = realTernaryOp(h < 4, y, realTernaryOp(h == 12 or h == 14, x, z))
            return realTernaryOp(BlzBitAnd(h, 1) == 0, u, -u) + realTernaryOp(BlzBitAnd(h, 2) == 0, v, -v)
        endmethod

        static method perlin3D takes real x, real y, real z returns real
            local integer X = BlzBitAnd(floor(x), 255)
            local integer Y = BlzBitAnd(floor(y), 255)
            local integer Z = BlzBitAnd(floor(z), 255)
            local real u
            local real v
            local real w
            local integer A
            local integer AA
            local integer AB
            local integer B
            local integer BA
            local integer BB
            local real lerpA1
            local real lerpA2
            local real lerpB1
            local real lerpB2
            set x = x - floor(x)
            set y = y - floor(y)
            set z = z - floor(z)
            set u = fade(x)
            set v = fade(y)
            set w = fade(z)
            set A = permutation[X] + Y
            set AA = permutation[A] + Z
            set AB = permutation[A + 1] + Z
            set B = permutation[X + 1] + Y
            set BA = permutation[B] + Z
            set BB = permutation[B + 1] + Z
            set lerpA1 = lerp(u, grad3D(permutation[AA], x, y, z), grad3D(permutation[BA], x - 1., y, z))
            set lerpA2 = lerp(u, grad3D(permutation[AB], x, y - 1., z), grad3D(permutation[BB], x - 1., y - 1., z))
            set lerpB1 = lerp(u, grad3D(permutation[AA + 1], x, y, z - 1.), grad3D(permutation[BA + 1], x - 1., y, z - 1.))
            set lerpB2 = lerp(u, grad3D(permutation[AB + 1], x, y - 1., z - 1.), grad3D(permutation[BB + 1], x - 1., y - 1., z - 1.))
            return lerp(w, lerp(v, lerpA1, lerpA2), lerp(v, lerpB1, lerpB2))
        endmethod

        static method permutationInit takes nothing returns nothing
            local integer i = 0
            loop
                exitwhen i > 255
                set permutation[i] = GetRandomInt(0, 255)
                    set permutation[i + 256] = permutation[i]
                    set i = i + 1
            endloop
        endmethod
    endstruct
endlibrary
 



Lua

Code (Lua):

--[[
    Perlin Noise Lua v1.0.1

    Port by Glint
    Perlin Noise by Kenneth Perlin, https://mrl.nyu.edu/~perlin/noise/
]]
--
do
    Noise = {}

    Noise.version = "1.0.1"
    Noise.permutation = {}

    local function floor(value)
        local n = R2I(value)
        if value < 0. and value - n ~= 0. then n = n - 1 end
        return n
    end

    local function fade(t)
        return t * t * t * (t * (t * 6. - 15.) + 10.)
    end

    local function lerp(t, a, b)
        return a + t * (b -a)
    end

    local function grad1D(hash, x)
        local h = BlzBitAnd(hash, 15)
        return (BlzBitAnd(h, 1) == 0 and x or -x)
    end

    function Noise.perlin1D (x)
        local X = BlzBitAnd(floor(x), 255)
        x = x - floor(x)
        return lerp(fade(x), grad1D(Noise.permutation[X], x), grad1D(Noise.permutation[X + 1], x - 1)) * 2
    end

    local function grad2D(hash, x, y)
        local h = BlzBitAnd(hash, 15)
        local u, v = h < 8 and x or y, h < 4 and y or x
        return (BlzBitAnd(h, 1) == 0 and u or -u) + (BlzBitAnd(h, 2) == 0 and v or -v)
    end

    function Noise.perlin2D (x, y)
        local X, Y = BlzBitAnd(floor(x), 255), BlzBitAnd(floor(y), 255)
        x, y = x - floor(x), y - floor(y)
        local u, v = fade(x), fade(y)
        local A = Noise.permutation[X] + Y
        local B = Noise.permutation[X + 1] + Y
        local a1 = lerp(u, grad2D(Noise.permutation[A], x, y), grad2D(Noise.permutation[B], x - 1, y))
        local a2 = lerp(u, grad2D(Noise.permutation[A + 1], x, y - 1), grad2D(Noise.permutation[B + 1], x - 1, y - 1))
        return lerp(v, a1, a2)
    end

    local function grad3D(hash, x, y, z)
        local h = BlzBitAnd(hash, 15)
        local u, v = h < 8 and x or y, h < 4 and y or ((h == 12 or h == 14) and x or z)
        return (BlzBitAnd(h, 1) == 0 and u or -u) + (BlzBitAnd(h, 2) == 0 and v or -v)
    end

    function Noise.perlin3D (x, y, z)
        local X, Y, Z = BlzBitAnd(floor(x), 255), BlzBitAnd(floor(y), 255), BlzBitAnd(floor(z), 255)
        x, y, z = x - floor(x), y - floor(y), z - floor(z)
        local u, v, w = fade(x), fade(y), fade(z)
        local A = Noise.permutation[X] + Y
        local AA = Noise.permutation[A] + Z
        local AB = Noise.permutation[A + 1] + Z
        local B = Noise.permutation[X + 1] + Y
        local BA = Noise.permutation[B] + Z
        local BB = Noise.permutation[B + 1] + Z
        local a1 = lerp(u, grad3D(Noise.permutation[AA], x, y, z), grad3D(Noise.permutation[BA], x - 1, y, z))
        local a2 = lerp(u, grad3D(Noise.permutation[AB], x, y - 1, z), grad3D(Noise.permutation[BB], x - 1, y - 1, z))
        local b1 = lerp(u, grad3D(Noise.permutation[AA + 1], x, y, z - 1), grad3D(Noise.permutation[BA + 1], x - 1, y, z - 1))
        local b2 = lerp(u, grad3D(Noise.permutation[AB + 1], x, y - 1, z - 1), grad3D(Noise.permutation[BB + 1], x - 1, y - 1, z - 1))
        return lerp(w, lerp(v, a1, a2), lerp(v, b1, b2))
    end

    function Noise.permutationInit ()
        for i = 0, 255 do
            Noise.permutation[i] = GetRandomInt(0, 255)
            Noise.permutation[i + 256] = Noise.permutation[i]
        end
    end
end
 


Wurst

Code (WurstScript):

/*
    Perlin Noise Wurst v1.0.1

    Port by Glint
    Perlin Noise by Kenneth Perlin, https://mrl.nyu.edu/~perlin/noise/
*/

package Noise

import NoWurst
import Integer
import Vectors

function grad(int hash, real x) returns real
    var h = hash.bitAnd(15)
    return h.bitAnd(1) == 0 ? x : -x
 
function grad(int hash, vec2 vec) returns real
    var h = hash.bitAnd(15)
    let u = h < 8 ? vec.x : vec.y
    let v = h < 4 ? vec.y : vec.x
    return (h.bitAnd(1) == 0 ? u: -u) + (h.bitAnd(2) == 0 ? v : -v)

function grad(int hash, vec3 vec) returns real
    let h = hash.bitAnd(15)
    let u = h < 8 ? vec.x : vec.y
    let v = h < 4 ? vec.y : (h == 12 or h == 14 ? vec.x : vec.z)
    return (h.bitAnd(1) == 0 ? u : -u) + (h.bitAnd(2) == 0 ? v : -v)

function real.fade () returns real
    return this * this * this * (this * (this * 6. - 15.) + 10.)

public class Noise
    static int array p

    static function perlin (real x) returns real
        var lx = x
        let X = lx.floor().bitAnd(255)
        lx -= lx.floor()
        return grad(p[X], lx).lerp(
               grad(p[X + 1], lx - 1), lx.fade()) * 2

    static function perlin (vec2 vec) returns real
        var lvec = vec
        let X = lvec.x.floor().bitAnd(255)
        let Y = lvec.y.floor().bitAnd(255)
        lvec = vec2(lvec.x - lvec.x.floor(), lvec.y - lvec.y.floor())
        let u = lvec.x.fade()
        let v = lvec.y.fade()
        let A = p[X] + Y
        let B = p[X + 1] + Y
        return grad(p[A], lvec).lerp(
               grad(p[B], lvec - vec2(1, 0)), u).lerp(
               grad(p[A + 1], lvec - vec2(0, 1)).lerp(
               grad(p[B + 1], lvec - vec2(1, 1)), u), v)

    static function perlin (vec3 vec) returns real
        var lvec = vec
        let X = vec.x.floor().bitAnd(255)
        let Y = vec.y.floor().bitAnd(255)
        let Z = vec.z.floor().bitAnd(255)  
        lvec = vec3(lvec.x - lvec.x.floor(), lvec.y - lvec.y.floor(), lvec.z - lvec.z.floor())
        let u = lvec.x.fade()
        let v = lvec.y.fade()
        let w = lvec.z.fade()
        let A = p[X] + Y
        let AA = p[A] + Z
        let AB = p[A + 1] + Z
        let B = p[X + 1] + Y
        let BA = p[B] + Z
        let BB = p[B + 1] + Z
        return grad(p[AA], lvec).lerp(
               grad(p[BA], lvec - vec3(1, 0, 0)), u).lerp(
               grad(p[AB], lvec - vec3(0, 1, 0)).lerp(
               grad(p[BB], lvec - vec3(1, 1, 0)), u), v).lerp(
               grad(p[AA + 1], lvec - vec3(0, 0, 1)).lerp(
               grad(p[BA + 1], lvec - vec3(1, 0, 1)), u).lerp(
               grad(p[AB + 1], lvec - vec3(0, 1, 1)).lerp(
               grad(p[BB + 1], lvec - vec3(1, 1, 1)), u), v), w)

    static function generateRandomPermutation()
        for i = 0 to 255
            p[i] = GetRandomInt(0, 255)
            p[i + 256] = p [i]
 





Example

Code (vJASS):

function GetResult takes nothing returns nothing
    local real x = (udg_Offset_X + udg_World_Offset_X + I2R(udg_X)) * udg_Scale
    local real y = (udg_Offset_Y + udg_World_Offset_Y + I2R(udg_Y)) * udg_Scale
    if udg_IsOctavePerlin then
        set udg_Result = OctavePerlin2D(x, y,udg_Octaves, udg_Persistence)
    else
        set udg_Result = PerlinNoise2D(x, y)
    endif
    set x = udg_World_Offset_X + udg_X * udg_PerSquare_Width
    set y = udg_World_Offset_Y + -(udg_Y * udg_PerSquare_Height)
    if udg_Result < .1 then
        call SetTerrainType(x, y, 'Ldrt', 0, 1, 0)
    elseif udg_Result < .2 then
        call SetTerrainType(x, y, 'Ldro', 0, 1, 0)
    elseif udg_Result < .25 then
        call SetTerrainType(x, y, 'Lgrs', 0, 1, 0)
    elseif udg_Result < .5 then
        call SetTerrainType(x, y, 'Ldrg', 0, 1, 0)
    else
        call SetTerrainType(x, y, 'Lrok', 0, 1, 0)
    endif
endfunction
 



Previews
Contents

[JASS] Perlin Noise (Map)

[vJASS] Perlin Noise (Map)

[Lua] Perlin Noise (Map)

WurstPerlinNoise (Map)

  1. MyPad

    MyPad

    Spell Reviewer

    Joined:
    May 9, 2014
    Messages:
    1,362
    Resources:
    7
    Models:
    1
    Icons:
    2
    Spells:
    3
    JASS:
    1
    Resources:
    7
    This … is quite an unusual resource in the Spells section. An algorithm of sorts that normally doesn't pertain to the usual ideas centered around spells. I'll reserve judgment to @Dr Super Good and @Frotty.
     
  2. Frotty

    Frotty

    Wurst Reviewer

    Joined:
    Jan 1, 2009
    Messages:
    1,473
    Resources:
    11
    Models:
    3
    Tools:
    1
    Maps:
    5
    Tutorials:
    1
    Wurst:
    1
    Resources:
    11
    Cool, Wurst code looks good from a first viewing. `lerp` already exists as `linear` in the Interpolation package.
    Is there a git repo for it, so it can be used as dependency via grill? If not, that would be a nice addition.
    Thumbs up for covering all scripting languages :thumbs_up:
     
  3. Drake53

    Drake53

    Joined:
    Jan 1, 2018
    Messages:
    265
    Resources:
    0
    Resources:
    0
    You sure you're not forgetting something? Don't worry though, I got you covered.

    Code (C#):
        [NativeLuaMemberContainer]
        internal static class PerlinNoise
        {
            [NativeLuaMember("Noise.perlin1D")]
            public static extern float Noise(float x);

            [NativeLuaMember("Noise.perlin2D")]
            public static extern float Noise(float x, float y);

            [NativeLuaMember("Noise.perlin3D")]
            public static extern float Noise(float x, float y, float z);

            [NativeLuaMember("Noise.permutationInit")]
            public static extern void Init();
        }
    It's probably more efficient like this anyways, compared to writing the entire library in C#.


    Also, spotted a small mistake here:
    Code (Lua):
    function Noise.perlin1D (x, y, z)
     
  4. Glint

    Glint

    Joined:
    Dec 28, 2014
    Messages:
    68
    Resources:
    2
    Maps:
    1
    Spells:
    1
    Resources:
    2
    I'll work on that one. I was just to upload the source code in Github.

    Oh my, I even remember using it before. Well, I'm gonna update that one once I upload it to git.

    Nice catch! I caught another one as well.

    Code (Lua):
    function Noise.grad1D (hash, x, y)
    I updated the Lua version to 1.0.1.
     
  5. Glint

    Glint

    Joined:
    Dec 28, 2014
    Messages:
    68
    Resources:
    2
    Maps:
    1
    Spells:
    1
    Resources:
    2
    JASS, vJASS and Lua now have a git repository.

    Updated Wurst version to 1.0.1.
    - Removed lerp() and used the one in the standard library: real.lerp()

    Also for Wurst, you can now use Grill to add wurstNoiselib as a dependency to your project.

    Code (Text):

    grill install https://github.com/eGlint/wurstNoiselib
    grill install
     
     
  6. Chaosy

    Chaosy

    Joined:
    Jun 9, 2011
    Messages:
    10,739
    Resources:
    18
    Maps:
    1
    Spells:
    11
    Tutorials:
    6
    Resources:
    18
    Underrated dedication to multiple languages.

    I do not have use for this right now, but I will try to keep it in mind in the future
     
  7. Frotty

    Frotty

    Wurst Reviewer

    Joined:
    Jan 1, 2009
    Messages:
    1,473
    Resources:
    11
    Models:
    3
    Tools:
    1
    Maps:
    5
    Tutorials:
    1
    Wurst:
    1
    Resources:
    11
    You don't need an 'install' after installing the dependency.
    Other than that, good stuff
     
  8. Glint

    Glint

    Joined:
    Dec 28, 2014
    Messages:
    68
    Resources:
    2
    Maps:
    1
    Spells:
    1
    Resources:
    2
    Oh, thank you for the correction.
     
  9. Cheezeman

    Cheezeman

    Joined:
    Aug 19, 2008
    Messages:
    488
    Resources:
    2
    Spells:
    1
    Tutorials:
    1
    Resources:
    2
    Iirc perlin says in the paper it is to align the array with memory or some such. He mentions it anyway.
     
  10. Frotty

    Frotty

    Wurst Reviewer

    Joined:
    Jan 1, 2009
    Messages:
    1,473
    Resources:
    11
    Models:
    3
    Tools:
    1
    Maps:
    5
    Tutorials:
    1
    Wurst:
    1
    Resources:
    11
  11. Edy

    Edy

    Joined:
    Nov 21, 2015
    Messages:
    226
    Resources:
    1
    Maps:
    1
    Resources:
    1
    1x1 pathing blockers and smaller tiles are the things that I hope for Wc3.
    Good stuff