diff --git a/.github/workflows/luacheck.yml b/.github/workflows/luacheck.yml
new file mode 100644
index 0000000..1d5241c
--- /dev/null
+++ b/.github/workflows/luacheck.yml
@@ -0,0 +1,18 @@
+
+name: luacheck
+
+on: [push, pull_request]
+
+jobs:
+  build:
+
+    runs-on: ubuntu-latest
+
+    steps:
+    - uses: actions/checkout@v1
+    - name: apt
+      run: sudo apt-get install -y luarocks
+    - name: luacheck install
+      run: luarocks install --local luacheck
+    - name: luacheck run
+      run: $HOME/.luarocks/bin/luacheck ./
\ No newline at end of file
diff --git a/.luacheckrc b/.luacheckrc
new file mode 100644
index 0000000..a90b066
--- /dev/null
+++ b/.luacheckrc
@@ -0,0 +1,25 @@
+unused_args = false
+allow_defined_top = true
+
+exclude_files = {".luacheckrc"}
+
+globals = {
+    "minetest", "core",
+
+    --mod provided
+    "unifieddyes",
+}
+
+read_globals = {
+    string = {fields = {"split"}},
+    table = {fields = {"copy", "getn"}},
+
+    --luac
+    "math", "table",
+
+    -- Builtin
+    "vector", "ItemStack", "dump", "DIR_DELIM", "VoxelArea", "Settings", "PcgRandom", "VoxelManip", "PseudoRandom",
+
+    --mod produced
+
+}
\ No newline at end of file
diff --git a/README.md b/README.md
index 44ddbb2..fc75cb0 100644
--- a/README.md
+++ b/README.md
@@ -13,4 +13,4 @@ Install: Unzip the distribution file, rename the resultant folder to just "unifi
 
 Usage: for detailed usage information, please see [the Unified Dyes Thread](https://forum.minetest.net/viewtopic.php?f=11&t=2178&p=28399) on the Minetest forum.
 
-API: the full API is documented here: https://github.com/minetest-mods/unifieddyes/blob/master/API.md
+API: the full API is documented here: https://github.com/mt-mods/unifieddyes/blob/master/API.md
diff --git a/airbrush.lua b/airbrush.lua
index 262ca24..24d41a2 100644
--- a/airbrush.lua
+++ b/airbrush.lua
@@ -49,7 +49,7 @@ function unifieddyes.on_airbrush(itemstack, player, pointed_thing)
 		return
 	end
 
-	local palette = nil
+	local palette
 	local fdir = 0
 	if not def or not def.palette then
 		minetest.chat_send_player(player_name, "*** That node can't be colored -- it's either undefined or has no palette.")
@@ -71,12 +71,15 @@ function unifieddyes.on_airbrush(itemstack, player, pointed_thing)
 
 	local idx, hue = unifieddyes.getpaletteidx(painting_with, palette)
 	local inv = player:get_inventory()
-	if (not creative or not creative.is_enabled_for(player_name)) and not inv:contains_item("main", painting_with) then
+	if (not minetest.is_creative_enabled(player_name)) and not inv:contains_item("main", painting_with) then
 		local suff = ""
 		if not idx then
 			suff = "  Besides, "..string.sub(painting_with, 5).." can't be applied to that node."
 		end
-		minetest.chat_send_player(player_name, "*** You're in survival mode, and you're out of "..string.sub(painting_with, 5).."."..suff)
+		minetest.chat_send_player(
+			player_name,
+			"*** You're in survival mode, and you're out of "..string.sub(painting_with, 5).."."..suff
+		)
 		return
 	end
 
@@ -92,8 +95,8 @@ function unifieddyes.on_airbrush(itemstack, player, pointed_thing)
 
 		local modname = string.sub(name, 1, string.find(name, ":")-1)
 		local nodename2 = string.sub(name, string.find(name, ":")+1)
-		local oldcolor = "snozzberry"
-		local newcolor = "razzberry" -- intentionally misspelled ;-)
+		local oldcolor
+		local newcolor
 
 		if def.ud_color_start and def.ud_color_end then
 			oldcolor = string.sub(node.name, def.ud_color_start, def.ud_color_end)
@@ -123,7 +126,7 @@ function unifieddyes.on_airbrush(itemstack, player, pointed_thing)
 		return
 	end
 	minetest.swap_node(pos, {name = name, param2 = fdir + idx})
