diff --git a/mods/nyancat/README.txt b/mods/nyancat/README.txt
new file mode 100644
index 0000000000000000000000000000000000000000..fadc1d239ace006fe5de1012fa7c72b3629bcf37
--- /dev/null
+++ b/mods/nyancat/README.txt
@@ -0,0 +1,16 @@
+Minetest Game mod: nyancat
+==========================
+See license.txt for license information.
+
+Authors of source code
+----------------------
+Originally by celeron55, Perttu Ahola <celeron55@gmail.com> (LGPL 2.1)
+Various Minetest developers and contributors (LGPL 2.1)
+
+Authors of media files
+----------------------
+VanessaE (CC BY-SA 3.0):
+  nyancat_front.png
+  nyancat_back.png
+  nyancat_side.png
+  nyancat_rainbow.png
diff --git a/mods/nyancat/depends.txt b/mods/nyancat/depends.txt
new file mode 100644
index 0000000000000000000000000000000000000000..4ad96d51599fb734101f6229f6c1a8a509bd6255
--- /dev/null
+++ b/mods/nyancat/depends.txt
@@ -0,0 +1 @@
+default
diff --git a/mods/nyancat/init.lua b/mods/nyancat/init.lua
new file mode 100644
index 0000000000000000000000000000000000000000..2feaa9e5a990838c3bbe361a951cc9f589090c60
--- /dev/null
+++ b/mods/nyancat/init.lua
@@ -0,0 +1,92 @@
+minetest.register_node("nyancat:nyancat", {
+	description = "Nyan Cat",
+	tiles = {"nyancat_side.png", "nyancat_side.png", "nyancat_side.png",
+		"nyancat_side.png", "nyancat_back.png", "nyancat_front.png"},
+	paramtype = "light",
+	light_source = default.LIGHT_MAX,
+	paramtype2 = "facedir",
+	groups = {cracky = 2},
+	is_ground_content = false,
+	legacy_facedir_simple = true,
+	sounds = default.node_sound_defaults(),
+})
+
+minetest.register_node("nyancat:nyancat_rainbow", {
+	description = "Nyan Cat Rainbow",
+	tiles = {
+		"nyancat_rainbow.png^[transformR90",
+		"nyancat_rainbow.png^[transformR90",
+		"nyancat_rainbow.png"
+	},
+	paramtype = "light",
+	light_source = default.LIGHT_MAX,
+	paramtype2 = "facedir",
+	groups = {cracky = 2},
+	is_ground_content = false,
+	sounds = default.node_sound_defaults(),
+})
+
+minetest.register_craft({
+	type = "fuel",
+	recipe = "nyancat:nyancat",
+	burntime = 1,
+})
+
+minetest.register_craft({
+	type = "fuel",
+	recipe = "nyancat:nyancat_rainbow",
+	burntime = 1,
+})
+
+nyancat = {}
+
+function nyancat.place(pos, facedir, length)
+	if facedir > 3 then
+		facedir = 0
+	end
+	local tailvec = minetest.facedir_to_dir(facedir)
+	local p = {x = pos.x, y = pos.y, z = pos.z}
+	minetest.set_node(p, {name = "nyancat:nyancat", param2 = facedir})
+	for i = 1, length do
+		p.x = p.x + tailvec.x
+		p.z = p.z + tailvec.z
+		minetest.set_node(p, {name = "nyancat:nyancat_rainbow", param2 = facedir})
+	end
+end
+
+function nyancat.generate(minp, maxp, seed)
+	local height_min = -31000
+	local height_max = -32
+	if maxp.y < height_min or minp.y > height_max then
+		return
+	end
+	local y_min = math.max(minp.y, height_min)
+	local y_max = math.min(maxp.y, height_max)
+	local volume = (maxp.x - minp.x + 1) * (y_max - y_min + 1) * (maxp.z - minp.z + 1)
+	local pr = PseudoRandom(seed + 9324342)
+	local max_num_nyancats = math.floor(volume / (16 * 16 * 16))
+	for i = 1, max_num_nyancats do
+		if pr:next(0, 1000) == 0 then
+			local x0 = pr:next(minp.x, maxp.x)
+			local y0 = pr:next(minp.y, maxp.y)
+			local z0 = pr:next(minp.z, maxp.z)
+			local p0 = {x = x0, y = y0, z = z0}
+			nyancat.place(p0, pr:next(0, 3), pr:next(3, 15))
+		end
+	end
+end
+
+minetest.register_on_generated(function(minp, maxp, seed)
+	nyancat.generate(minp, maxp, seed)
+end)
+
+-- Legacy
+minetest.register_alias("default:nyancat", "nyancat:nyancat")
+minetest.register_alias("default:nyancat_rainbow", "nyancat:nyancat_rainbow")
+minetest.register_alias("nyancat", "nyancat:nyancat")
+minetest.register_alias("nyancat_rainbow", "nyancat:nyancat_rainbow")
+minetest.register_alias("default:nyancat_rainbow_doublepanel", "nyancat:nyancat_rainbow_doublepanel")
+minetest.register_alias("default:nyancat_rainbow_outerstair", "nyancat:nyancat_rainbow_outerstair")
+
+default.make_nyancat = nyancat.place
+default.generate_nyancats = nyancat.generate
diff --git a/mods/nyancat/license.txt b/mods/nyancat/license.txt
new file mode 100644
index 0000000000000000000000000000000000000000..3aa386175cf3a1274acd0763f9edc65b88b37811
--- /dev/null
+++ b/mods/nyancat/license.txt
@@ -0,0 +1,50 @@
+License of source code
+----------------------
+
+GNU Lesser General Public License, version 2.1
+Copyright (C) 2011-2016 celeron55, Perttu Ahola <celeron55@gmail.com>
+Copyright (C) 2012-2016 Various Minetest developers and contributors
+
+This program is free software; you can redistribute it and/or modify it under the terms
+of the GNU Lesser General Public License as published by the Free Software Foundation;
+either version 2.1 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See the GNU Lesser General Public License for more details:
+https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
+
+
+Licenses of media (textures)
+----------------------------
+
+Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)
+Copyright (C) 2012-2016 VanessaE
+
+You are free to:
+Share — copy and redistribute the material in any medium or format.
+Adapt — remix, transform, and build upon the material for any purpose, even commercially.
+The licensor cannot revoke these freedoms as long as you follow the license terms.
+
+Under the following terms:
+
+Attribution — You must give appropriate credit, provide a link to the license, and
+indicate if changes were made. You may do so in any reasonable manner, but not in any way
+that suggests the licensor endorses you or your use.
+
+ShareAlike — If you remix, transform, or build upon the material, you must distribute
+your contributions under the same license as the original.
+
+No additional restrictions — You may not apply legal terms or technological measures that
+legally restrict others from doing anything the license permits.
+
+Notices:
+
+You do not have to comply with the license for elements of the material in the public
+domain or where your use is permitted by an applicable exception or limitation.
+No warranties are given. The license may not give you all of the permissions necessary
+for your intended use. For example, other rights such as publicity, privacy, or moral
+rights may limit how you use the material.
+
+For more details:
+http://creativecommons.org/licenses/by-sa/3.0/
diff --git a/mods/nyancat/textures/nyancat_back.png b/mods/nyancat/textures/nyancat_back.png
new file mode 100644
index 0000000000000000000000000000000000000000..e479ace8306c8f856da9f8f99f40924ef67a8a9a
Binary files /dev/null and b/mods/nyancat/textures/nyancat_back.png differ
diff --git a/mods/nyancat/textures/nyancat_front.png b/mods/nyancat/textures/nyancat_front.png
new file mode 100644
index 0000000000000000000000000000000000000000..c9dd6a330ed87cfb410787d9038410c2f1576c54
Binary files /dev/null and b/mods/nyancat/textures/nyancat_front.png differ
diff --git a/mods/nyancat/textures/nyancat_rainbow.png b/mods/nyancat/textures/nyancat_rainbow.png
new file mode 100644
index 0000000000000000000000000000000000000000..685a22ccf53ab659eafcab0dd95e7b031cbdb0af
Binary files /dev/null and b/mods/nyancat/textures/nyancat_rainbow.png differ
diff --git a/mods/nyancat/textures/nyancat_side.png b/mods/nyancat/textures/nyancat_side.png
new file mode 100644
index 0000000000000000000000000000000000000000..3152c337c56a705485ac578098ce3f7eba74fd69
Binary files /dev/null and b/mods/nyancat/textures/nyancat_side.png differ
diff --git a/mods/pbj_pup/depends.txt b/mods/pbj_pup/depends.txt
new file mode 100644
index 0000000000000000000000000000000000000000..4ad96d51599fb734101f6229f6c1a8a509bd6255
--- /dev/null
+++ b/mods/pbj_pup/depends.txt
@@ -0,0 +1 @@
+default
diff --git a/mods/pbj_pup/init.lua b/mods/pbj_pup/init.lua
new file mode 100644
index 0000000000000000000000000000000000000000..76eb1ac4691cd1ef7edb5a5053d108f2613b04d4
--- /dev/null
+++ b/mods/pbj_pup/init.lua
@@ -0,0 +1,136 @@
+
+--[[
+
+  Minetest's official Peanut Butter & Jelly Pup mod
+
+]]--
+
+local enable = minetest.setting_getbool("pbj_pup_enable")
+if enable == false then
+	return
+end
+
+local function howl(ttl, player)
+	if not player then
+		return
+	end
+	ttl = ttl - 15
+	if ttl < 0 then
+		return
+	end
+
+	minetest.sound_play("pbj_pup_howl", {object = player, loop = false})
+	minetest.do_item_eat(5, nil, ItemStack("pbj_pup:pbj_pup"), player, nil)
+
+	minetest.after(15, howl, ttl, player)
+end
+
+--
+-- nodes
+--
+minetest.register_node("pbj_pup:pbj_pup", {
+	description = "PB&J Pup",
+	tiles = {
+		"pbj_pup_sides.png",
+		"pbj_pup_jelly.png",
+		"pbj_pup_sides.png",
+		"pbj_pup_sides.png",
+		"pbj_pup_back.png",
+		"pbj_pup_front.png"
+	},
+	paramtype = "light",
+	light_source = default.LIGHT_MAX,
+	paramtype2 = "facedir",
+	groups = {cracky = 2},
+	is_ground_content = false,
+	legacy_facedir_simple = true,
+	sounds = default.node_sound_defaults(),
+	stack_max = 1,
+	on_use = function(itemstack, user, pointed_thing)
+		howl(300, user)
+		itemstack:take_item()
+		return itemstack
+	end,
+})
+
+minetest.register_node("pbj_pup:pbj_pup_candies", {
+	description = "PB&J Pup Candies",
+	tiles = {{
+		name = "pbj_pup_candies_animated.png",
+		animation = {
+			type = "vertical_frames",
+			aspect_w = 16,
+			aspect_h = 16,
+			length = 1.6
+		}
+	}},
+	paramtype = "light",
+	light_source = default.LIGHT_MAX,
+	paramtype2 = "facedir",
+	groups = {cracky = 2},
+	is_ground_content = false,
+	stack_max = 5,
+	sounds = default.node_sound_defaults(),
+	on_use = function(itemstack, user, pointed_thing)
+		minetest.do_item_eat(5, nil, itemstack, user, pointed_thing)
+		minetest.sound_play("pbj_pup_barks", {object = user, loop = false})
+		itemstack:take_item()
+		return itemstack
+	end,
+})
+
+--
+-- mapgen
+--
+local gen = minetest.setting_getbool("pbj_pup_generate")
+if gen == nil or gen then
+	local function place(pos, facedir, length)
+		if facedir > 3 then
+			facedir = 0
+		end
+		local tailvec = minetest.facedir_to_dir(facedir)
+		local p = {x = pos.x, y = pos.y, z = pos.z}
+		minetest.set_node(p, {name = "pbj_pup:pbj_pup", param2 = facedir})
+		for i = 1, length do
+			p.x = p.x + tailvec.x
+			p.z = p.z + tailvec.z
+			minetest.set_node(p, {name = "pbj_pup:pbj_pup_candies", param2 = facedir})
+		end
+	end
+
+	local function generate(minp, maxp, seed)
+		local height_min = -31000
+		local height_max = -32
+		if maxp.y < height_min or minp.y > height_max then
+			return
+		end
+		local y_min = math.max(minp.y, height_min)
+		local y_max = math.min(maxp.y, height_max)
+		local volume = (maxp.x - minp.x + 1) * (y_max - y_min + 1) * (maxp.z - minp.z + 1)
+		local pr = PseudoRandom(seed + 9324342)
+		local max_num = math.floor(volume / (16 * 16 * 16))
+		for i = 1, max_num do
+			if pr:next(0, 1000) == 0 then
+				local x0 = pr:next(minp.x, maxp.x)
+				local y0 = pr:next(minp.y, maxp.y)
+				local z0 = pr:next(minp.z, maxp.z)
+				local p0 = {x = x0, y = y0, z = z0}
+				place(p0, pr:next(0, 3), pr:next(3, 15))
+			end
+		end
+	end
+
+	minetest.register_on_generated(generate)
+end
+--
+-- compat
+--
+
+if minetest.setting_getbool("pbj_pup_alias_nyancat") then
+	minetest.register_alias("default:nyancat", "pbj_pup:pbj_pup")
+	minetest.register_alias("default:nyancat_rainbow","pbj_pup:pbj_pup_candies")
+	minetest.register_alias("nyancat", "pbj_pup:pbj_pup")
+	minetest.register_alias("nyancat_rainbow", "pbj_pup:pbj_pup_candies")
+	minetest.register_alias("nyancat:nyancat", "pbj_pup:pbj_pup")
+	minetest.register_alias("nyancat:nyancat_rainbow", "pbj_pup:pbj_pup_candies")
+end
diff --git a/mods/pbj_pup/license.md b/mods/pbj_pup/license.md
new file mode 100644
index 0000000000000000000000000000000000000000..b5fcf3a26544fe0bf81c6d0b1a25034876a364b9
--- /dev/null
+++ b/mods/pbj_pup/license.md
@@ -0,0 +1,26 @@
+
+## PB&J Pup
+
+PB&J Pup is a parody on the "Nyan Cat" TM toasted poptart meme.
+
+
+## License and Copyright
+
+(C) 2017 Vanessa Ezekowitz, Auke Kok, celeron55
+
+ * All Code: LGPL-2.1+
+ * All Images: CC-BY-4.0
+
+
+## Sounds
+
+ * `pbj_pup_barks.ogg`:
+   Artist: Tomlija <tshesound@gmail.com>
+   License: CC-BY-3.0
+   Url: http://freesound.org/people/Tomlija/sounds/97392/
+
+ * `pbj_pup_howl.ogg`:
+   Copyright 2013 Iwan Gabovitch (qubodup)
+   License: CC-BY-3.0
+   Url: http://freesound.org/people/qubodup/sounds/193394/
+
diff --git a/mods/pbj_pup/sounds/pbj_pup_barks.ogg b/mods/pbj_pup/sounds/pbj_pup_barks.ogg
new file mode 100644
index 0000000000000000000000000000000000000000..bdd3440e04f455924ef935392eb0209d8a72477e
Binary files /dev/null and b/mods/pbj_pup/sounds/pbj_pup_barks.ogg differ
diff --git a/mods/pbj_pup/sounds/pbj_pup_howl.ogg b/mods/pbj_pup/sounds/pbj_pup_howl.ogg
new file mode 100644
index 0000000000000000000000000000000000000000..15e93bc21e86ce168a0e868a9a88a793131890b4
Binary files /dev/null and b/mods/pbj_pup/sounds/pbj_pup_howl.ogg differ
diff --git a/mods/pbj_pup/textures/pbj_pup_back.png b/mods/pbj_pup/textures/pbj_pup_back.png
new file mode 100644
index 0000000000000000000000000000000000000000..f72fc24620627b2c2fe6f96dae66034b90984d2e
Binary files /dev/null and b/mods/pbj_pup/textures/pbj_pup_back.png differ
diff --git a/mods/pbj_pup/textures/pbj_pup_candies.png b/mods/pbj_pup/textures/pbj_pup_candies.png
new file mode 100644
index 0000000000000000000000000000000000000000..185fa2d8e3da756f2c0246a69e6f1ae8d47de392
Binary files /dev/null and b/mods/pbj_pup/textures/pbj_pup_candies.png differ
diff --git a/mods/pbj_pup/textures/pbj_pup_candies_animated.png b/mods/pbj_pup/textures/pbj_pup_candies_animated.png
new file mode 100644
index 0000000000000000000000000000000000000000..d092759a147f5be810749a7ddb6423a8c8709d11
Binary files /dev/null and b/mods/pbj_pup/textures/pbj_pup_candies_animated.png differ
diff --git a/mods/pbj_pup/textures/pbj_pup_front.png b/mods/pbj_pup/textures/pbj_pup_front.png
new file mode 100644
index 0000000000000000000000000000000000000000..d1c5739fe6e5403cd5339dae2f9be423a1739531
Binary files /dev/null and b/mods/pbj_pup/textures/pbj_pup_front.png differ
diff --git a/mods/pbj_pup/textures/pbj_pup_jelly.png b/mods/pbj_pup/textures/pbj_pup_jelly.png
new file mode 100644
index 0000000000000000000000000000000000000000..ec0c1ebf1b3ed11e4273fdc53780271da8d2c26e
Binary files /dev/null and b/mods/pbj_pup/textures/pbj_pup_jelly.png differ
diff --git a/mods/pbj_pup/textures/pbj_pup_sides.png b/mods/pbj_pup/textures/pbj_pup_sides.png
new file mode 100644
index 0000000000000000000000000000000000000000..d65d7be703e6122d20ef571ea7c11d634be38675
Binary files /dev/null and b/mods/pbj_pup/textures/pbj_pup_sides.png differ
diff --git a/settingtypes.txt b/settingtypes.txt
index 855235c2551735c09efdcbae94c1f2f1e79cbd34..2c48d849d33521c74c05cbcb891f2afdec71bd2b 100644
--- a/settingtypes.txt
+++ b/settingtypes.txt
@@ -46,3 +46,13 @@ share_bones_time (Bone share time) int 1200 0
 
 #    Replaces old stairs with new ones. Only required for older worlds.
 enable_stairs_replace_abm (Replace old stairs) bool false
+
+#    Enable the PB&J Pup mod entirely
+pbj_pup_enable (Enable PB&J pup mod) bool true
+
+#    Generate PB&J Pup blocks in the world
+pbj_pup_generate (Generate PBJ Pup blocks in world) bool true
+
+#    Let the PB&J Pup mod replace Nyan Cat nodes
+pbj_pup_alias_nyancat (Replace Nyan Cat blocks) bool false
+