City generator framework done

The last thing someone needs to do is grep the whole thing and rename
"citygen" to general map generation framework.
This commit is contained in:
Dany0 2015-02-05 23:12:27 +01:00
parent 7006faca24
commit 15d8a91f86
6 changed files with 155 additions and 71 deletions

43
docs/citygen_docs.txt Normal file
View File

@ -0,0 +1,43 @@
##Citygen framework by Dany0, 2015
So you want to make a new map generator? Well you've come to the right place!
In pkg/base/citygen you will find gen_city.lua which contains the basic framework.
But you want to build a new generator, so just jump right into it.
You'll need to mention your generator code file in modes.json. Add a new item there, it should probably look something like this:
{
"default" : [ "dany0/default/gen_terrain.lua", "dany0/default/gen_buildings.lua" ],
"mynewmapgenerator" : [ "anon/mynewmapgenerator/mynewmapgenerator.lua" ]
}
Note that you need at least one file in it to work. The following is a minimal code that will generate a flat terrain.
--code start
function gen_terrain(mx, my, mz)
local r, g, b = 12, 12, 12 -- base ground colour
for x=0,mx-1 do
for z=0,mz-1 do
l = {0, my - 4, my - 4, 0, b, g, r, 1} -- map pillar, check out the vxl file format for "columns"
common.map_pillar_set(x, z, l)
end
end
end
-- function load_buildings()
-- dofile(DIR_CITYGEN_BUILDINGS.."/basic_building.lua")
-- end
-- function create_city_grid()
-- end
-- function manufacture_buildings()
-- end
--code end
As you can see you need to specify - override a few functions. These functions will be called by gen_city.lua.
If you have ANY questions, ask us on the chat #iceball on i.r0t.co or file an issue on github. Enjoy!

View File

@ -29,17 +29,12 @@ local function f_new_building(...)
local s_build = this.build
function this.build(x, y, z, width, depth, height)
-- for x1=x,(x+width) do
-- for z1=z,(z+height) do
-- l = {0, 60, 60, 10, 120, 120, 120, 1}
-- common.map_pillar_set(x1, z1, l)
-- end
if depth % 2 == 0 then depth = depth + 1 end
local start_x, start_z = x, z
local current_x, current_z = start_x, start_z
local end_x, end_z = x+width, z+ height
repeat
--y = 60
chunk_header = 0
starting_block = y
ending_block = y
@ -48,18 +43,17 @@ local function f_new_building(...)
r,g,b = 120, 120, 120
type_of_block = 1
pillar_table = {chunk_header, starting_block, ending_block, air_start, b, g, r, type_of_block}
--common.map_pillar_set(current_x, current_z, pillar_table)
-- common.map_pillar_set(current_x, current_z, pillar_table)
for i=y,y+depth do
rand = math.floor(math.random()*5)%4
if rand == 0 then
map_block_set(current_x, i, current_z, 1, 35, 156, 233)
map_block_set(current_x, i+1, current_z, 1, 35, 156, 233)
map_block_set(current_x-1, i, current_z, 1, r, g, b)
map_block_set(current_x+1, i, current_z, 1, r, g, b)
elseif rand == 3 and i > y+depth - 5 then
if rand == 3 and i > y+depth - 5 then
map_block_set(current_x, i, current_z, 1, r-60, g-60, b-60)
else
map_block_set(current_x, i, current_z, 1, r, g, b)
if current_x % 2 == 0 and i < y+depth - 5 and i % 3 ~= 0 and i > y then
map_block_set(current_x, i, current_z, 1, 35, 156, 233)
else
map_block_set(current_x, i, current_z, 1, r, g, b)
end
end
end
current_x = current_x + 1
@ -72,7 +66,6 @@ local function f_new_building(...)
current_x = start_x
current_z = start_z
repeat
--y = 60
chunk_header = 0
starting_block = y
ending_block = y
@ -81,18 +74,17 @@ local function f_new_building(...)
r,g,b = 120, 120, 120
type_of_block = 1
pillar_table = {chunk_header, starting_block, ending_block, air_start, b, g, r, type_of_block}
--common.map_pillar_set(current_x, current_z, pillar_table)
common.map_pillar_set(current_x, current_z, pillar_table)
for i=y,y+depth do
rand = math.floor(math.random()*5)%4
if rand == 0 then
map_block_set(current_x, i, current_z, 1, 35, 156, 233)
map_block_set(current_x, i+1, current_z, 1, 35, 156, 233)
map_block_set(current_x, i, current_z-1, 1, r, g, b)
map_block_set(current_x, i, current_z+1, 1, r, g, b)
elseif rand == 3 and i > y+depth - 5 then
if rand == 3 and i > y+depth - 5 then
map_block_set(current_x, i, current_z, 1, r-60, g-60, b-60)
else
map_block_set(current_x, i, current_z, 1, r, g, b)
if current_z % 2 == 0 and i < y+depth - 5 and i % 3 ~= 0 and i > y then
map_block_set(current_x, i, current_z, 1, 35, 156, 233)
else
map_block_set(current_x, i, current_z, 1, r, g, b)
end
end
end
current_z = current_z + 1

View File

