Zen

by Yut Put
Survive with your pals, build a house, and get eaten by werebunnies.
ID:1156734
 
been adding stuff tonight, because i felt like it. Most of this stuff is really big and game changing.

-Reduced the distance required to kill an enemy(closer range = more likely to get hurt = adds value to the whole survival element of the game. I want to get to a point where monsters are worth being feared so that hp and food has actual value)
-Added weather system
-Added snowfall(forms in clumps on grassy tiles while the snow is still active)
-Added rainstorms(Random lightning strikes which can destroy stone structures or damage players/animals. Protect your buildings and farms by using lightningrods. Increases the growth rate of all farm plants by a percent, and sets pumpkins to 100%)
-Added lightningrods(attracts lightning away from anything in a 5 tile radius.)
-Rubies, emeralds, darkgems, and sapphires now spawn differently. Instead of randomly popping out of rocks, they have their own separate entities. You can visually spot the ores before mining them. The spawn rates are currently the same.
-Big lag + bug fix(trees dont spam spawn areas any longer, etc)
-Slenderman is removed from the world if you destroy all five temples.
woo
poop
none plays this game lol
Very nice stuff.

Have you decided whether or not to open source this in the near future? The topic you started in August has 61 votes for yes, and personally I'd like to see how you did some things.
i just randomly update binge sometimes, regardless of who plays it or not lol. The funny thing is the only people I play byond games with are kate and falcon

I don't think I'll open source this, because the programming is a mess. my programming takes the works-and-does-cool-stuff-and-somehow-avoids-lag-and-ineffic iency approach.

oh, and i'll be adding to this list later, so if you're interested feel free to check on the post periodically. i'm not going to upload this update until i feel similar to a samoan cow, and that may take a while to achieve.
Sounds exciting. Any chance of a hint where you learned to create the world generation?
In response to TheLionsRoar
TheLionsRoar wrote:
Sounds exciting. Any chance of a hint where you learned to create the world generation?

This. You could make a demo/tutorial/snippit for world generation if you wanted. It would help me, and i'm sure a load of others out.
LOL, I don't know much about it, to be honest. It was mostly a trial+error process that took about 5 hours to get finished. Before Zen, my only dabblings in procedural map generation involved a large grid-based city for a zombie survival concept.

It's mostly based around water. Once you have the water placed, everything else is easy. In fact, it's almost an illusion of random generation.

Basically, I think it just randomly places water seeds around the map, and those water seeds fill up a specific range of tiles, and then place smaller seeds around themselves which fill up more smaller ranges of tiles.

it first makes sure the edges of the map are watery, and then it fractalizationalates the rest of the map.

fractals basically are just random offsets which slowly decay upon each iteration. So if you split a line in the middle by separating it into two sections and raising that middle vertex up or down a random amount, the second time you'd split it you would take the two edges created from the first split and randomly raise a midpoint on each of them up or down an amount equal to half of the range of the first randomization.

um. That's really complicated, but its a simple concept. Google it.

    proc/fractal_water(num)


if(num == 1)
var/I = rand(30,50)
while(I)
I--

var/turf/T = pick(block(locate(1,1,1),locate(maxx,maxy,maxz)))
T.icon_state = "water"
T.density=1
for(var/turf/t in orange(rand(1,4),T))
t.icon_state = "water"
t.density=1

for(var/turf/t in orange(15,T))
var/i = rand(1,20)
if(i == 1)
t.icon_state = "water"
t.density=1

var/fractal_list = list()
var/list1 = list()
for(var/turf/T in world)
if(T.icon_state == "water")
for(var/turf/t in orange(1,T))
if(t.icon_state <> "water")
T.fractal = 100
fractal_list += T
list1+=1
var/X = 10
var/fractal_list2 = list()
while(X)
X--



for(var/turf/T in fractal_list)
for(var/turf/t in orange(1,T))
if(t.icon_state == "grass")
if(rand(T.fractal,100)==100 || T.fractal == 100)



t.icon_state = "water"
t.density=1

t.fractal = T.fractal-5
fractal_list2 += t

fractal_list = fractal_list2
if(num == 2)
for(var/turf/T in list1)
if(T.icon_state == "water")
for(var/turf/t in orange(1,T))
t.icon_state = "water"
t.density=1


