Colorize a node

Post Reply
Nekrofage
Member
Posts: 52
Joined: Mon Oct 17, 2016 21:12
GitHub: Nekrofage

Colorize a node

by Nekrofage » Post

Hello !!

I would like to know if it is possible to set a color on a node?
How do to that?

Thank you!

User avatar
Nathan.S
Member
Posts: 1147
Joined: Wed Sep 24, 2014 17:47
GitHub: NathanSalapat
IRC: NathanS21
In-game: NathanS21
Location: Bigsby Texas
Contact:

Re: Colorize a node

by Nathan.S » Post

do you mean the texture options, as found here: http://dev.minetest.net/texture
I record Minetest videos, Mod reviews, Modding tutorials, and Lets plays.
Check out my website, and brand new Minetest Modding Course

User avatar
Linuxdirk
Member
Posts: 3218
Joined: Wed Sep 17, 2014 11:21
In-game: Linuxdirk
Location: Germany
Contact:

Re: Colorize a node

by Linuxdirk » Post

Nekrofage wrote:I would like to know if it is possible to set a color on a node?
How do to that?
Hardware coloring is a bit tricky to implement.

Code: Select all

minetest.register_node('cement:hard', {
    -- Usual stuff here
    paramtype2 = 'color',
    drawtype = 'color',
    palette = 'cement_palette.png', -- ideally a 16x16 image with 1 color per pixel
    on_punch = function (pos, node, puncher, pointed_thing)
        -- on punch coloring function here
    end
})
This basically registers a node that allows hardware coloring. The palette file ideally is 16x16 pixels in size to allow addressing colors directly by a single value (all other sizes result in "stretched" color addresses because the addresses are stretched to 256 addresses always).

For actual coloring you need to register on_punch for example. Or you can use anything else that changes the node. The on_punch function could be something like

Code: Select all

local name = puncher:get_wielded_item():get_name()
local colors = {
    ['dye:white']      = 0,
    ['dye:grey']       = 1,
    ['dye:dark_grey']  = 2,
    ['dye:black']      = 3,
    ['dye:blue']       = 4,
    ['dye:cyan']       = 5,
    ['dye:green']      = 6,
    ['dye:dark_green'] = 7,
    ['dye:yellow']     = 8,
    ['dye:orange']     = 9,
    ['dye:brown']      = 10,
    ['dye:red']        = 11,
    ['dye:pink']       = 12,
    ['dye:magenta']    = 13,
    ['dye:violet']     = 14,
    ['dye:white']      = 15 -- double with 1
}

if minetest.registered_items[name].groups.dye ~= nil then
    local color = colors[name] or false
    if color ~= false then
        local node = minetest.get_node(pos)
        node.param2 = color
        minetest.set_node(pos, node)
    end
end
If you now punch the node while wielding one of the default dyes the node gets colored in the that color. Well, actually the param2 gets set to the palette index. The palette index corresponds to your palette. 0 is the top left pixel, 255 is the bottom right pixel when using a 16x16 palette.

I have implemented hardware coloring like that in my Cement mod.

See comments in this file: https://github.com/4w/cement/blob/4c0c2 ... 9/init.lua

User avatar
sorcerykid
Member
Posts: 1842
Joined: Fri Aug 26, 2016 15:36
GitHub: sorcerykid
In-game: Nemo
Location: Illinois, USA

Re: Colorize a node

by sorcerykid » Post

Am I correct in understanding that hardware coloring will only work on non-facedir nodes? If so, that is very unfortunate. I'm wondering whether the addition of a third param field is finally in order, because it's already impossible to rotate leveled nodes.

Perhaps, it might be worth simply extending the param2 field to 16 bits. This would allow all three features to be used simultaneously, plus one spare bit which could perhaps be used to implement non-diggable nodes. Of course it would also mean having to sacrifice some color depth (4 bits instead of 8 bits).

Code: Select all

0123456789ABCDEF
----------------
vvvvvvccccrrrrrx

c - color (0-15)
v - level (0-63)
r - align (0-23)
x - undig (bool)

Nekrofage
Member
Posts: 52
Joined: Mon Oct 17, 2016 21:12
GitHub: Nekrofage

Re: Colorize a node

by Nekrofage » Post

Nathan.S wrote:do you mean the texture options, as found here: http://dev.minetest.net/texture
Ah yes !
It is a good idea to use a basic texture and colorize it with this:

Code: Select all

