Minecraft GenLayer
by eddyb
HTML
<span class=info></span><div style=height:100%;overflow-y:auto>
<br>
<input class=seed value=42>
(<input class=cx value=0>, <input class=cy value=0>) <input class=w value=4096> × <input class=h value=512>
<div class=outputs></div>
</div>
CSS
html,body {
height: 100%;
}
body {
font-family: monospace;
margin: 0;
}
.info {
position: absolute;
z-index: 100000;
background: white;
padding: 0.5em;
border-bottom-right-radius: 0.5em;
}
input {
border: 1px solid gray;
}
.cx, .cy, .w, .h {
width: 5ch;
}
.outputs {
display: flex;
flex-direction: row;
align-items: flex-start;
}
.outputs > * {
display: flex;
flex-direction: column-reverse;
}
figure {
display: flex;
flex-direction: column;
align-items: center;
}
figure > figcaption {
text-align: center;
font-size: 14px;
white-space: nowrap;
}
figure > canvas {
border: 1px solid black;
image-rendering: pixelated;
}
JavaScript 1.7
$(() => {
const range = function*(start, end, step=1) {
if(typeof end == 'undefined') {
end = start;
start = 0;
}
if(step < 0) {
step = - step;
[start, end] = [end, start];
}
if(start < end)
for(var i = start; i < end; i += step)
yield i;
else
for(var i = start; i > end; i -= step)
yield i;
};
const i64 = x => BigInt.asIntN(64, BigInt(x));
class GenLayerRNG {
constructor(seed0, ...seeds) {
if(!seeds.length)
seeds = [seed0, seed0, seed0];
this.seed = this.seed0 = i64(seed0);
for(let seed of seeds)
this.feed(seed);
}
worldSeed(seed) {
return new GenLayerRNG(seed, this.seed, this.seed, this.seed);
}
pos(x, y) {
return new GenLayerRNG(this.seed, x, y, x, y);
}
feed(seed) {
this.seed = i64(i64(this.seed * i64(i64(this.seed * GenLayerRNG.multiplicand) + GenLayerRNG.addend)) + i64(seed));
}
next(n) {
if(Array.isArray(n))
return n[this.next(n.length)];
let r = Number((this.seed >> 24n) % i64(n));
this.feed(this.seed0);
return r < 0 ? r + n : r;
}
next0(n) {
return this.next(n) === 0;
}
}
GenLayerRNG.multiplicand = 6364136223846793005n;
GenLayerRNG.addend = 1442695040888963407n;
const Biomes = {names: [], colors: []};
[
['Ocean', 'rgb(0, 0, 112)', 'C'],
['Plains', 'rgb(141, 179, 96)', 'A'],
['Desert', 'rgb(250, 148, 24)', 'E'],
['Extreme Hills', 'rgb(96, 96, 96)', 'I'],
['Forest', 'rgb(5, 102, 33)', 'A'],
['Taiga', 'rgb(11, 102, 89)', 'F'],
['Swampland', 'rgb(7, 249, 178)', 'M'],
['River', 'rgb(0, 0, 255)', 'B'],
['Hell', 'rgb(255, 0, 0)', 'A'],
['Sky', 'rgb(128, 128, 255)', 'A'],
['Frozen Ocean', ...