......It's a horrid mess. This is why I chose not to release the source.



Once you have the water, you just have to measure the distance between each grass turf and the water. If it's right next to the water, I used a mix between mud and seamud. If it's a bit farther out, I used sand. the sand and mud both spread themselves with fractals. This is called a heightmap.

Before placing water, random snow and sand seeds are placed to create deserts and tundras, which can be overlapped by water.

After everything is placed, cave seeds are placed, and then the caves have their edges randomly lifted.

Then trees, etc are placed.

Oh, and temples are also placed.

It's all pretty straightforward. You gotta actually try it yourself.
That's actually very simple compared to everything i've found on google. Thank. I'm going to try that now.

EDIT: This makes nearly the entire map water. i'm unsure if i'm doing this right. You call this in the New() proc for world and use fractal_water on every type of water turf, right?
from procedural generation.dm

mind the horrid mess

var/water_list = list()
var/sand_list = list()
var/stone_list = list()
turf
var

is_snow=0
obj
HUD
title_screen
screen_loc = "1,1"
New(client/c)
c.screen+=src
icon = 'title screen.png'
layer = 103
Click()
usr.finish_HUD()
del(src)

world

loop_checks=0

proc/generate_world()


maxx = 300
maxy = 300
maxz=1





fractal_snow(1)
fractal_snow(2)

fractal_sand(1)
fractal_sand(2)

for(var/turf/t in world)
if(t.icon_state == "snow")
t.is_snow=1
t.icon_state = "grass"
if(t.icon_state == "sand")
t.is_snow=2
t.icon_state = "grass"

place_water()
world.log << "water placed"
place_sand()
world.log << "sand placed"

fractal_caves(1)
world.log << "caves placed"
fractal_caves(2)




polish_caves()

place_temples()


final_polish()




/* var/MapBase/base = new(1)
base.save("level.map")

map = maps.copy("level.map")*/



place_spawns()
world.log << "spawn placed"

proc/final_polish()
for(var/turf/T in world)
if(T.icon_state == "water")
T.density=1
else
T.density=0

if(T.is_snow==1 && T.icon_state == "grass")
T.icon_state = "snow"

if(T.is_snow==2 && T.icon_state == "grass")
T.icon_state = "sand"
for(var/obj/block/b in world)
if(b.icon_state == "stone")
var/i = rand(1,20)
if(i==1)
b.icon_state = "ruby"
i = rand(1,40)
if(i == 1)
b.icon_state = "saphire"
i = rand(1,60)
if(i == 1)
b.icon_state = "emerald"
i = rand(1,80)
if(i == 1)
b.icon_state = "darkgem"


proc/place_temples()
var/I = 5
var/tlist = list()
for(var/turf/T in world)
if(T.icon_state == "grass" || T.icon_state == "stone")
tlist += T

var/tlist2 = list()
while(I--)
tlist2 += pick(tlist)

for(var/turf/T in tlist2)

if(T.icon_state == "grass" || T.icon_state == "stone")


for(var/obj/O in orange(5,T))



del(O)




for(var/turf/t in orange(5,T))

t.icon_state = "stone"
t.density=0
t.is_snow=0

if(get_dist(t,T) == 5)


if(t.y == T.y || t.x == T.x)

if(t.y < T.y && t.x == T.x)

new/obj/block/door(t)
else
t.icon_state = "stained glass"
t.raise()
else

t.raise()



new/obj/block/bunny_on_a_stick(locate(T.x+3,T.y+3,T.z))
new/obj/block/bunny_on_a_stick(locate(T.x-3,T.y+3,T.z))
new/obj/block/bunny_on_a_stick(locate(T.x-3,T.y-3,T.z))
new/obj/block/bunny_on_a_stick(locate(T.x+3,T.y-3,T.z))


new/obj/block/table(locate(T.x+2,T.y,T.z))

new/obj/block/table(locate(T.x-2,T.y,T.z))



for(var/turf/t in orange(5,T))
t.icon_state = "stone"
new/obj/block/monster_spawner(T)
T.icon_state="stone"