-	if not creative or not creative.is_enabled_for(player_name) then
+	if not minetest.is_creative_enabled(player_name) then
 		inv:remove_item("main", painting_with)
 		return
 	end
@@ -144,7 +147,7 @@ function unifieddyes.make_readable_color(color)
 	local s = string.gsub(color, "_s50", "")
 
         -- replace underscores with spaces to make it look nicer
-	local s = string.gsub(s, "_", " ")
+	s = string.gsub(s, "_", " ")
 
         -- capitalize words, you know, looks nicer ;)
         s = string.gsub(s, "(%l)(%w*)", function(a,b) return string.upper(a)..b end)
@@ -160,7 +163,8 @@ function unifieddyes.make_readable_color(color)
 	return s
 end
 
-function unifieddyes.make_colored_square(hexcolor, colorname, showall, creative, painting_with, nodepalette, hp, v2, selindic, inv, explist)
+function unifieddyes.make_colored_square(hexcolor, colorname, showall, creative, painting_with, nodepalette, hp, v2,
+	selindic, inv, explist)
 
 	local dye = "dye:"..colorname
 
@@ -216,7 +220,7 @@ function unifieddyes.show_airbrush_form(player)
 
 	local player_name = player:get_player_name()
 	local painting_with = unifieddyes.player_selected_dye[player_name] or unifieddyes.player_current_dye[player_name]
-	local creative = creative and creative.is_enabled_for(player_name)
+	local creative = minetest.is_creative_enabled(player_name)
 	local inv = player:get_inventory()
 	local nodepalette = "extended"
 	local showall = unifieddyes.player_showall[player_name]
@@ -280,7 +284,8 @@ function unifieddyes.show_airbrush_form(player)
 
 			local hexcolor = string.format("%02x", r2)..string.format("%02x", g2)..string.format("%02x", b2)
 			local f