[colorize:#RGB
    Colorizes the textures with given color. (Possible formats: #RGB, #RGBA, #RRGGBB, #RRGGBBAA) 

User avatar
sorcerykid
Member
Posts: 1842
Joined: Fri Aug 26, 2016 15:36
GitHub: sorcerykid
In-game: Nemo
Location: Illinois, USA

Re: Colorize a node

by sorcerykid » Post

That will only change the texture overlay color in the node definition. It will not colorize an individual node.

User avatar
Linuxdirk
Member
Posts: 3218
Joined: Wed Sep 17, 2014 11:21
In-game: Linuxdirk
Location: Germany
Contact:

Re: Colorize a node

by Linuxdirk » Post

sorcerykid wrote:Am I correct in understanding that hardware coloring will only work on non-facedir nodes?
That is by design. Unfortunately everything relevant is crammed into param2 instead of properly separating it. You can use drawtype = "colorfacedir" and some math to map some parts of the palette to the remaining bits.

https://github.com/minetest/minetest/bl ... t#L580L606

Extremely inconvenient and annoying, but for basic nodes it works.
sorcerykid wrote:Perhaps, it might be worth simply extending the param2 field to 16 bits. This would allow all three features to be used simultaneously, plus one spare bit which could perhaps be used to implement non-diggable nodes.
I’d say: go a level higher with this. Just implement more fields for different things.

User avatar
sorcerykid
Member
Posts: 1842
Joined: Fri Aug 26, 2016 15:36
GitHub: sorcerykid
In-game: Nemo
Location: Illinois, USA

Re: Colorize a node

by sorcerykid » Post

I’d say: go a level higher with this. Just implement more fields for different things.
That could certainly work, but iirc the original design goal was efficiency. I'm not familiar with the internals of database organization, yet I would imagine that multiple fields would be less optimal than a single field, particularly if any field is under-utilized.

For example, storing only 4 bits in an 8 bit field, as in the case of levels, would result in 1 wasted byte for every two nodes in addition to the fact most nodes don't use levels; so in effect the field itself would be wasted 99% of the time. Also, don't forget the increased overhead of mapblock data that must be transferred to every client. Even a small order of magnitude difference, could be perceptible to players that do not have good connectivity. Just some thoughts!

Nekrofage
Member
Posts: 52
Joined: Mon Oct 17, 2016 21:12
GitHub: Nekrofage

Re: Colorize a node

by Nekrofage » Post

To colorize a node, I use the 'colorize' parameter for the texture:
https://github.com/Nekrofage/nodevoxel/ ... r/init.lua

Do you know if it is possible to update the value of 'colorize' in-game?

User avatar
sorcerykid
Member
Posts: 1842
Joined: Fri Aug 26, 2016 15:36
GitHub: sorcerykid
In-game: Nemo
Location: Illinois, USA

Re: Colorize a node

by sorcerykid » Post

No, all node definitions (the table passed to minetest.register_node( ) function during startup), are persistent until the game is restarted.

User avatar
Linuxdirk
Member
Posts: 3218
Joined: Wed Sep 17, 2014 11:21
In-game: Linuxdirk
Location: Germany
Contact:

Re: Colorize a node

by Linuxdirk » Post

sorcerykid wrote:For example, storing only 4 bits in an 8 bit field, as in the case of levels, would result in 1 wasted byte for every two nodes ...
The keyword here is "compression". This would add little to no overhead if only a few fields are used.

At least coloring should be independent of param2. Binding such a giant functionality to a tiny multi-purpose field is simply a bad idea imho. Coloring could be extended to properly allow shades and alpha values and chroma key, and all kind of fancy stuff it it weren't limited by param2 usage.

User avatar
sorcerykid
Member
Posts: 1842
Joined: Fri Aug 26, 2016 15:36
GitHub: sorcerykid
In-game: Nemo
Location: Illinois, USA

Re: Colorize a node

by sorcerykid » Post

That is a good point. If compression is used, then in theory there could be an arbitrary number of fields, each with a specific purpose. Perhaps three fields would be better. Expanding on my idea above, with multiple fields

Code: Select all

Colorization (16-bit)
0123456789ABCDEF0123456789ABCDEF
ccccccccaaaabzzz

c - color (0-255)
a - alpha (0-15)
b - light (bool)
z - reserved for future use

Configuration (16-bit)
0123456789ABCDEF0123456789ABCDEF
vvvvvvrrrrrzzzzz

v - level (0-63)
r - align (0-23)
z - reserved for future use

Miscellaneous (8-bit)
0123456789ABCDEF
xzzzoooo

x - break (bool)
z - reserved for future use
o - free for other purposes
PS. Sorry for derailing this discussion :D

Sokomine
Member
Posts: 4276
Joined: Sun Sep 09, 2012 17:31
GitHub: Sokomine
IRC: Sokomine
In-game: Sokomine

Re: Colorize a node

by Sokomine » Post

sorcerykid wrote: I'm not familiar with the internals of database organization, yet I would imagine that multiple fields would be less optimal than a single field, particularly if any field is under-utilized.
No! Minetest does not make intelligent usage of databases. Each mapblock is stored as index (x,y,z mapped into it) and a compressed binary blob containing all the data. That's then stored in the database.
Linuxdirk wrote: At least coloring should be independent of param2. Binding such a giant functionality to a tiny multi-purpose field is simply a bad idea imho. Coloring could be extended to properly allow shades and alpha values and chroma key, and all kind of fancy stuff it it weren't limited by param2 usage.
I'm glad that we have hardware coloring at all. Certainly, it'd be nice to have the same amount of colors for nodes with facedir as well. But that's not the case right now. And in a way even the existing colors are too many for the existing ways of dealing with nodes. Can't craft 256 diffrent colors in any reasonable way.

What makes life difficult is the mapping/translation of palettes. That is what's currently keeping me from adding support for colored nodes to the circular saw in moreblocks. The technical means are there, but...to which color value and palette of stairlike nodes shall I map the color and palette of the full block? There has to be some reduction as 32 sub-palettes for each shape would be too many nodes for too little gain. Adding manual translations is tiresome.

It would help if there'd be a way to throw palette name and color index at a function and get rgb values back so that they could be compared with another palette.
A list of my mods can be found here.

User avatar
Linuxdirk
Member
Posts: 3218
Joined: Wed Sep 17, 2014 11:21
In-game: Linuxdirk
Location: Germany
Contact:

Re: Colorize a node

by Linuxdirk » Post

Sokomine wrote:What makes life difficult is the mapping/translation of palettes. […] Adding manual translations is tiresome.
Wait until it comes to <256 colors palettes. Then Minetest stretches the param2 value to palette index association.

https://github.com/minetest/minetest/bl ... t#L557L567

Who in the right mind does something like that?!

I wish all dyes are associated with a color value and you can simply access that value via getting the wielded item and then apply that color. As of now there are conversion tables from item ID to palette index and palette index and actual pixel of the palette and all the way round actual pixel should match the dye color whose item ID you translate to the palette index.

Oh, and a simple colorize = 'RGBA' -- set this to the desired red/green/blue/alpha node parameter would be waaaaaay better than craming the whole color definition stuff into param2 where already a lot of other node specifications are stored.

[Edit] Just created this issue (that will either get talked to death, be ignored, come to nothing, or get closed).

juhdanad
New member
Posts: 6
Joined: Tue Jan 03, 2017 21:42
GitHub: juhdanad
IRC: juhdanad
In-game: juhdanad

Re: Colorize a node

by juhdanad » Post

Hi! I implemented hardware colorization. I posted a reply to your issue, I hope that it will be helpful. Personally I also think that an extra parameter for nodes is a good idea. However, that would allow 256 colors by itself, so palettes would be still required.

User avatar
sorcerykid
Member
Posts: 1842
Joined: Fri Aug 26, 2016 15:36
GitHub: sorcerykid
In-game: Nemo
Location: Illinois, USA

Re: Colorize a node

by sorcerykid » Post

Sokomine wrote:No! Minetest does not make intelligent usage of databases. Each mapblock is stored as index (x,y,z mapped into it) and a compressed binary blob containing all the data. That's then stored in the database.
Good to know. For storing large amounts of binary data, a compressed BLOB with the primary key being the mapblock address (hashed position) is a good approach

However, combining several unrelated datasets within a single, monolithic BLOB is not so ideal. I would think that multiple fields would afford better compression and performance, not to mention greatly simplifying database maintenance. After some brainstorming, I devised a rudimentary table layout that might be more suitable:

MapBlock Table
  • Address
  • Version
  • Flags
  • ContentData
  • ParamData
  • MetaData
  • TimerData
Since the MetaData and TimerData are variable and optional, perhaps a more structured organizational scheme could be devised for them instead of a BLOB. I'm not sure if that would be more or less efficient from the standpoint of SQL, so it's just a thought.

Sokomine
Member
Posts: 4276
Joined: Sun Sep 09, 2012 17:31
GitHub: Sokomine
IRC: Sokomine
In-game: Sokomine

Re: Colorize a node

by Sokomine » Post

sorcerykid wrote: Since the MetaData and TimerData are variable and optional, perhaps a more structured organizational scheme could be devised for them instead of a BLOB. I'm not sure if that would be more or less efficient from the standpoint of SQL, so it's just a thought.
Trouble is that existing maps would have to be converted and new ones would become incompatible with older clients for not much gain. Storing something in an extra field is usually good if you want to be able to search for it. It's hard to search compressed data.
IMHO we would gain more if creation time, time last loaded and time last modified plus perhaps amount of blocks digged and placed by players could be saved. Those values could help identify unmodified mapblocks which could be deleted to gain disk space.
A list of my mods can be found here.

User avatar
GamingAssociation39
Member
Posts: 858
Joined: Mon Apr 25, 2016 16:09
GitHub: Gerold55
IRC: Gerold55
In-game: Gerold55
Location: Maryland, USA

Re: Colorize a node

by GamingAssociation39 » Post

Code: Select all

local sofa_table = { --name, color, colorize(hex or color name:intensity(1-255))
{'Black', 'black', 'black:225'},
{'Blue', 'blue', 'blue:225'},
{'Brown', 'brown', 'brown:225'},
{'Cyan', 'cyan', 'cyan:200'},
{'Dark Green', 'dark_green', 'green:225'},
{'Dark Grey', 'dark_grey', 'black:200'},
{'Green', 'green', '#32cd32:150'},
{'Grey', 'grey', 'black:100'},
{'Magenta', 'magenta', 'magenta:200'},
{'Orange', 'orange', 'orange:225'},
{'Pink', 'pink', 'pink:225'},
{'Red', 'red', 'red:225'},
{'Violet', 'violet', 'violet:225'},
{'White', 'white', 'white:1'},
{'Yellow', 'yellow', 'yellow:225'},
}

for i in ipairs (sofa_table) do
	local name = sofa_table[i][1]
	local color = sofa_table[i][2]
	local hex = sofa_table[i][3]
	
minetest.register_node('furniture_mod:sofa_'..color, {
	description = name..' Sofa',
	drawtype = 'mesh',
	mesh = 'FM_sofa.obj',
	tiles = {'wool_'..color..'.png'},
	groups = {cracky=3, oddly_breakable_by_hand=2, flammable=1, furniture=1, fall_damage_add_percent=-80, bouncy=80},
	inventory_image = 'fm_sofa.png^[colorize:'..hex,
	paramtype = 'light',
	paramtype2 = 'facedir',
	sounds = {wood = {name="furn_bouncy", gain=0.8}},
	on_rightclick = function(pos, node, clicker)
		furniture_mod.sit(pos, node, clicker)
		end,
	selection_box = {
		type = 'fixed',
		fixed = {
			{-.5, -.5, -.5, .5, 0, .5}, --Right, Bottom, Back, Left, Top, Front
			{-.5, 0, .5, .5, .5, .2},
			{-.65, -.15, -.45, -.45, .3, .25}, --left
			{.65, -.15, -.45, .45, .3, .25}, --right
			},
		},
	collision_box = {
		type = 'fixed',
		fixed = {
			{-.5, -.5, -.5, .5, 0, .5}, --base
			{-.5, 0, .5, .5, .5, .2}, --back
			{-.65, -.15, -.45, -.45, .3, .25}, --left
			{.65, -.15, -.45, .45, .3, .25}, --right
			},
		},
})
end
Jesus Is Lord and Savior!!!

User avatar
sorcerykid
Member
Posts: 1842
Joined: Fri Aug 26, 2016 15:36
GitHub: sorcerykid
In-game: Nemo
Location: Illinois, USA

Re: Colorize a node

by sorcerykid » Post

Sokomine wrote: Trouble is that existing maps would have to be converted and new ones would become incompatible with older clients for not much gain.
Combining param2 into a separate BLOB with zlib compression should result in a dramatic reduction of database size since the vast majority of nodes have "0" for param2. If we're talking about a single map block, that's 4096 bytes for param2 that could be reduced to only a few bytes using RLE. Same with the ContentIDs, which in many mapblocks are predominantly the same, either air or stone.

In my view, that is a substantial gain. As it is now, param data is interleaved with content data, which probably defeats the compression algorithm.

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest