# terrible doom terrain generator of terribleness

## Recommended Posts

Ever want to plot your favorite R^2 --> R function in doom? Well you're in luck.

In another fit of boredom I wrote a small python script that implements an idea based on this thread, that is, take a giant grid of squares, and apply some function to modify floor heights.

For example, here's 128*sin((x+y)/256) plotted over the domain ([-448,448],[-448,448]), using 8x8 tiles:

completely useless? probably. terrible framerates? if you go overboard with grid resolution, then definitely. Though the above wad runs pretty smoothly for me in glboom+.

here's a link to the code. You can use your own function by simply changing the function at the beginning of the .py file, though if you want to change the domain you'll have to alter the input grid wad. At the moment the process is extremely ghetto and will likely break at the slightest perturbance in input wad format, etc. So on the off chance anyone actually cares enough to try it themselves feel free to PM me and I can explain the nitty gritty :)

That looks quite cool.
I think mediafire is down right now maybe (and filesmelt has been off and on.. maybe the feds are going after them right now like megaupload).
Will try again later, but the pic is cool.

I've only very briefly fiddled with a "seed" grid of randomly shaded pixels, then try some sort of cellular automata rule (in multiple steps, feeding the output back to the input grid) to more smoothly "hillify" it for a landscape. But haven't figured out some sort of rule that makes hills yet (tried making each pixel the average of all its neighbors, but that mostly results in just everything fading to grey. Using pygame.

Edit: actually an idea for yours: maybe do your algorithm w/ random settings in multiple steps, each time "interfering"/adding to the previous pattern (output back into input).. might produce complex hills, not sure.
Like instead of height = bla(x, y) it'd be height = height + bla(x, y) for each step I guess (add to previously generated pattern)

You could also make your floor animated/wavy by changing one of the equation numbers over time, but might have to use acs for that since your operating on the wad in a separate program.

edit again: toomanypuppies.wad is a large file size so maybe it accidentally has doom 2 data in it (happened to me once when making doom 4x larger I think)

Downloaded both. That .py will come in quite handy if I fiddle with editing wads directly some time.

I tried these height fubctions but none work:

```        value = 128.*np.sin((x+y)/256.)
#value = min(128.*np.sin(x/(np.abs(y+10.))),200)
#value = 128.*np.exp(-((x+y)/256.)**2)
#value = 128+128.*np.sin(x/128.)*np.sin(y/128.)
```
Yours does not work too.
PrBoom complains:
```P_GetNodesVersion: using normal BSP nodes
P_CheckForZDoomNodes: ZDoom nodes not supported yet
```
And ZDoom:
```No player 1 start
```

looks awsome. can you animate it and make it looks like waves? :)

@ducon,

the problems you are having is because of how shitty toomanypuppies.wad is.

the input wad is literally just a grid of sectors, nothing else, so it will require edits in DB after being mathified. I'd actually recommend making your own template wad, as long as the file is organized in the same manner (byte size of lmps is the same, only 1 map in wad, etc) it will work. here's a description of how the script works:

-determine approximate (x,y) coords of each sector by averaging together the vertices corresponding to every linedef that references that sector
-apply function

After running the script on toomanypuppies, I went into DB, re-saved the nodes as zdsp (toomanypuppies was saved as gldsp or something, idk, I just chose a random nodebuilder until I found one that allowed for 2^16-1 sidedefs without compressing anything). Then I added textures, and fixed some stupid linedef errors because I was sloppy when I drew the grid.

So you can feed the script any wad, make your own grids (or arbitrary cluster of sectors), etc, add player starts/items/whatever, and it should be good to go.

zzzornbringer said:

looks awsome. can you animate it and make it looks like waves? :)

with enough dummy sectors and hours of tedium I imagine I could, but at that point I would probably cave and go learn acs or something :p

This is pretty badass (animating waves using acs for zdoom):

I basically succeeded in making complex animated interesting waves, even though it probably has bugs/brainfarts/etc, and never would have thought that just popping each x/y of a grid into a function to get a height could make kinda organic waves. The variables were getting complex like heightStep then heightStepStep (doublestep) or something to change the heightStep over time. Basically I have no idea what's going on, and maybe its time to stop coding it before I accidentally instruct the computer to fire a bolt of lightening at me.

Not sure what a R^2 --> R function is.
And I'm pretty sure its not possible to animate using a python script like that because acs is needed to change floors in game? Not 100% sure.
On the other hand, I wonder if acs can somehow "save" computed data OUTSIDE the program. Like maybe when you press the "s" key, it could output one of the animation "frames" data, so you can manipulate that particular frame, like process it to put that frame in a boom map instead etc. Maybe in the zdoom console or whatever it might be able to print the data but not sure if you can copy/paste the data into a text file or whatever.

hah, that's strangely mesmerizing, almost makes me wanna putz around with acs. Now if only these grids didn't eat up so many linedefs...

gggmork said:

Not sure what a R^2 --> R function is.

2 variables in, 1 out, nothing fancy. technically it should be R^2 --> Z, takes 2 real numbers (x,y), spits out an integer z for each point.

I think this step:
-determine approximate (x,y) coords of each sector by averaging together the vertices corresponding to every linedef
is unnecessary, because each x of the grid is just a linear sequence, like:
for y in range(gridheight):
for x in range(gridwidth):
would do the same thing and you could multiply by squareSize if necessary (but probably not).

