<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://olddev.minetest.org/index.php?action=history&amp;feed=atom&amp;title=Mapgen_memory_optimisations</id>
	<title>Mapgen memory optimisations - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://olddev.minetest.org/index.php?action=history&amp;feed=atom&amp;title=Mapgen_memory_optimisations"/>
	<link rel="alternate" type="text/html" href="https://olddev.minetest.org/index.php?title=Mapgen_memory_optimisations&amp;action=history"/>
	<updated>2026-04-15T01:19:04Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.38.7</generator>
	<entry>
		<id>https://olddev.minetest.org/index.php?title=Mapgen_memory_optimisations&amp;diff=108&amp;oldid=prev</id>
		<title>&gt;Wuzzy: Remove Misc category</title>
		<link rel="alternate" type="text/html" href="https://olddev.minetest.org/index.php?title=Mapgen_memory_optimisations&amp;diff=108&amp;oldid=prev"/>
		<updated>2020-06-26T19:52:19Z</updated>

		<summary type="html">&lt;p&gt;Remove Misc category&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{LuaTips}}&lt;br /&gt;
&lt;br /&gt;
''This page is based on Paramat's [https://forum.minetest.net/viewtopic.php?t=16043 forum topic] and has been updated for Minetest 5.0.0.''&lt;br /&gt;
&lt;br /&gt;
Lua map generators can use excessive memory if they are not using these 3 optimisations. Not using these optimizations can eventually lead to OOM (out-of-memory) errors because the Lua mapgen wasted way too much memory. Applying this advice is '''strongly recommended''', and should make OOM errors much less likely. But there is no guarantee this will fix all OOM errors, your mapgen might still use excessive memory for other reasons, or the computer just has very limited memory.&lt;br /&gt;
&lt;br /&gt;
== Perlin noise objects: Only create once ==&lt;br /&gt;
&lt;br /&gt;
The noise object is created by &amp;lt;code&amp;gt;minetest.get_perlin_map()&amp;lt;/code&amp;gt;.&lt;br /&gt;
It has to be created inside &amp;lt;code&amp;gt;register_on_generated()&amp;lt;/code&amp;gt; to be usable, but only needs to be created once, many mapgen mods create it for every mapchunk, this consumes memory unnecessarily.&lt;br /&gt;
&lt;br /&gt;
Localise the noise object outside &amp;lt;code&amp;gt;register_on_generated()&amp;lt;/code&amp;gt; and initialise it to &amp;lt;code&amp;gt;nil&amp;lt;/code&amp;gt;.&lt;br /&gt;
See the code below for how to create it once only.&lt;br /&gt;
The creation of the perlin noise tables with &amp;lt;code&amp;gt;get_3d_map_flat()&amp;lt;/code&amp;gt; etc. is done per mapchunk&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
-- Initialize noise objects to nil&lt;br /&gt;
&lt;br /&gt;
local nobj_terrain = nil&lt;br /&gt;
local nobj_biome = nil&lt;br /&gt;
&lt;br /&gt;
-- ...&lt;br /&gt;
-- ...&lt;br /&gt;
&lt;br /&gt;
-- On generated function&lt;br /&gt;
minetest.register_on_generated(function(minp, maxp, seed)&lt;br /&gt;
   -- ...&lt;br /&gt;
   -- ...&lt;br /&gt;
   nobj_terrain = nobj_terrain or minetest.get_perlin_map(np_terrain, chulens3d)&lt;br /&gt;
   nobj_biome = nobj_biome or minetest.get_perlin_map(np_biome, chulens2d)&lt;br /&gt;
   &lt;br /&gt;
   nobj_terrain:get_3d_map_flat(minpos3d, nvals_terrain)&lt;br /&gt;
   nobj_biome:get2d_map_flat(minpos2d, nvals_biome)&lt;br /&gt;
   -- ...&lt;br /&gt;
   -- ...&lt;br /&gt;
end)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Perlin noise tables: Re-use a single table ==&lt;br /&gt;
&lt;br /&gt;
The Lua table that stores the noise values for a mapchunk is big, especially for 3D noise (80&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt; = 512000 values).&lt;br /&gt;
Many Lua mapgens are creating a new table for every mapchunk, while the previous tables are only cleared out slowly by garbage collection, resulting in a large and unnecessary memory use.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;code&amp;gt;buffer&amp;lt;/code&amp;gt; parameter was added in 0.4.13 to avoid this, a single table is re-used by overwriting the former values.&lt;br /&gt;
&lt;br /&gt;
 For each of the functions with an optional `buffer` parameter:  If `buffer` is not&lt;br /&gt;
 nil, this table will be used to store the result instead of creating a new table.&lt;br /&gt;
  &lt;br /&gt;
 #### Methods&lt;br /&gt;
 * `get_2d_map_flat(pos, buffer)`: returns a flat `&amp;lt;size.x * size.y&amp;gt;` element array of 2D noise&lt;br /&gt;
 with values starting at `pos={x=,y=}`&lt;br /&gt;
 * `get_3d_map_flat(pos, buffer)`: Same as `get_2d_map_flat`, but 3D noise&lt;br /&gt;
