diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000000000000000000000000000000000000..ff692d99b1ee03701c386247ed36b2f42ae150b6
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,46 @@
+# irc mod
+Copyright (c) 2013, Diego Martinez (kaeza)
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ - Redistributions of source code must retain the above copyright notice,
+   this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright notice,
+   this list of conditions and the following disclaimer in the documentation
+   and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# matrix mod
+Copyright (c) 2017, Jon Neverland (joenas)
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ - Redistributions of source code must retain the above copyright notice,
+   this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright notice,
+   this list of conditions and the following disclaimer in the documentation
+   and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/callback.lua b/callback.lua
new file mode 100644
index 0000000000000000000000000000000000000000..f0b9903813cf37aaf5b6151565328af96cd80814
--- /dev/null
+++ b/callback.lua
@@ -0,0 +1,38 @@
+-- This file is licensed under the terms of the BSD 2-clause license.
+-- See LICENSE.txt for details.
+
+minetest.register_on_joinplayer(function(player)
+	local name = player:get_player_name()
+	if matrix.connected then --and matrix.config.send_join_part then
+		matrix.say("*** "..name.." joined the game")
+	end
+end)
+
+minetest.register_on_leaveplayer(function(player, timed_out)
+	local name = player:get_player_name()
+	if matrix.connected then -- and matrix.config.send_join_part then
+		matrix.say("*** "..name.." left the game"..
+				(timed_out and " (Timed out)" or ""))
+	end
+end)
+
+minetest.register_on_chat_message(function(name, message)
+	if not matrix.connected
+	   or message:sub(1, 1) == "/"
+	   or message:sub(1, 5) == "[off]"
+	   --or not matrix.joined_players[name] # TODO fix in player_part
+	   or (not minetest.check_player_privs(name, {shout=true})) then
+		return
+	end
+	local nl = message:find("\n", 1, true)
+	if nl then
+		message = message:sub(1, nl - 1)
+	end
+	matrix.say("<"..name.."> "..message)
+end)
+
+
+minetest.register_on_shutdown(function()
+	matrix.disconnect("Game shutting down.")
+end)
+
diff --git a/config.lua b/config.lua
new file mode 100644
index 0000000000000000000000000000000000000000..1c248e508ddef226d0e31c0a573c5029a3224980
--- /dev/null
+++ b/config.lua
@@ -0,0 +1,33 @@
+-- This file is licensed under the terms of the BSD 2-clause license.
+-- See LICENSE.txt for details.
+
+matrix.config = {}
+
+local function setting(stype, name, default, required)
+	local value
+	if stype == "bool" then
+		value = minetest.setting_getbool("matrix."..name)
+	elseif stype == "string" then
+		value = minetest.setting_get("matrix."..name)
+	elseif stype == "number" then
+		value = tonumber(minetest.setting_get("matrix."..name))
+	end
+	if value == nil then
+		if required then
+			error("Required configuration option matrix."..
+				name.." missing.")
+		end
+		value = default
+	end
+	matrix.config[name] = value
+end
+
+-------------------------
+-- BASIC USER SETTINGS --
+-------------------------
+
+setting("string", "user", nil, true) 			-- User name, fe @digbot:matrix.org
+setting("string", "server", nil, true) 		-- Server address to connect to
+setting("number", "port", 8448) 					-- Server port to connect to
+setting("string", "channel", nil, true) 	-- Channel to join (not needed?)
+setting("string", "password", nil, true) 	-- Server password
diff --git a/description.txt b/description.txt
new file mode 100644
index 0000000000000000000000000000000000000000..d0de424f44ae30a9f4d08b60707cce5fc2822f3d
--- /dev/null
+++ b/description.txt
@@ -0,0 +1 @@
+This mod creates a bridge between (multiple) Matrix channels and in-game chat!
diff --git a/init.lua b/init.lua
new file mode 100644
index 0000000000000000000000000000000000000000..20d45726a20ea186024990b3415932b7922554c8
--- /dev/null
+++ b/init.lua
@@ -0,0 +1,143 @@
+-- This file is licensed under the terms of the BSD 2-clause license.
+-- See LICENSE.txt for details.
+
+local modpath = minetest.get_modpath(minetest.get_current_modname())
+
+-- Handle mod security if needed
+local ie, req_ie = _G, minetest.request_insecure_environment
+if req_ie then ie = req_ie() end
+if not ie then
+	error("The Matrix mod requires access to insecure functions in order "..
+		"to work.  Please add the matrix mod to your secure.trusted_mods "..
+		"setting or disable the matrix mod.")
+end
+
+ie.package.path =
+		modpath.."/lua-matrix/?.lua;"
+		..ie.package.path
+
+matrix = {
+	version = "0.0.1",
+	joined_players = {},
+	connected = false,
+	modpath = modpath,
+	lib = lib,
+}
+
+dofile(modpath.."/config.lua")
+
+local function eprintf(fmt, ...)
+	 minetest.log("info", fmt:format(...))
+end
+
+local client = require("matrix").client("https://"..matrix.config.server..":"..matrix.config.port)
+
+client:login_with_password(matrix.config.user, matrix.config.password, true)
+
+local running, start_ts = true, os.time() * 1000
+
+client:hook("invite", function (client, room)
+   -- When invited to a room, join it
+   eprintf("Invited to room %s\n", room)
+   client:join_room(room)
+end):hook("logged-in", function (client)
+	matrix.connected = true
+  eprintf("Logged in successfully\n")
+end):hook("logged-out", function (client)
+	eprintf("Logged out... bye!\n")
+	matrix.connected = false
+end):hook("left", function (client, room)
+   eprintf("Left room %s, active rooms:\n", room)
+   for room_id, room in pairs(client.rooms) do
+      assert(room_id == room.room_id)
+      eprintf("  - %s\n", room)
+   end
+end):hook("joined", function (client, room)
+   eprintf("Active rooms:\n")
+   for room_id, room in pairs(client.rooms) do
+      assert(room_id == room.room_id)
+      eprintf("  - %s\n", room)
+   end
+
+   room:send_text("Type “!bot quit” to make the bot exit")
+
+   room:hook("message", function (room, sender, message, event)
+      if event.origin_server_ts < start_ts then
+        eprintf("%s: (Skipping message sent before bot startup)\n", room)
+        return
+      end
+      if sender == room.client.user_id then
+        eprintf("%s: (Skipping message sent by ourselves)\n", room)
+        return
+      end
+      if message.msgtype ~= "m.text" then
+        eprintf("%s: (Message of type %s ignored)\n", room, message.msgtype)
+        return
+      end
+
+      eprintf("%s: <%s> %s\n", room, sender, message.body)
+
+			if message.body == "!bot quit" then
+        for _, room in pairs(client.rooms) do
+        room:send_text("(gracefully shutting down)")
+        end
+        client:logout()
+        matrix.connected = false
+      else
+        minetest.chat_send_all("<"..sender.."> "..message.body)
+      end
+   end)
+end)
+
+
+dofile(modpath.."/callback.lua")
+
+local stepnum = 0
+
+minetest.register_globalstep(function(dtime) return matrix.step(dtime) end)
+
+function matrix.step()
+	if stepnum == 3 then
+		matrix.connect()
+	end
+	stepnum = stepnum + 1
+
+	if not matrix.connected then return end
+
+	-- Hooks will manage incoming messages and errors
+	local good, err = xpcall(function() client:_sync() end, debug.traceback)
+	if not good then
+		print(err)
+		return
+	end
+end
+
+function matrix.connect()
+	if matrix.connected then
+		minetest.log("error", "Matrix: already connected")
+		return
+	end
+	client:login_with_password(matrix.config.user, matrix.config.password, true)
+	matrix.connected = true
+	minetest.log("action", "Matrix: Connected!")
+	minetest.chat_send_all("Matrix: Connected!")
+end
+
+
+function matrix.disconnect(message)
+	if matrix.connected then
+		--The OnDisconnect hook will clear matrix.connected and print a disconnect message
+		client:logout()
+	end
+end
+
+function matrix.say(to, message)
+	if not message then
+		message = to
+		to = matrix.config.channel
+	end
+	to = to or matrix.config.channel
+	for room_id, room in pairs(client.rooms) do
+	  room:send_text(message)
+	end
+end
diff --git a/lua-matrix b/lua-matrix
new file mode 160000
index 0000000000000000000000000000000000000000..2946b558101a22dd0770a2548f938ada86475256
--- /dev/null
+++ b/lua-matrix
@@ -0,0 +1 @@
+Subproject commit 2946b558101a22dd0770a2548f938ada86475256
diff --git a/mod.conf b/mod.conf
new file mode 100644
index 0000000000000000000000000000000000000000..5a6944136de3d08b197f1d9825ad1418cba90cf5
--- /dev/null
+++ b/mod.conf
@@ -0,0 +1 @@
+name = matrix
diff --git a/settingtypes.txt b/settingtypes.txt
new file mode 100644
index 0000000000000000000000000000000000000000..7bc98f5aa0c1a682b906a5658303a31ffcda4abb
--- /dev/null
+++ b/settingtypes.txt
@@ -0,0 +1,24 @@
+
+[Basic]
+
+# Bots username. May only contain characters A-Z, 0-9
+# '{', '}', '[', ']', '|', '^', '-', or '_'.
+matrix.user (Username) string
+
+# Server to connect to, include http(s)
+matrix.server (Matrix server) string https://matrix.org
+
+# Server port.
+# The standard matrix port is 8448
+matrix.port (Server port) int 8448
+
+# Channel the bot joins after connecting.
+matrix.channel (Channel to join) string #minetest
+
+# Matrix user password.
+matrix.password (Server password) string
+
+# Accesstoken for User (not used?)
+matrix.access_token (Server password) string
+
+