zdoom wiki is key to learning built in functions etc of acs, just click acs links on left of main page. Many programming languages are practically the same, just a few differences like print(d:fart, s:butt); vs. print fart, butt.
Also I think it helps to pretty much make all numbers fixed point, at least when starting so you don't confuse the 2, like use 5.0 instead of 5. Then you have to use fixedmul() and fixeddiv() to multiply/divide 2 fixed point (decimal) numbers. U can convert from fixed to integer with >>16 and <<16.
Also all arrays have to be global (outside scripts).
And you can't have delays in functions, only scripts.
Those are the main tricky hurdles I know of. Oh also can't do an enormous amount of computation on a single tic or you'll get "runaway script", and each infinite while(1) needs a delay() in it.

Playing with a cellular automata algorithm instead now. So far I found one that takes randomized pixels and blends them over time into hills. Here's an animated gif of that happening:

http://www.freeimagehosting.net/edb4y

* start w/ "input" grid of pixels, each set to random 0 to 255 (EDIT: 0 OR 255 works better than a spectrum of greys)
* make an "output" grid of the same size
* for each output grid cell (C), check its 8 neighboring cells (from input grid)
* average neighbors and "slide" C a certain percentage toward that average
* this results in everything blending grey, so to prevent that, multiply them in a certain way to increase contrast (multiply values >=128 by a sliding value higher than 1 and values < 128 by a sliding value lower than 1)
* repeat by making output the new input

Haven't tried doing it for actual floor (and ceiling, so cavelike) heights in acs yet.

Cave generator for zdoom and whatever else uses acs (type "idclev01" to make a new random cave). Not animated, so won't kill slow computers like the previously linked wavy thing (might update that later so the horizontal stripes are animated too). But not sure if zdoom 2.6.x is required because lots of actions happen per tick in the initial computation probably and 2.6.x has a higher cap than 2.5.x:

cave generator wad (uses cellular automata style height settings (where each cell is influenced by the average of its 8 neighbors) for 14 iterations):

As a final touch, I made the border of the whole grid much more likely to have 255s than 0s (so walls tend to hug the border) and made lights vary inversely with heights.

pic:

damn ggg, looks awesome! I love the light gradients. If there was a wad format that supported a bajillion sidedefs/sectors, you could make some sweet Cave Explorer levels

As soon as I saw this thread, I immediately thought 2 things.

1) This has so much potential for awesome, and
2)gggmork is gonna turn up on this thread and do interesting stuff.

Keep doing stuff with this guys, because, well, awesome doesn't do itself.

An alternative for zdoom slopes... Interesting.

Ha ha, I'm guessing cave explorer is perry bible fellowship, don't remember seeing that one.

It was kinda annoying me how everything was mirrored over the same x/y plane in the above wad, so I generated a SECOND separate grid of 'hills' to ADD/combine with the final thing. So now its more interesting looking imo:
Might have to idclip at the beginning if it generates a wall on top of you, but liked how it "tidal waves" toward you (an accident since I just updated a row at a time per tic @start instead of the whole grid to reduce slowdown).

pic:

By the way I "borrowed" this whole grid I've been using with all its tags from a previous thing I was working on, using acs set_color() or whatever to draw every pixel of a cacodemon on a grid on the floor (in 4 animated frames, used python to get the colors), which is why the grid is 50x60 (also because bigger would have more slowdown). I'll probably post that in the monochrome project thread later. Might make it shoot sphere homing projectiles or something.

Yeah, slopes are much more efficient/less computationally intensive, but this is still interesting imo. And maybe the data could be converted into slopes somehow, but I've hardly used them and doubt it'd be easy.

Nice work. cellularAutomata2.wad is so cool! Can you make the cave bigger (preferably much larger)? If the cave was large and there was a way to populate it with monsters and items it would be really fun.

jute said:

Can you make the cave bigger?

I think it can only get about 2x bigger without collapsing in a fail of slowdown. One cheap way to make it all bigger is copy paste the whole grid against itself on the right or whatever, then scale that double pasted grid to 200% or whatever. The cave becomes wider but less detailed/intersting.

Ground monster movements mostly fail over terrain like that, even when scaled 200%. They can barely step over any bumps, almost all demons are stuck if you just randomly put monsters in the grid.

I tried to make "infinite" caves, by a warping illusion, like when you walk too far in one direction you warp backwards and the whole cave warps back with you (more like shifts back because each side smoothly leads back into the opposite side). But that was too much slowdown.

That looks like it would blow up my low end pc, is it laggy or is it compensated or something like that.

I don't think that smilar structures can be made without FPS-lag on weaker PCs.

zdoom 2.6.x runs it at a normal good speed for me (even the animated waves linked earlier). For the caves, the acs computation only happens once at the beginning, then its just a solid static but complex structure. I bought my computer used for like 40 bucks.

Sure am liking the "caves" pictures there gggmork. Somebody could make a good Doom wad out of that kind of level architecture.

Or at the very worst, a Minecraft-Doom knock off.

gggmork: Your screenshots call to mind a higher resolution version of Notch's "Cave Game" test before it became the sensation known as Minecraft.