Infinite maps for games!

Community Forums/Showcase/Infinite maps for games!

Ryan Burnside(Posted 2008) [#1]
I've set out to create code that will make random maps for games. The code is slow right now but it only needs to be executed once per map. I've used Perlin noise and a normalize function to create a terrain array. I show the terrain array as an image in the demo but you could generate the image then map it onto a 3D mesh of the same values.

I hope this inspires some folks. Imagine a game with soldiers on land and in boats in the water with infinite playmaps. Pretty cool.

I don't know if I'll make a full blown engine but this should at least inspire a few people. I'm a sloppy coder and it could be optimized pretty heavily.

Teaser screens!






Source, and .exe (look for link at bottom of page)

Updated as of 7-14-08
http://www.filesend.net/download.php?f=5c083b9a14f25603d204b912a7c85d78


Xip(Posted 2008) [#2]
Looks good to me :)
might check out the code later :D


_33(Posted 2008) [#3]
This looks really good. The height levels are a little confusing (colors) but with small enhancement this could be ace.


Ryan Burnside(Posted 2008) [#4]
I'll work on this more if time permits. I have many little things going on this week.


WMSteadman(Posted 2008) [#5]
Um.. I failed to see how this was an infinite map. admitedly I do not have BlitzMax so I couldn't have a look at your source, so I was greatful you provided an exe. However, pressing any key quits the app.

Only having seen a couple of static height maps, I can't see the infinite bit.

That aside, the quality of the maps look pretty good and very usable in the genre you suggest.


Torrente(Posted 2008) [#6]
The title says "infinite maps," perhaps meaning that you can make an infinite amount of them -- or at least enough so that you can't tell the difference.


slenkar(Posted 2008) [#7]
very generous, thanks,
does it have the capability to create several maps that tile together? or can it create maps that are tileable with themselves?


WMSteadman(Posted 2008) [#8]
Good point Torrente. I don't know how I missed that simple symantics. D'oh!

Apologies to Ryan. I was looking for more than was there. :)

Still look good though.


Ginger Tea(Posted 2008) [#9]
aye pic 2 and 3 look like they are a few missing pixels from being able to join up with each other


Ryan Burnside(Posted 2008) [#10]
Ok guys I'll take a look I wonder why the last set of pixels is not written to.

Anyway if you want maps to tile up you must force the edges of one array to be the same on the edge you want to link up with.

You just need to match up the border values

xxxa axxx
xxxb bxxx
xxxc cxxx
xxxd matches to the left with dxxx

this noise sample would self-tile

abcd
exxe
fxxf
abca


_33(Posted 2008) [#11]
The thing that seems odd with the maps generated is that the colors are not representative of a heightmap. The green must go from dark for low altitude to bright for high altitude, not the other way around. There would need some modifications for it to be a heightmap. But this is a good start anyhow. Still, with the source unavailable it seems we can't do much, and this is BMX code I believe no?


Ginger Tea(Posted 2008) [#12]
aye ive only ever seen grey scale height maps
but this looks like
blue ocean
sandy beach
grassy green hills


Kalisme(Posted 2008) [#13]
Ohhhh!
I clicked on this expecting a nethack kind of map generation... I've been trying to do one for a while... I think I finally figured most of it out, just have to type it all out :( (bug testing is annoying)

Your idea looks great. I presume it's able to be used as height maps for creating large terrains... I wonder if it would be possible to add in scenery generation sort of based off POPULUS logic... if there's enough flat land (or just level land) it might randomly place a preconstructed mesh of a house or a tree...
I dunno... But looks really interesting.


Ryan Burnside(Posted 2008) [#14]
@ Kalisme

I have already created a dungeon generator for nethack style games.
http://www.blitzbasic.com/codearcs/codearcs.php?code=2281


Ok so I have made some progress. This is more of a texture generator than a heightmap generator. However if you load the grayscale image you will get a sort of heightmap generation tool. The textures are now seamless. The height values range from 0 to 255. This is just a demo not a full blown engine.

7 layer perlin noise


THE NEW VERSION
http://www.filesend.net/download.php?f=5c083b9a14f25603d204b912a7c85d78


slenkar(Posted 2008) [#15]
it looks a lot better now,
thanks for that dungeon generator too!

If I had to offer some constructive criticism I would say it looks a little too blurred.but otherwise great job

where are you thinking of taking this in the future?


_33(Posted 2008) [#16]
Much better. So the combination of the texture and heighmap would give for a useful terrain system. My game project actually requires terrain that loops on itself. I don,t know how this would look for generating a planetscape. You would need maps at least twice as wide for that, but it might be useful there too.


Axel Wheeler(Posted 2008) [#17]
(Note to self: Putting the word Infinite in the subject of a post acts like a buglight for responses... :) )

Nice job!

(My posts tend to be long winded and rambling, and this is no exception. I'm just trying to be as helpful as I can given my own experience.)

It looks like you are thinking more in terms of a top-down game with fleets and armies. Risk and Diplomacy come to mind.

It also looks like you are trying to provide an infinite variety of game boards. One game I know of that does this is called Slay:

http://www.windowsgames.co.uk/slay.html

It's not Blitz and it's a hex-based game, so no real terrain mapping, but it's an awesome game, partly because of the enormous variety of boards. The variety is managed with randomizer seed numbers acting as board numbers; i.e. board number 1, 2, 3, etc. Presumably these are the actual seeds used in the randomizer: seedrnd(boardseed) instead of seedrnd(millisecs()).

I think Slay has an editor as well; in your game you might instead want to use a random button and/or a next button to traverse the seeds, and a bookmarking system to save the favorites boards. That would be cool.

Tiling:

I wanted to put my two cents in regarding the tiling issue. With Perlin noise I know of two general approaches: Pre- and Post- generation.

Pre-generation is done in each of the original Perlin sub-arrays by setting the right and bottom edges equal to the opposide side value. This (supposedly) causes the resulting noise map to tile seamlessly.

Post-generation is necessary if you are making modifications to the Perlin noise map after generation that might involve the edges (and would thus ruin the tiling). The issue is surprisingly weird and difficult, but kind of challenging and fun if you have the time and the need.

Below is my silly treatise on this issue, which is what happened to me when I tried it. What you have already looks good enough for your purposes, but someone here may find this amusing or even interesting:

At first you think, "Well, I'll just take the right 25% or so and gradually adjust it toward the opposite edge value". That is, average the existing height with the opposite edge and weight that average with the distance from the edge.
Result; stretched-looking and not good.

Then you think, "Ok, instead I'll average the current value not with the opposite edge but with the corresponding pixel at the same distance from the opposite side." (Let's call this the reference point)
The result is much better but you'll notice a ridge (or valley) along the seam, which becomes like a mirror image as you get closer to the edge.

Then you realize, "Aha! I need to invert that value vertically so the slopes approach the edge from opposite vertical directions! I'll average the current value not with the reference point itself, but with the inverse of that value (up vs. down). But what is the inverse? It must be the value that is the same vertical distance from the edge pixel, but in the opposite vertical direction. But wait! Oh no! That could easily go beyond the height range of the map. And no, you can't just clamp it, Clampett. You'll have weird plateaus all around the edges of your map.

You have to take not just the same vertical distance from the edge point, but rather the same vertical _proportion_ of the range from the height of the edge pixel to the maximum height (or minimum height, depending which way you are going). Then you say "Ouch my head hurts!"

Here is some code that does this for my terrain editor (WIP). It only does the right side, so you'd have to adapt it for the bottom. It is buggy and confusing and I don't even remember how it works exactly, but here it is:



I hope this was useful for someone. Good luck with the project Ryan!


Ryan Burnside(Posted 2008) [#18]
Thanks for that at length post. I do tend to read them.

It's important that coders share information freely sometimes. It encourages quicker progression and new tecniques.

I plan to make some option for sphere mapping with distortion correction incase people want to texture planets and such.


This is just a learning project. I like to learn and pass on what I learn. It helps people learn things more quickly and saves them a step.

This is not for any specific game. Well ok it is, I plan to cubemap some cloud texture to my objects and then rotate them and such giving the illusion of a mirrored surface. The game is going to be an arcade style shmup.

I like these kinds of things because in a sense it is like letting my computer be the artist for a change. I just give it some rules.

I see these kinds of patterns in nature and it's like having a never ending world inside my computer.

Just imagine:

A house procedurally generated on a procedural landscape with hills topped with lindenmayer trees set against a perlin noise sky. Your computer has a whole world inside, you just have to write the rules.

I would like to see more procedural content in games media often makes up the largest parts of the game. I have an interest in procedural music too and might look into that next.

Now you can make a cloud map by simply making that black to white gradient blue to white.



I will tell you how to make your own gradients.

I have photoshop elements 2.0 (about as crappy as you can go)

first make an empty image that is 256 pixels wide by 1 pixel tall.

Next create a gradient layer and make sure that the direction is set to 0.

Then just save to a png.


Axel Wheeler(Posted 2008) [#19]
Yeah I saw those line graphics. I figured that's what was going on. Thanks.

You might want to check out Filter Forge as well. It's like the Photoshop filter system but just the filters. And the node-based editor is fun and easy, as is the online community gallery; see a filter you like, click Download, Filter Forge pulls it down, installs it and runs it immediately.

It's expensive but there's a long free demo period and if you upload filters that generate enough interest you can get a free copy.

http://www.filterforge.com/

Of course, that won't work for infinite ingame generation, but it will certainly let you design (or find in the gallery) what you are looking for and see how it's done. Then you know you are on the right track when you start coding. I highly recommend it.

My own program from which my code above was yanked can be seen at:

http://www.blitzbasic.com/gallery/view_pic.php?id=1827&gallery=&page=3

It may come out someday :)

Keep livin' the dream!


slenkar(Posted 2008) [#20]
yeah that program is what I and a lot of others would be interested in.
You could create a large world with a click of a button


Axel Wheeler(Posted 2008) [#21]
I'll try to get something demo'd shortly. Keep in mind, though, it doesn't do objects, just terrains and textures. But the resulting textures could be used by themselves as a top-down map for 2D games as Ryan is doing.

I'll post something on here when I have something to show...

Hey Ryan, just looking at those clouds; ever consider a skybox generator? I see a skysphere generator in here (see link) but not a skybox one.

http://www.blitzbasic.com/Community/posts.php?topic=31940


Ryan Burnside(Posted 2008) [#22]
Axel, I do plan to make a skybox and skysphere mapping option. I'm a bit busy with work at the moment but know exactly what and how to do it. I suppose an engine might be more useful to people than a demo. Are there any options to export array to different image types?


Axel Wheeler(Posted 2008) [#23]
savebuffer() saves either the frontbuffer() or backbuffer() to a .bmp file. Other formats require additional functions which may be in the code archives but I haven't checked.

sswift has a great screeshot function using savebuffer(), which I think is in the code archives and which I might have modified somewhat for my purposes. It checks for the next available filename and saves the frontbuffer(). Here it is:

; -------------------------------------------------------------------------------------------------------------------
; This function saves a screenshot to the cureent directory, incrementing the file counter if neccessary.
; -------------------------------------------------------------------------------------------------------------------
Function SaveScreenshot(prefix$)

    iFileNumber% = 0
    Repeat
        iFileNumber = iFileNumber + 1
        sFileName$ = "Screenshot-" + prefix$ + String$("0", 3 - Len(Str$(iFileNumber))) + iFileNumber + ".bmp"
    Until Not(FileType(sFileName$))
    
    SaveBuffer FrontBuffer(), sFileName$

End Function


Just hit F12 (or whatever you assign to the function) and check your program directory for the .bmp file.

I don't know if savebuffer() works on an imagebuffer or texturebuffer, but if not then just copyrect to frontbuffer() or backbuffer().