Hi !
I'm new to Godot, and to game development in general ( already tried some projects in the past but didn't stick to them )
I'd like to first of all say how of a nice community this is, a really positive and non toxic one, and that's appreciated.
To the problem now, I'm a software engineer so don't be afraid to throw stuff at me :)
I'm generating a fixed size procedural map using simplex noise, for this example I'll be generating a 2500 x 2500 map, tiles are 32 x 32 pixels.
The problem is I have quite a big of a RAM usage ( or maybe it's normal for those dimensions ?), as I'm hitting around the 1.5GB RAM when running the game. As it's the start of my game, so my core foundation, I'd like to already optimize this a little bit.
I'll just explain how I got to this point as it isn't much yet.
The first thing I did was importing the textures, just by putting them in the folder, re-importing them without a filter. Then I made a scene (2D Node), added each texture as a sprite, no collisions, just a sprite with the texture in it, then I exported that scene to a tile set resource.
Assets & TileSet picture
After that, I made my noise generator script which just fills and array with heights for all my x and y values.
extends Node2D
class_name NoiseGenerator
static func generate(width: int, height: int, mapSeed: int, octaves: int, period: int, lacunarity: float, persistence: float) -> Array:
var generator = OpenSimplexNoise.new()
generator.seed = mapSeed
generator.octaves = octaves
generator.period = period
generator.lacunarity = lacunarity
generator.persistence = persistence
var heightMap: Array = []
heightMap.resize(height * width)
for y in height:
for x in width:
heightMap[y * width + x] = generator.get_noise_2d(x, y)
return heightMap
After that I created my "Terrain" tilemap, which consists of the base layer of my map. It takes my heightmap, width & height as parameters and just matches the right tile based on the height ( the reason I match it in the dictionary as 'heightValue': "index", is to be able to re-use the same tile on a different height value, let's say I want to make grass plateaus on a mountain, the dictionary can't have duplicate keys with different values so I use the boundary as key & the tile index as value.)
extends TileMap
class_name Terrain
enum TILES {
None = -1
DeepWater,
Water,
Sand,
Grass,
LightDirt,
Dirt,
Snow,
}
const tile_heights = {
-0.75: TILES.DeepWater,
-0.25: TILES.Water,
-0.2: TILES.Sand,
0.35: TILES.Grass,
0.4: TILES.LightDirt,
0.8: TILES.Dirt,
1.0: TILES.Snow,
}
func generate_terrain(width: int, height: int, height_map: Array) -> void:
for y in height:
for x in width:
var cell_height = height_map[y * width + x]
var terrain = get_terrain_type(cell_height)
set_cell(x, y, terrain)
func get_terrain_type(height: float) -> int:
for tile_height in tile_heights:
if height <= tile_height:
return tile_heights[tile_height]
return TILES.None
And finally I have a map scene where I will manage the different layers of my map.
extends Node2D
class_name Map
const MAP_WIDTH = 2000
const MAP_HEIGHT = 2000
const NATURE_NOISE_OCTAVES = 4
const TERRAIN_NOISE_OCTAVES = 8
const NOISE_PERIOD = 16
const NOISE_LACUNARITY = 0.6
const NOISE_PERSITENCE = 2
func _ready() -> void:
randomize()
var mapSeed = randi()
var terrain_height_map = $NoiseGenerator.generate(MAP_WIDTH, MAP_HEIGHT, mapSeed, TERRAIN_NOISE_OCTAVES, NOISE_PERIOD, NOISE_LACUNARITY, NOISE_PERSITENCE)
$Terrain.generate_terrain(MAP_WIDTH, MAP_HEIGHT, terrain_height_map)
var nature_height_map = $NoiseGenerator.generate(MAP_WIDTH, MAP_HEIGHT, mapSeed, NATURE_NOISE_OCTAVES, NOISE_PERIOD, NOISE_LACUNARITY, NOISE_PERSITENCE)
$Nature.generate_nature(MAP_WIDTH, MAP_HEIGHT, nature_height_map, terrain_height_map)
As you can see, I go trough this process again but for my "Nature" layer, which consists of a height map of the same seed but with more octaves, and based on those values + the values of the terrain map ( still need to figure a way out to get a generic way of doing this, but that's another question ), I generate for example trees as for now. This part is not important as I had the RAM usage "issue" before implementing this part.
The result is good, I'll add a picture of it too, but it's just the RAM usage that concerns me, I hope you guys can figure something out, and sorry for the long post !
Example of generation ( the brown dots are my temporary tree textures :) )
Example picture
Thank you !