-			f, selindic = unifieddyes.make_colored_square(hexcolor, val..hue..sat, showall, creative, painting_with, nodepalette, hp, v2, selindic, inv, explist)
+			f, selindic = unifieddyes.make_colored_square(hexcolor, val..hue..sat, showall, creative, painting_with, nodepalette,
+			hp, v2, selindic, inv, explist)
 			t[#t+1] = f
 		end
 
@@ -313,7 +318,8 @@ function unifieddyes.show_airbrush_form(player)
 
 				local hexcolor = string.format("%02x", r3)..string.format("%02x", g3)..string.format("%02x", b3)
 				local f
-				f, selindic = unifieddyes.make_colored_square(hexcolor, val..hue..sat, showall, creative, painting_with, nodepalette, hp, v2, selindic, inv, explist)
+				f, selindic = unifieddyes.make_colored_square(hexcolor, val..hue..sat, showall, creative, painting_with,
+				nodepalette, hp, v2, selindic, inv, explist)
 				t[#t+1] = f
 			end
 		end
@@ -327,7 +333,7 @@ function unifieddyes.show_airbrush_form(player)
 		local hexgrey = string.format("%02x", y*17)..string.format("%02x", y*17)..string.format("%02x", y*17)
 		local grey = "grey_"..y
 
-		if y == 0 then grey = "black" 
+		if y == 0 then grey = "black"
 		elseif y == 4 then grey = "dark_grey"
 		elseif y == 8 then grey = "grey"
 		elseif y == 11 then grey = "light_grey"
@@ -335,7 +341,8 @@ function unifieddyes.show_airbrush_form(player)
 		end
 
 		local f
-		f, selindic = unifieddyes.make_colored_square(hexgrey, grey, showall, creative, painting_with, nodepalette, hp, v2, selindic, inv, explist)
+		f, selindic = unifieddyes.make_colored_square(hexgrey, grey, showall, creative, painting_with, nodepalette, hp, v2,
+		selindic, inv, explist)
 		t[#t+1] = f
 
 	end
@@ -412,11 +419,11 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
 			end
 		end
 
-		if fields.show_all then 
+		if fields.show_all then
 			unifieddyes.player_showall[player_name] = true
 			unifieddyes.show_airbrush_form(player)
 			return
-		elseif fields.show_avail then 
+		elseif fields.show_avail then
 			unifieddyes.player_showall[player_name] = false
 			unifieddyes.show_airbrush_form(player)
 			return
@@ -431,7 +438,8 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
 					minetest.chat_send_player(player_name, "*** Clicked \"Accept\", but the selected color can't be used on the")
 					minetest.chat_send_player(player_name, "*** node that was right-clicked (and \"Show All\" wasn't in effect).")
 					if unifieddyes.player_current_dye[player_name] then
-						minetest.chat_send_player(player_name, "*** Ignoring it and sticking with "..string.sub(unifieddyes.player_current_dye[player_name], 5)..".")
+						minetest.chat_send_player(player_name, "*** Ignoring it and sticking with "
+						..string.sub(unifieddyes.player_current_dye[player_name], 5)..".")
 					else
 						minetest.chat_send_player(player_name, "*** Ignoring it.")
 					end
@@ -451,12 +459,12 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
 			local s3 = string.sub(s1,1, string.find(s1, '"')-1)
 
 			local inv = player:get_inventory()
-			local creative = creative and creative.is_enabled_for(player_name)
+			local creative = minetest.is_creative_enabled(player_name)
 			local dye = "dye:"..s3
 
 			if (showall or unifieddyes.palette_has_color[nodepalette.."_"..s3]) and
-				(minetest.registered_items[dye] and (creative or inv:contains_item("main", dye))) then
-				unifieddyes.player_selected_dye[player_name] = dye 
+				(creative or inv:contains_item("main", dye)) then
+				unifieddyes.player_selected_dye[player_name] = dye
 				unifieddyes.show_airbrush_form(player)
 			end
 		end
@@ -492,7 +500,7 @@ minetest.register_tool("unifieddyes:airbrush", {
 
 			if newcolor and string.find(def.paramtype2, "color") then
 				minetest.chat_send_player(player_name, "*** Switching to "..newcolor.." for the airbrush, to match that node.")
-				unifieddyes.player_current_dye[player_name] = "dye:"..newcolor 
+				unifieddyes.player_current_dye[player_name] = "dye:"..newcolor
 			else
 				minetest.chat_send_player(player_name, "*** That node is uncolored.")
 			end
diff --git a/api.lua b/api.lua
index 8b4eb14..0623e23 100644
--- a/api.lua
+++ b/api.lua
@@ -1,7 +1,5 @@
 -- This file supplies the majority of Unified Dyes' API
 
-local S = minetest.get_translator("unifieddyes")
-
 unifieddyes.player_current_dye = {}
 unifieddyes.player_selected_dye = {}
 unifieddyes.player_last_right_clicked = {}
@@ -51,7 +49,7 @@ minetest.register_on_placenode(
 
 local function move_item(item, pos, inv, digger, fix_color)
 	if not (digger and digger:is_player()) then return end
-	local creative = creative_mode or minetest.check_player_privs(digger, "creative")
+	local creative = minetest.is_creative_enabled(digger:get_player_name())
 	item = unifieddyes.fix_bad_color_info(item, fix_color)
 	if inv:room_for_item("main", item)
 	  and (not creative or not inv:contains_item("main", item, true)) then
@@ -65,7 +63,7 @@ end
 function unifieddyes.on_dig(pos, node, digger)
 	if not digger then return end
 	local playername = digger:get_player_name()
-	if minetest.is_protected(pos, playername) then 
+	if minetest.is_protected(pos, playername) then
 		minetest.record_protection_violation(pos, playername)
 		return
 	end
@@ -78,9 +76,11 @@ function unifieddyes.on_dig(pos, node, digger)
 		fix_color = 240
 	elseif def.paramtype2 == "color" and oldparam2 == 0 and def.palette == "unifieddyes_palette_extended.png" then
 		fix_color = 0
-	elseif def.paramtype2 == "colorwallmounted" and math.floor(oldparam2 / 8) == 0 and def.palette == "unifieddyes_palette_colorwallmounted.png" then
+	elseif def.paramtype2 == "colorwallmounted" and math.floor(oldparam2 / 8) == 0
+	and def.palette == "unifieddyes_palette_colorwallmounted.png" then
 		fix_color = 0
-	elseif def.paramtype2 == "colorfacedir" and math.floor(oldparam2 / 32) == 0 and string.find(def.palette, "unifieddyes_palette_") then
+	elseif def.paramtype2 == "colorfacedir" and math.floor(oldparam2 / 32) == 0
+	and string.find(def.palette, "unifieddyes_palette_") then
 		fix_color = 0
 	end
 
@@ -147,7 +147,7 @@ end
 
 local function register_c(craft, h, sat, val)
 	local hue = (type(h) == "table") and h[1] or h
-	local color = ""
+	local color
 	if val then
 		if craft.palette == "wallmounted" then
 			color = val..hue..sat
@@ -288,9 +288,9 @@ end
 
 function unifieddyes.get_hsv(name) -- expects a node/item name
 	local hue = ""
-	local a,b
+	local a
 	for _, i in ipairs(unifieddyes.HUES_EXTENDED) do
-		a,b = string.find(name, "_"..i[1])
+		a,_ = string.find(name, "_"..i[1])
 		if a then
 			hue = i[1]
 			break
@@ -328,8 +328,6 @@ end
 
 function unifieddyes.getpaletteidx(color, palette_type)
 
-	local origcolor = color
-
 	if string.sub(color,1,4) == "dye:" then
 		color = string.sub(color,5,-1)
 	elseif string.sub(color,1,12) == "unifieddyes:" then
@@ -383,7 +381,8 @@ function unifieddyes.getpaletteidx(color, palette_type)
 		elseif color == "pink" then return 56,7
 		elseif color == "blue" and shade == "light" then return 40,5
 		elseif unifieddyes.gpidx_hues_wallmounted[color] and unifieddyes.gpidx_shades_wallmounted[shade] then
-			return (unifieddyes.gpidx_shades_wallmounted[shade] * 64 + unifieddyes.gpidx_hues_wallmounted[color] * 8), unifieddyes.gpidx_hues_wallmounted[color]
+			return (unifieddyes.gpidx_shades_wallmounted[shade] * 64 + unifieddyes.gpidx_hues_wallmounted[color] * 8),
+			unifieddyes.gpidx_hues_wallmounted[color]
 		end
 	else
 		if color == "brown" then
@@ -399,7 +398,8 @@ function unifieddyes.getpaletteidx(color, palette_type)
 			end
 		elseif palette_type == "extended" then
 			if unifieddyes.gpidx_hues_extended[color] and unifieddyes.gpidx_shades_extended[shade] then
-				return (unifieddyes.gpidx_hues_extended[color] + unifieddyes.gpidx_shades_extended[shade]*24), unifieddyes.gpidx_hues_extended[color]
+				return (unifieddyes.gpidx_hues_extended[color] + unifieddyes.gpidx_shades_extended[shade]*24),
+				unifieddyes.gpidx_hues_extended[color]
 			end
 		end
 	end
@@ -427,7 +427,7 @@ function unifieddyes.color_to_name(param2, def)
 		local color = param2
 
 		local v = 0
-		local s = 1 
+		local s = 1
 		if color < 24 then v = 1
 		elseif color > 23  and color < 48  then v = 2
 		elseif color > 47  and color < 72  then v = 3
@@ -445,7 +445,7 @@ function unifieddyes.color_to_name(param2, def)
 			elseif color == 244 then return "light_grey"
 			elseif color == 247 then return "grey"
 			elseif color == 251 then return "dark_grey"
-			elseif color == 255 then return "black" 
+			elseif color == 255 then return "black"
 			else return "grey_"..15-(color-240)
 			end
 		else
diff --git a/color-tables.lua b/color-tables.lua
index 12eaa32..f20fe41 100644
--- a/color-tables.lua
+++ b/color-tables.lua
@@ -91,24 +91,6 @@ for i = 1, 14 do
 	end
 end
 
-local default_dyes = {
-	"black",
-	"blue",
-	"brown",
-	"cyan",
-	"dark_green",
-	"dark_grey",
-	"green",
-	"grey",
-	"magenta",
-	"orange",
-	"pink",
-	"red",
-	"violet",
-	"white",
-	"yellow"
-}
-
 -- reverse lookups for getpaletteidx()
 
 unifieddyes.gpidx_aliases = {
diff --git a/debian/changelog b/debian/changelog
index d1e21cd..d94bcb1 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+minetest-mod-unifieddyes (20210420.1+git20220224.1.41dd54d-1) UNRELEASED; urgency=low
+
+  * New upstream snapshot.
+
+ -- Debian Janitor <janitor@jelmer.uk>  Wed, 09 Mar 2022 12:16:53 -0000
+
 minetest-mod-unifieddyes (20210420.1-2) unstable; urgency=medium
 
   * Point d/watch to new upstream.
diff --git a/dyes-crafting.lua b/dyes-crafting.lua
index 2c11c41..9d8c8bf 100644
--- a/dyes-crafting.lua
+++ b/dyes-crafting.lua
@@ -56,11 +56,11 @@ for _, h in ipairs(unifieddyes.HUES_EXTENDED) do
 			local g3 = math.floor(p+(g2-p)*0.5)
 			local b3 = math.floor(p+(b2-p)*0.5)
 
-			local color = string.format("%02x", r3)..string.format("%02x", g3)..string.format("%02x", b3)
+			local ccolor = string.format("%02x", r3)..string.format("%02x", g3)..string.format("%02x", b3)
 
 			minetest.register_craftitem(":dye:"..val..hue.."_s50", {
 				description = S(desc.." (low saturation)"),
-				inventory_image = "unifieddyes_dye.png^[colorize:#"..color..":200",
+				inventory_image = "unifieddyes_dye.png^[colorize:#"..ccolor..":200",
 				groups = { dye=1, not_in_creative_inventory=1 },
 			})
 			minetest.register_alias("unifieddyes:"..val..hue.."_s50", "dye:"..val..hue.."_s50")
@@ -87,19 +87,21 @@ for y = 1, 14 do -- colors 0 and 15 are black and white, default dyes
 	end
 end
 
-minetest.override_item("dye:grey", {
-	inventory_image = "unifieddyes_dye.png^[colorize:#888888:200",
-})
+if minetest.get_modpath("dye") then
+	minetest.override_item("dye:grey", {
+		inventory_image = "unifieddyes_dye.png^[colorize:#888888:200",
+	})
 
-minetest.override_item("dye:dark_grey", {
-	inventory_image = "unifieddyes_dye.png^[colorize:#444444:200",
-})
+	minetest.override_item("dye:dark_grey", {
+		inventory_image = "unifieddyes_dye.png^[colorize:#444444:200",
+	})
 
-minetest.register_craftitem(":dye:light_grey", {
-	description = S("Light grey Dye"),
-	inventory_image = "unifieddyes_dye.png^[colorize:#cccccc:200",
-	groups = { dye=1, not_in_creative_inventory=1 },
-})
+	minetest.register_craftitem(":dye:light_grey", {
+		description = S("Light grey Dye"),
+		inventory_image = "unifieddyes_dye.png^[colorize:#cccccc:200",
+		groups = { dye=1, not_in_creative_inventory=1 },
+	})
+end
 
 -- build a table of color <-> palette associations to reduce the need for
 -- realtime lookups with getpaletteidx()
@@ -122,7 +124,7 @@ for _, palette in ipairs({"extended", "split", "wallmounted"}) do
 	for y = 0, 15 do
 		local grey = "grey_"..y
 
-		if y == 0 then grey = "black" 
+		if y == 0 then grey = "black"
 		elseif y == 4 then grey = "dark_grey"
 		elseif y == 8 then grey = "grey"
 		elseif y == 11 then grey = "light_grey"
diff --git a/init.lua b/init.lua
index a8e5092..42069f9 100644
--- a/init.lua
+++ b/init.lua
@@ -31,8 +31,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 unifieddyes = {}
 
-local creative_mode = minetest.settings:get_bool("creative_mode")
-
 local S = minetest.get_translator("unifieddyes")
 local modpath=minetest.get_modpath(minetest.get_current_modname())
 
@@ -43,3 +41,4 @@ dofile(modpath.."/dyes-crafting.lua")
 dofile(modpath.."/aliases.lua")
 
 print(S("[UnifiedDyes] Loaded!"))
+unifieddyes.init = true
\ No newline at end of file
diff --git a/mod.conf b/mod.conf
index 8afae56..28bacb6 100644
--- a/mod.conf
+++ b/mod.conf
@@ -1,4 +1,4 @@
 name = unifieddyes
 description = Unified Dyes expands the standard dye set from 15 to 90 colors.
-depends = default, dye, basic_materials
-min_minetest_version = 5.2.0
+optional_depends = default, dye, basic_materials
+min_minetest_version = 5.3.0