proc/place_sand()
var/tlist = list()
for(var/turf/T in world)
if(T.icon_state == "water")
tlist += T
for(var/turf/t in orange(1,T))
if(t.icon_state == "grass")
t.icon_state = "sand"
sand_list += t
tlist -= t
for(var/turf/T in sand_list)
for(var/turf/t in orange(1,T))
var/i = rand(1,20)
if(i <> 20)
t.icon_state = "sand"

for(var/turf/T in world)
if(T.icon_state == "water")
for(var/turf/t in orange(1,T))
if(t.icon_state == "sand")
t.icon_state = "mud"
for(var/turf/k in orange(3,t))
if(k.icon_state == "water")
k.icon_state = "shallow water"


proc/place_water()


for(var/turf/T in block(locate(1,1,1),locate(10,maxy,1)))
T.icon_state = "water"
T.density=1

for(var/turf/T in block(locate(1,1,1),locate(maxx,10,1)))
T.icon_state = "water"
T.density=1

for(var/turf/T in block(locate(maxx-10,1,1),locate(maxx,maxy,1)))
T.icon_state = "water"
T.density=1

for(var/turf/T in block(locate(1,maxy-10,1),locate(maxx,maxy,1)))
T.icon_state = "water"
T.density=1




fractal_water(1)
fractal_water(2)









proc/polish_caves()
for(var/turf/T in stone_list)
for(var/turf/t in orange(1,T))
if(t.icon_state == "grass" || t.icon_state == "water")
var/K = rand(1,10)
if(K <> 1)
if(T.icon_state == "stone")
T.raise()
else
T.icon_state = "mud"
for(var/turf/k in orange(1,T))
var/s = rand(1,4)
if(s == 1)
k.icon_state = "mud"
break

var/I = rand(1,20)
if(I == 1)
T.raise()
for(var/turf/t in orange(1,T))
if(t.icon_state == "stone")
var/i =rand(1,4)
if(i == 1)
t.raise()
proc/fractal_snow(num)


if(num == 1)
var/I = rand(3,5)
while(I)
I--

var/turf/T = pick(block(locate(1,1,1),locate(maxx,maxy,maxz)))

T.icon_state = "snow"

for(var/turf/t in orange(rand(4,6),T))
t.icon_state = "snow"

for(var/turf/t in orange(15,T))
var/i = rand(1,20)
if(i == 1)
t.icon_state = "snow"



var/fractal_list = list()
var/list1 = list()
for(var/turf/T in world)
if(T.icon_state == "snow")
for(var/turf/t in orange(1,T))
if(t.icon_state <> "snow")
T.fractal = 100
fractal_list += T
// list1+=T
var/X = 10
var/fractal_list2 = list()
while(X)
X--



for(var/turf/T in fractal_list)
for(var/turf/t in orange(1,T))
if(t.icon_state != "snow")
if(rand(T.fractal,100)==100 || T.fractal == 100)



t.icon_state = "snow"


t.fractal = T.fractal-5
fractal_list2 += t

fractal_list = fractal_list2
if(num == 2)
for(var/turf/T in list1)
if(T.icon_state == "snow")
for(var/turf/t in orange(1,T))
t.icon_state = "snow"


proc/fractal_sand(num)


if(num == 1)
var/I = rand(3,5)
while(I)
I--

var/turf/T = pick(block(locate(1,1,1),locate(maxx,maxy,maxz)))

T.icon_state = "sand"

for(var/turf/t in orange(rand(4,6),T))
t.icon_state = "sand"

for(var/turf/t in orange(15,T))
var/i = rand(1,20)
if(i == 1)
t.icon_state = "sand"



var/fractal_list = list()
var/list1 = list()
for(var/turf/T in world)
if(T.icon_state == "sand")
for(var/turf/t in orange(1,T))
if(t.icon_state <> "sand")
T.fractal = 100
fractal_list += T
// list1+=T
var/X = 10
var/fractal_list2 = list()
while(X)
X--



for(var/turf/T in fractal_list)
for(var/turf/t in orange(1,T))
if(t.icon_state != "sand")
if(rand(T.fractal,100)==100 || T.fractal == 100)



t.icon_state = "sand"


t.fractal = T.fractal-5
fractal_list2 += t

fractal_list = fractal_list2
if(num == 2)
for(var/turf/T in list1)
if(T.icon_state == "sand")
for(var/turf/t in orange(1,T))
t.icon_state = "sand"