&lt;br /&gt;
Localise the noise buffer outside &amp;lt;code&amp;gt;register_on_generated()&amp;lt;/code&amp;gt;&lt;br /&gt;
Use the &amp;lt;code&amp;gt;buffer&amp;lt;/code&amp;gt; parameter in &amp;lt;code&amp;gt;get_3d_map_flat()&amp;lt;/code&amp;gt; etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
-- Localise noise buffers&lt;br /&gt;
local nvals_terrain = {}&lt;br /&gt;
local nvals_biome = {}&lt;br /&gt;
-- ...&lt;br /&gt;
-- ...&lt;br /&gt;
-- On generated function&lt;br /&gt;
minetest.register_on_generated(function(minp, maxp, seed)&lt;br /&gt;
   -- ...&lt;br /&gt;
   -- ...&lt;br /&gt;
   nobj_terrain:get3d_map_flat(minpos3d, nvals_terrain)&lt;br /&gt;
   nobj_biome:get2d_map_flat(minpos2d, nvals_biome)&lt;br /&gt;
   -- ...&lt;br /&gt;
   -- ...&lt;br /&gt;
end)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Lua voxelmanip table: Re-use a single table ==&lt;br /&gt;
&lt;br /&gt;
The Lua table that stores the node content IDs for a mapchunk plus the mapblock shell is big (112&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt; = 1404928 values).&lt;br /&gt;
Many Lua mapgens are creating a new table for every mapchunk, while the previous tables are only cleared out slowly by garbage collection, resulting in a large and unnecessary memory use.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;code&amp;gt;buffer&amp;lt;/code&amp;gt; parameter was added in 0.4.13 to avoid this, a single table is re-used by overwriting the former values.&lt;br /&gt;
&lt;br /&gt;
In Minetest 0.4.15, a &amp;lt;code&amp;gt;buffer&amp;lt;/code&amp;gt; parameter was also added to &amp;lt;code&amp;gt;get_param2_data()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 * `get_data([buffer])`: Retrieves the node content data loaded into the `VoxelManip` object&lt;br /&gt;
     * returns raw node data in the form of an array of node content IDs&lt;br /&gt;
     * if the param `buffer` is present, this table will be used to store the result instead&lt;br /&gt;
 * `get_param2_data([buffer])`: Gets the raw `param2` data read into the `VoxelManip` object&lt;br /&gt;
     * Returns an array (indices 1 to volume) of integers ranging from `0` to `255`&lt;br /&gt;
     * If the param `buffer` is present, this table will be used to store the result instead&lt;br /&gt;
&lt;br /&gt;
Localise the data buffer outside &amp;lt;code&amp;gt;register_on_generated()&amp;lt;/code&amp;gt;.&lt;br /&gt;
Use the buffer in &amp;lt;code&amp;gt;get_data()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;get_param2_data()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
-- Localise data buffer&lt;br /&gt;
local data = {}&lt;br /&gt;
&lt;br /&gt;
-- On generated function&lt;br /&gt;
minetest.register_on_generated(function(minp, maxp, seed)&lt;br /&gt;
   -- ...&lt;br /&gt;
   -- ...&lt;br /&gt;
   local vm, emin, emax = minetest.get_mapgen_object(&amp;quot;voxelmanip&amp;quot;)&lt;br /&gt;
   local area = VoxelArea:new{MinEdge = emin, MaxEdge = emax}&lt;br /&gt;
   vm:get_data(data)&lt;br /&gt;
   -- ...&lt;br /&gt;
   -- ...&lt;br /&gt;
end)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Mapgen]]&lt;/div&gt;</summary>
		<author><name>&gt;Wuzzy</name></author>
	</entry>
</feed>