@ -0,0 +1,27 @@
function load_buildings()
dofile(DIR_CITYGEN_BUILDINGS.."/basic_building.lua")
end
-- function create_city_grid()
-- local mx, my, mz = common.map_get_dims()
-- we're just doing a basic "procedural" generation, but if you want
-- use this to set building x,y,z and build roads
-- then call manufacture_buildings() to build the buildings
-- end
function manufacture_buildings()
local mx, my, mz = common.map_get_dims()
local building_number = math.floor((mx-24)/12)
for i=1+12, mx-1-12, 1*(12+16) do
print("- building section "..i)
map_cache_start() -- cache here instead of outside the loop to save on RAM
for y=1+12, mz-1-12, 1*(12+16) do
rand_height = math.floor(13 + math.random()*37)
print("RAND:"..rand_height)
building = new_building({})
building.build(i + 12, my-4-rand_height, y+12, 12, rand_height, 12)
end
map_cache_end()
end
end

View File

@ -0,0 +1,23 @@
function gen_terrain(mx, my, mz)
local asphalt_r, asphalt_g, asphalt_b = 12, 12, 12 -- base ground colour
for x=0,mx-1 do
for z=0,mz-1 do
subtly_changing_the_colour = (1+(math.random()/10))
l = {0, my - 4, my - 4, 0, asphalt_b*subtly_changing_the_colour, asphalt_g*subtly_changing_the_colour, asphalt_r*subtly_changing_the_colour, 1}
if x % 8 == 0 and x % 16 ~= 0 then
l = {0, my - 4, my - 4, 0, 120*subtly_changing_the_colour, 120*subtly_changing_the_colour, 120*subtly_changing_the_colour, 1}
end
common.map_pillar_set(x, z, l)
end
end
for x=0,mx-1,16 do
for z=0,mz-1 do
if z % 4 ~= 0 then
l = {0, my - 4, my - 4, 0, 233, 233, 233, 1}
common.map_pillar_set(x, z, l)
end
end
end
end

View File

@ -14,9 +14,23 @@
You should have received a copy of the GNU Lesser General Public License
along with Ice Lua Components. If not, see <http://www.gnu.org/licenses/>.
]]
DIR_CITYGEN_BUILDINGS = "pkg/base/citygen/buildings"
DIR_CITYGEN = "pkg/base/citygen/"
DIR_CITYGEN_BUILDINGS = DIR_CITYGEN.."buildings/"
--OVERRIDE ME! I am called 1st.
function gen_terrain(mx, my, mz) end --mx = mapx = map "width"
--OVERRIDE ME! I am called 2nd.
function load_buildings() end
--OVERRIDE ME! I am called 3rd.
function create_city_grid() end
--OVERRIDE ME! I am called 4th and last.
function manufacture_buildings() end
do
local ret
local loose, user_toggles, user_settings
loose, user_toggles, user_settings = ...
local mx,my,mz,mode
@ -25,53 +39,35 @@ do
mz = user_settings["mz"] or 512
mode = user_settings["mode"] or "default"
--TODO: move terrain gen to tpl_genterrain.lua
local ret = common.map_new(mx, my, mz)
common.map_set(ret)
print("Generating asphalt")
local asphalt_r, asphalt_g, asphalt_b = 12, 12, 12 -- base ground colour
for x=0,mx-1 do
for z=0,mz-1 do
ayylmao = (1+(math.random()/10)) --this is horrible don't do this
l = {0, my - 4, my - 4, 0, asphalt_b*ayylmao, asphalt_g*ayylmao, asphalt_r*ayylmao, 1}
common.map_pillar_set(x, z, l)
end
modes_config = common.json_load(DIR_CITYGEN.."modes.json")
local i = 1
repeat
dofile(DIR_CITYGEN..modes_config[mode][i]) --so you caught a "nil" error here? setting at least one file is mandatory!
i = i + 1
until modes_config[mode][i] == nil
--this isn't supposed to be overridden --also the reason why it's hidden away here
function execute_map_gen(mx, my, mz, mode)
ret = common.map_new(mx, my, mz)
common.map_set(ret)
print("Generating terrain")
gen_terrain(mx, my, mz)
print("Loading buildings")
load_buildings()
--print("Loading prefabs")
--load_kv6()
print("Generating the city outline")
create_city_grid()
print("Making buildings")
--map_cache_start() -- please handle map caching yourselves!
manufacture_buildings()
--collectgarbage() --waiting for this to be implemented
print("gen finished")
return ret, "citygen_"..mode.."("..mx..","..mz..","..my..")"
end
print("Generating lines")
for x=0,mx-1,16 do
for z=0,mz-1 do
if z % 4 ~= 0 then
l = {0, my - 4, my - 4, 0, 233, 233, 233, 1}
common.map_pillar_set(x, z, l)
end
end
end
--TODO: read the mode from JSON city settings
--TODO: mode should point to tpl_gencity.lua to generate the city grid
--TODO: grid should probably be 2d, array of lines, then buildings should adapt to terrain
print("Loading buildings")
dofile(DIR_CITYGEN_BUILDINGS.."/basic_building.lua")
-- building1 = new_building({})
-- building1.build(mx/2, my-4-12, mz/2, 12, 12, 12)
print("Making buildings")
local building_number = math.floor((mx-24)/12)
for i=1, mx-1, 12+16 do
print("- building section "..i)
map_cache_start() -- cache here instead of outside the loop to save on RAM
for y=1, mz-1, 12+16 do
building = new_building({})
building.build(i + 12, my-4-12, y+12, 12, 12, 12)
end
map_cache_end()
end
--collectgarbage() --waiting for this to be implemented
print("gen finished")
return ret, "citygen("..mx..","..mz..","..my..")"
end
return execute_map_gen(mx, my, mz, mode)
end

View File

@ -0,0 +1,3 @@
{
"default" : [ "dany0/default/gen_terrain.lua", "dany0/default/gen_buildings.lua" ]
}