proc/fractal_caves(num)


if(num == 1)
var/I = rand(30,50)
while(I)
I--

var/turf/T = pick(block(locate(1,1,1),locate(maxx,maxy,maxz)))

if(T.icon_state != "water")
T.icon_state = "stone"

for(var/turf/t in orange(rand(1,6),T))
t.icon_state = "stone"

for(var/turf/t in orange(10,T))
var/i = rand(1,20)
if(i == 1)
t.icon_state = "stone"
if(T.icon_state != "stone")
var/i = rand(1,100)
if(i == 1)
T.icon_state = "stone"



var/fractal_list = list()
var/list1 = list()
for(var/turf/T in world)
if(T.icon_state == "stone")
for(var/turf/t in orange(1,T))
if(t.icon_state <> "stone")
T.fractal = 100
fractal_list += T
list1+=1
var/X = 10
var/fractal_list2 = list()

while(X)
X--



for(var/turf/T in fractal_list)
for(var/turf/t in orange(1,T))
if(t.icon_state != "water")
if(rand(T.fractal,100)==100 || T.fractal == 100)



t.icon_state = "stone"


t.fractal = T.fractal-5
fractal_list2 += t

fractal_list = fractal_list2
if(num == 2)
for(var/turf/T in list1)
if(T.icon_state == "stone")
for(var/turf/t in orange(1,T))
t.icon_state = "stone"

for(var/turf/T in world)
if(T.icon_state == "stone")
stone_list += T
proc/fractal_water(num)


if(num == 1)
var/I = rand(30,50)
while(I)
I--

var/turf/T = pick(block(locate(1,1,1),locate(maxx,maxy,maxz)))
T.icon_state = "water"
T.density=1
for(var/turf/t in orange(rand(1,4),T))
t.icon_state = "water"
t.density=1

for(var/turf/t in orange(15,T))
var/i = rand(1,20)
if(i == 1)
t.icon_state = "water"
t.density=1

var/fractal_list = list()
var/list1 = list()
for(var/turf/T in world)
if(T.icon_state == "water")
for(var/turf/t in orange(1,T))
if(t.icon_state <> "water")
T.fractal = 100
fractal_list += T
list1+=1
var/X = 10
var/fractal_list2 = list()
while(X)
X--



for(var/turf/T in fractal_list)
for(var/turf/t in orange(1,T))
if(t.icon_state == "grass")
if(rand(T.fractal,100)==100 || T.fractal == 100)



t.icon_state = "water"
t.density=1

t.fractal = T.fractal-5
fractal_list2 += t

fractal_list = fractal_list2
if(num == 2)
for(var/turf/T in list1)
if(T.icon_state == "water")
for(var/turf/t in orange(1,T))
t.icon_state = "water"
t.density=1






proc/place_spawns()

var/spawnlist = list()
for(var/turf/T in world)
if(T.icon_state == "grass")
for(var/turf/t in orange(2,T))
if(t.icon_state != "grass")
continue

spawnlist += T
var/turf/te = pick(spawnlist)
new/spawns(te)
return

turf
var/fractal=0
Oh I see, I struggled through this but managed to get it to work. If you polished this up and made it into a tutoral/snippit with comments it could help out a lot of developers on BYOND struggling with PGC.
when I made it, I went in with minimal understanding of fractals and just kind of experimented on the livestream until it worked, lol.

There are plenty of other, better libs for this anyway
Thanks for the snippets, Yut. I know that these will help me out, at least to give me an idea of a starting point.

And you mean better libraries for BYOND? I've found one, and it's quite hard to tweak and add new terrain, or even a different map size for that matter. I found it easier to just keep attempting to roll my own.
BYOND's libraries for Map generations are rather, Complicated. They may be better but they basically throw you in with no comments or understanding of how the separate parts work individually.

Making a tutorial for something like this would be a giant help, not only to others, but me as well.
I've looked at a couple libraries for map generation related features, and I feel similarly to D-Cire about it. They're too difficult to work with, and while they may be better they're also so old that they could probably be surpassed by now.

I'm not sure if I'd make use of it or not, but I know a lot of people could use a simpler learning tool for this type of thing; so I do hope you do it. Also, good luck with Zen.
lol slenderman

now why does that sound familiar...