<?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=MetaDataRef</id>
	<title>MetaDataRef - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://olddev.minetest.org/index.php?action=history&amp;feed=atom&amp;title=MetaDataRef"/>
	<link rel="alternate" type="text/html" href="https://olddev.minetest.org/index.php?title=MetaDataRef&amp;action=history"/>
	<updated>2026-04-16T00:00:37Z</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=MetaDataRef&amp;diff=112&amp;oldid=prev</id>
		<title>&gt;ROllerozxa at 14:06, 25 October 2022</title>
		<link rel="alternate" type="text/html" href="https://olddev.minetest.org/index.php?title=MetaDataRef&amp;diff=112&amp;oldid=prev"/>
		<updated>2022-10-25T14:06:29Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{UnofficialLua}}&lt;br /&gt;
&lt;br /&gt;
See [https://minetest.gitlab.io/minetest/class-reference/#metadataref MetaDataRef] and [https://minetest.gitlab.io/minetest/metadata/ Metadata] in the Lua API documentation.&lt;br /&gt;
&lt;br /&gt;
'''Warning''' all metadata is sent to client, don't store sensitive stuff here.&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
This adds a chatcommand, that opens a formspecs in that you can change the color and name of an item, if you havethe rename priv.&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
minetest.register_privilege(&amp;quot;rename&amp;quot;, {&lt;br /&gt;
	description = &amp;quot;Can rename Items and Nodes&amp;quot;,&lt;br /&gt;
	give_to_singleplayer = false&lt;br /&gt;
})&lt;br /&gt;
&lt;br /&gt;
minetest.register_chatcommand(&amp;quot;rename&amp;quot;, {&lt;br /&gt;
    func = function(name, param)&lt;br /&gt;
        minetest.show_formspec(name, &amp;quot;rename:renameform&amp;quot;,&lt;br /&gt;
                &amp;quot;size[4,4.5]&amp;quot; ..&lt;br /&gt;
                &amp;quot;label[0,0;rename]&amp;quot; ..&lt;br /&gt;
                &amp;quot;field[1,1.5;3,1;name;New Node/Item name;]&amp;quot; ..&lt;br /&gt;
								&amp;quot;field[1,2.5;3,1;color;New Color;]&amp;quot; ..&lt;br /&gt;
                &amp;quot;button_exit[1,3;2,1;exit;Rename Now!]&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
})&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
minetest.register_on_player_receive_fields(function(player,&lt;br /&gt;
        formname, fields)&lt;br /&gt;
    if formname ~= &amp;quot;rename:renameform&amp;quot; then&lt;br /&gt;
&lt;br /&gt;
        return false&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local has, missing = minetest.check_player_privs(player:get_player_name(), {&lt;br /&gt;
            rename = true})&lt;br /&gt;
&lt;br /&gt;
    if has then&lt;br /&gt;
      local itemstack = player:get_wielded_item()&lt;br /&gt;
      local meta = itemstack:get_meta()&lt;br /&gt;
      meta:set_string(&amp;quot;description&amp;quot;, fields.name)&lt;br /&gt;
			meta:set_string(&amp;quot;color&amp;quot;, fields.color)&lt;br /&gt;
      player:set_wielded_item(itemstack)&lt;br /&gt;
&lt;br /&gt;
      return true&lt;br /&gt;
    else&lt;br /&gt;
        minetest.chat_send_player(player:get_player_name(), &amp;quot;You have no privilige to rename things :( &amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
local meta = minetest.get_meta(pos)&lt;br /&gt;
meta:set_string(&amp;quot;formspec&amp;quot;,&lt;br /&gt;
        &amp;quot;invsize[8,9;]&amp;quot;..&lt;br /&gt;
        &amp;quot;list[context;main;0,0;8,4;]&amp;quot;..&lt;br /&gt;
        &amp;quot;list[current_player;main;0,5;8,4;]&amp;quot;)&lt;br /&gt;
meta:set_string(&amp;quot;infotext&amp;quot;, &amp;quot;Chest&amp;quot;);&lt;br /&gt;
local inv = meta:[NodeMetaRef]get_inventory()&lt;br /&gt;
inv:set_size(&amp;quot;main&amp;quot;, 8*4)&lt;br /&gt;
print(dump(meta:[NodeMetaRef]to_table()))&lt;br /&gt;
meta:from_table({&lt;br /&gt;
    inventory = {&lt;br /&gt;
        main = {&lt;br /&gt;
[1] = &amp;quot;default:dirt&amp;quot;,&lt;br /&gt;
[2] = &amp;quot;&amp;quot;,&lt;br /&gt;
[3] = &amp;quot;&amp;quot;,&lt;br /&gt;
[4] = &amp;quot;&amp;quot;,&lt;br /&gt;
[5] = &amp;quot;&amp;quot;,&lt;br /&gt;
[6] = &amp;quot;&amp;quot;,&lt;br /&gt;
[7] = &amp;quot;&amp;quot;,&lt;br /&gt;
[8] = &amp;quot;&amp;quot;,&lt;br /&gt;
[9] = &amp;quot;&amp;quot;,&lt;br /&gt;
[10] = &amp;quot;&amp;quot;,&lt;br /&gt;
[11] = &amp;quot;&amp;quot;,&lt;br /&gt;
[12] = &amp;quot;&amp;quot;,&lt;br /&gt;
[13] = &amp;quot;&amp;quot;,&lt;br /&gt;
[14] = &amp;quot;default:cobble&amp;quot;,&lt;br /&gt;
[15] = &amp;quot;&amp;quot;,&lt;br /&gt;
[16] = &amp;quot;&amp;quot;,&lt;br /&gt;
[17] = &amp;quot;&amp;quot;,&lt;br /&gt;
[18] = &amp;quot;&amp;quot;,&lt;br /&gt;
[19] = &amp;quot;&amp;quot;,&lt;br /&gt;
[20] = &amp;quot;default:cobble&amp;quot;,&lt;br /&gt;
[21] = &amp;quot;&amp;quot;,&lt;br /&gt;
[22] = &amp;quot;&amp;quot;,&lt;br /&gt;
[23] = &amp;quot;&amp;quot;,&lt;br /&gt;
[24] = &amp;quot;&amp;quot;,&lt;br /&gt;
[25] = &amp;quot;&amp;quot;,&lt;br /&gt;
[26] = &amp;quot;&amp;quot;,&lt;br /&gt;
[27] = &amp;quot;&amp;quot;,&lt;br /&gt;
[28] = &amp;quot;&amp;quot;,&lt;br /&gt;
[29] = &amp;quot;&amp;quot;,&lt;br /&gt;
[30] = &amp;quot;&amp;quot;,&lt;br /&gt;
[31] = &amp;quot;&amp;quot;,&lt;br /&gt;
[32] = &amp;quot;&amp;quot;}&lt;br /&gt;
    },&lt;br /&gt;
    fields = {&lt;br /&gt;
        formspec = &amp;quot;invsize[8,9;]list[context;main;0,0;8,4;]list[current_player;main;0,5;8,4;]&amp;quot;,&lt;br /&gt;
        infotext = &amp;quot;Chest&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== An excerpt from an e-mail between Minetest developers ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt; When I attach a Lua table to a node I seem to have a&lt;br /&gt;
&amp;gt; choice: to store things with many calls to&lt;br /&gt;
&amp;gt; meta.set_int/meta.set_string etc. or via meta:from_table.&lt;br /&gt;
&amp;gt; meta:from_table lets me store an arbitrary table under &amp;quot;fields&amp;quot;:&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; local meta = minetest.get_meta(pos)&lt;br /&gt;
&amp;gt; local mt = meta:to_table()&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; len = tonumber(mt.fields.length_remaining)&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; ... only I have noticed that every key under fields can only store&lt;br /&gt;
&amp;gt; strings. So as a general purpose 'table' store, this is not so useful.&lt;br /&gt;
&amp;gt; I came upon this because I wanted to store the initial position of a&lt;br /&gt;
&amp;gt; node. This requires either:&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; meta:set_int('x', pos.x)&lt;br /&gt;
&amp;gt; meta:set_int('y', pos.y)&lt;br /&gt;
&amp;gt; meta:set_int('z', pos.z)&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; or something like:&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; mt.fields.tail_pos = &amp;quot;return {&amp;quot; .. pos.x .. &amp;quot;,&amp;quot; .. pos.y .. &amp;quot;,&amp;quot; .. pos.z .. &amp;quot;}&amp;quot;&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; and then something like this to read it back:&lt;br /&gt;
&amp;gt; tail_pos = loadstring(mt.fields.tail_pos)()&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; ...correct? Or am I missing an obvious alternate solution? The api&lt;br /&gt;
&amp;gt; docs are not detailed on this.&lt;br /&gt;
&lt;br /&gt;
Answer by celeron55:&lt;br /&gt;
&lt;br /&gt;
For simplicity, all the fields are internally strings, and don't store&lt;br /&gt;
any type information. I can see the inconvenience though.&lt;br /&gt;
&lt;br /&gt;
You shouldn't use loadstring() directly, because then somebody could&lt;br /&gt;
create a world which stores arbitrary Lua code, which can eg. remove&lt;br /&gt;
all files, or something similar.&lt;br /&gt;
&lt;br /&gt;
For storing Lua variables with type information, you can use&lt;br /&gt;
minetest.serialize() and minetest.deserialize(). They take any&lt;br /&gt;
serializable Lua table, which can contain:&lt;br /&gt;
- tables&lt;br /&gt;
- strings&lt;br /&gt;
- numbers&lt;br /&gt;
- functions that don't access anything outside of what is stored in&lt;br /&gt;
  the data itself and what is passed as a parameter))&lt;br /&gt;
and make it into a string, and the other way around, and they&lt;br /&gt;
will not execute any foreign code (unless you do certain&lt;br /&gt;
complicated-ish stupid things, which probably won't happen).&lt;br /&gt;
&lt;br /&gt;
You can check out the implementation in builtin/serialize.lua.&lt;br /&gt;
&lt;br /&gt;
So if you want to store a position in the data of a node, you can use:&lt;br /&gt;
  local pos = {x=this, y=and, z=that}&lt;br /&gt;
  meta:set_string(&amp;quot;tail_pos&amp;quot;, minetest.serialize(pos))&lt;br /&gt;
and&lt;br /&gt;
  local pos = minetest.deserialize(meta:get_string(&amp;quot;tail_pos&amp;quot;)).&lt;br /&gt;
&lt;br /&gt;
Keep in mind though that that thing isn't very largely in use, and&lt;br /&gt;
there might be unnoticed problems.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Objects]]&lt;/div&gt;</summary>
		<author><name>&gt;ROllerozxa</name></author>
	</entry>
</feed>