Procedural Generation?
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
Procedural Generation?
Is there a way to procedurally generate terrain for example by adding on maps and stuff?
PM me on here or elsewhere if you'd like to discuss porting your game to Nintendo Switch via mazette!
personal page and a raycaster
personal page and a raycaster
- Robin
- The Omniscient
- Posts: 6506
- Joined: Fri Feb 20, 2009 4:29 pm
- Location: The Netherlands
- Contact:
Re: Procedural Generation?
Yes. It's a trivial matter when you have Lua at your disposal (now good PG is a bit harder, that will require quite a lot of work, but then anything worth doing does).
Help us help you: attach a .love.
Re: Procedural Generation?
There is a lot of information available about procedural map generation, especially in the RogueLike forums and web sites. Here's an example of somebody who did it with Love2d and Lua.
But do a quick Google search with the key terms "procedural map generation", "lua" and "love2d" and you'll find many others. Your best bet is to learn Lua well and start by implementing an algorithm somebody else came up with ... then experiment until you have what you want.
But do a quick Google search with the key terms "procedural map generation", "lua" and "love2d" and you'll find many others. Your best bet is to learn Lua well and start by implementing an algorithm somebody else came up with ... then experiment until you have what you want.
- Roland_Yonaba
- Inner party member
- Posts: 1563
- Joined: Tue Jun 21, 2011 6:08 pm
- Location: Ouagadougou (Burkina Faso)
- Contact:
Re: Procedural Generation?
I wrote a few things that do procedural generation. The minicraft style terrain is done via some kind of smooth noise function, like perlin noise. I used a fractal technique (I forget the exact name) where it'll generate 4 random height values at the corners of the world, and then calculate the middle point's height as the average of the 4 plus some random factor. Then it recursively generates the mid point of the 4 quadrants contained. After writing the code, I wandered around in an infinitely generating world, looking at all of the 2d terrain, and realized how boring it was, so I stopped.
Here's the code for the random stuff. PlainMap (the superclass of Noisemap) is just a trivial 2d array define by width and height, that provides set and get functions that do range checking, so I'll omit it.
In order to make the world seamless, and dynamically generation: it divides up an endless 2d array into chunks, it pulls in the 8 surrounding chunks around the player's current chunk, and creates new chunks for nil blocks, picking the corners according to what existing chunks already have, or randomly generating whats missing. To produce an actual look, I cut the height map up so that the bottom of the range is water, the middle is dirt, the top is rock (muontain?).
It's a neat concept, maybe I'll package a love for it, but it's kinda dull overall.
Here's the code for the random stuff. PlainMap (the superclass of Noisemap) is just a trivial 2d array define by width and height, that provides set and get functions that do range checking, so I'll omit it.
Code: Select all
NoiseMap = class( PlainMap )
function NoiseMap:init( x, y, w, h, c1, c2, c3, c4 )
PlainMap.init(self, x, y, w, h)
self.data = {}
self:divide( x, y, self.width+1, self.height+1, c1, c2, c3, c4 )
end
function NoiseMap:displace( v )
local max = v / (self.width + self.height) * 3
return (math.random() - 0.5) * max
end
function NoiseMap:divide( x, y, w, h, c1, c2, c3, c4 )
if w > 2 or h > 2 then
local nW = w/2
local nH = h/2
local mid = ( c1 + c2 + c3 + c4 ) / 4 + self:displace(nW, nH)
if mid < 0 then mid = 0 elseif mid > 1 then mid = 1 end
local edge1 = (c1 + c2) / 2
local edge2 = (c2 + c3) / 2
local edge3 = (c3 + c4) / 2
local edge4 = (c4 + c1) / 2
self:divide(x, y, nW, nH, c1, edge1, mid, edge4);
self:divide(x + nW, y, nW, nH, edge1, c2, edge2, mid);
self:divide(x + nW, y + nH, nW, nH, mid, edge2, c3, edge3);
self:divide(x, y + nH, nW, nH, edge4, mid, edge3, c4);
else
local c = (c1+c2+c3+c4)/4
self:set( math.floor(x), math.floor(y), c )
end
end
It's a neat concept, maybe I'll package a love for it, but it's kinda dull overall.
Re: Procedural Generation?
And the question is also even more trivial when this forum is packed with a lot of threads about the subject and lots of examples of things being generated.Robin wrote:Yes. It's a trivial matter when you have Lua at your disposal (now good PG is a bit harder, that will require quite a lot of work, but then anything worth doing does).
Even searching for that search.php?st=0&sk=t&sd=d&sr=posts&keyw ... eration%3F gives a lot to be entertaining.
BTW Davidbot I tried to check how your projects are going but your barturov site seems be gone.
Re: Procedural Generation?
midpoint displacement technicInny wrote:I wrote a few things that do procedural generation. The minicraft style terrain is done via some kind of smooth noise function, like perlin noise. I used a fractal technique (I forget the exact name) where it'll generate 4 random height values at the corners of the world, and then calculate the middle point's height as the average of the 4 plus some random factor. Then it recursively generates the mid point of the 4 quadrants contained. After writing the code, I wandered around in an infinitely generating world, looking at all of the 2d terrain, and realized how boring it was, so I stopped
i made one too :
3D
Code: Select all
math.randomseed(os.time())
sqaures ={
{--one sqaure
{0,0,math.random(1,4)},--left up
{10,0,math.random(1,4)},--right up
{0,10,math.random(1,4)},--left down
{10,10,math.random(1,4)},--right down
}
}
irritations = 9
rratio = 2^irritations
ratio = 2^irritations
function routine()
for i = 1,#sqaures do
v = sqaures[i]
--make NEW points
d = {--middle
(v[1][1]+v[2][1]+v[3][1]+v[4][1])/4,--x
(v[1][2]+v[2][2]+v[3][2]+v[4][2])/4,--y
(v[1][3]+v[2][3]+v[3][3]+v[4][3])/4+math.random(-ratio,ratio)--z
}
np2 = {--top middle
(v[1][1]+v[2][1])/2,
(v[1][2]+v[2][2])/2,
(v[1][3]+v[2][3])/2
}
np3 = {--right middle
(v[2][1]+v[4][1])/2,
(v[2][2]+v[4][2])/2,
(v[2][3]+v[4][3])/2
}
np4 = {--bottom middle
(v[3][1]+v[4][1])/2,
(v[3][2]+v[4][2])/2,
(v[3][3]+v[4][3])/2
}
np5 = {--left middle
(v[1][1]+v[3][1])/2,
(v[1][2]+v[3][2])/2,
(v[1][3]+v[3][3])/2
}
--make 4 sqaures of 1 with the new points
s1 = {v[1],np2,np5,d}--left up
s2 = {np2,v[2],d,np3}--right up
s3 = {np5,d,v[3],np4}--left down
s4 = {d,np3,np4,v[4]}--right down
--add sqaures, and delete the old one
sqaures[i] = s1--old on replaced(deleted)
table.insert(sqaures,s2)
table.insert(sqaures,s3)
table.insert(sqaures,s4)
end
end
for i = 1,irritations do
routine()
ratio = ratio/2
end
imgData = love.image.newImageData(800,600)
for i,s in pairs(sqaures) do
for i,p in pairs(s) do
c = p[3]
if c < 0 then
c = 0
end
imgData:setPixel(p[1]*51, p[2]*51,c*(255/rratio),c*(255/rratio),c*(255/rratio), 255)
end
end
img = love.graphics.newImage(imgData)
function love.draw()
love.graphics.draw(img,0,0,0,1,1,0,0)
end
Code: Select all
function love.load()
smoothness = 10
iterations = 9
points = {0,0}
math.randomseed(os.time())
end
function love.draw()
love.graphics.print("smoothness = "..smoothness ,10,10)
for i = 1, #points - 1 do
love.graphics.line(i, math.floor(points[i]+0.5)+250, i+1, math.floor(points[i+1]+0.5)+250)
end
end
function love.keypressed(key)
if key == "down" and smoothness > 1 then
smoothness = smoothness - 1
run()
elseif key == "up" then
smoothness = smoothness + 1
run()
end
end
function run()
beginratio = math.floor((9^2-1)/(smoothness / 10))
points = {0,0}
for i = 1, iterations do
routine()
beginratio = beginratio/2
end
end
function routine()
add = 0
for point = 1, #points do
point = point+add
if point >= #points then return end
point1 = points[point]
point2 = points[point+1]
point3 = (point1+point2)/2+math.random(-beginratio,beginratio)
table.insert(points, point+1, point3)
add = add+1
end
end
Who is online
Users browsing this forum: No registered users and 148 guests