summaryrefslogtreecommitdiffstats
path: root/cwd/assets/altcraft
diff options
context:
space:
mode:
Diffstat (limited to 'cwd/assets/altcraft')
-rw-r--r--cwd/assets/altcraft/scripts/init.lua34
-rw-r--r--cwd/assets/altcraft/scripts/ui.lua171
-rw-r--r--cwd/assets/altcraft/shaders/frag/rml.fs12
-rw-r--r--cwd/assets/altcraft/shaders/frag/rmltex.fs14
-rw-r--r--cwd/assets/altcraft/shaders/rml.json8
-rw-r--r--cwd/assets/altcraft/shaders/rmltex.json9
-rw-r--r--cwd/assets/altcraft/shaders/vert/rml.vs22
-rw-r--r--cwd/assets/altcraft/ui/hud-styles.rcss56
-rw-r--r--cwd/assets/altcraft/ui/hud.rml21
-rw-r--r--cwd/assets/altcraft/ui/main-menu-styles.rcss59
-rw-r--r--cwd/assets/altcraft/ui/main-menu.rml18
-rw-r--r--cwd/assets/altcraft/ui/mc-styles.rcss48
-rw-r--r--cwd/assets/altcraft/ui/options-styles.rcss84
-rw-r--r--cwd/assets/altcraft/ui/options.rml61
-rw-r--r--cwd/assets/altcraft/ui/pause-styles.rcss43
-rw-r--r--cwd/assets/altcraft/ui/pause.rml16
16 files changed, 674 insertions, 2 deletions
diff --git a/cwd/assets/altcraft/scripts/init.lua b/cwd/assets/altcraft/scripts/init.lua
index 96b5ec3..790bab0 100644
--- a/cwd/assets/altcraft/scripts/init.lua
+++ b/cwd/assets/altcraft/scripts/init.lua
@@ -9,18 +9,48 @@ local plugin = {
}
function plugin.onLoad ()
- print("Loaded AltCraft plugin!")
+ rmlui:LoadFontFace("altcraft/fonts/OpenSans-Regular")
+ local con = rmlui.contexts["default"]
+ local uiMainMenu = con:LoadDocument("altcraft/ui/main-menu")
+ con:LoadDocument("altcraft/ui/hud")
+ con:LoadDocument("altcraft/ui/pause")
+ con:LoadDocument("altcraft/ui/options")
+
+ uiMainMenu:Show()
+ AC.Settings.Load()
+ uiMainMenu:GetElementById("username"):SetAttribute("value", AC.Settings.Read("username","Username"..tostring(math.random(10000))))
+ uiMainMenu:GetElementById("hostname"):SetAttribute("value",AC.Settings.Read("hostname","127.0.0.1"))
end
function plugin.onChangeState (newState)
- AC.LogWarning("New state: "..newState)
+ local toHide = {}
+ local toShow = {}
+
+ for i,doc in ipairs(rmlui.contexts["default"].documents) do
+ if doc.title == newState then
+ toShow[#toShow+1]=doc
+ else
+ toHide[#toHide+1]=doc
+ end
+ end
+
+ for i,doc in ipairs(toHide) do
+ doc:Hide()
+ end
+
+ for i,doc in ipairs(toShow) do
+ doc:Show()
+ end
end
function plugin.onUnload ()
AC.LogInfo("AC Core unloaded")
end
+require("altcraft/ui")
+
function plugin.onTick (deltaTime)
+ UpdateUi()
if AC.GetGameState() and AC.GetGameState():GetPlayer() and AC.GetGameState():GetTimeStatus().worldAge > 0 then
-- local player = AC.GetGameState():GetPlayer()
-- player.pos.x = player.pos.x + deltaTime * 0.5
diff --git a/cwd/assets/altcraft/scripts/ui.lua b/cwd/assets/altcraft/scripts/ui.lua
new file mode 100644
index 0000000..392ad27
--- /dev/null
+++ b/cwd/assets/altcraft/scripts/ui.lua
@@ -0,0 +1,171 @@
+local options = {
+ brightness = 0.2,
+ flight = false,
+ mouseSensetivity = 0.1,
+ renderDistance = 2,
+ resolutionScale = 1.0,
+ targetFps = 60,
+ vsync = false,
+ wireframe = false
+}
+
+function OpenOptions(doc)
+ optionsReturnDocument = doc
+ local optionsDoc = {}
+ for i,d in ipairs(rmlui.contexts["default"].documents) do
+ if d.title == "Options" then
+ optionsDoc = d
+ end
+ end
+ doc:Hide()
+ optionsDoc:Show()
+ optionsDoc.style["background-color"] = doc.style["background-color"]
+end
+
+function CloseOptions(doc)
+ for i, v in pairs(options) do
+ local input = doc:GetElementById(i)
+ if type(v) == "number" then
+ local val = input:GetAttribute("value")
+ if i == "targetFps" and val == 301 then
+ AC.Settings.WriteDouble(i, 10000)
+ else
+ AC.Settings.WriteDouble(i, tonumber(val))
+ end
+ elseif type(v) == "boolean" then
+ local val = input:HasAttribute("checked")
+ AC.Settings.WriteBool(i, val)
+ end
+ end
+ AC.Settings.Save()
+ AC.SettingsUpdate()
+
+ optionsReturnDocument:Show()
+ doc:Hide()
+end
+
+function ConnectToServer(doc)
+ AC.Settings.Write('hostname',doc:GetElementById('hostname'):GetAttribute('value'))
+ AC.Settings.Write('username',doc:GetElementById('username'):GetAttribute('value'))
+ AC.Settings.Save()
+ AC.ConnectToServer(
+ doc:GetElementById('hostname'):GetAttribute('value'),
+ doc:GetElementById('username'):GetAttribute('value'))
+end
+
+function OptionsDefaultHandler(event)
+ local input = event.current_element.previous_sibling
+ local id = input:GetAttribute("id")
+ if input:GetAttribute("type") == "checkbox" then
+ if options[id] then
+ input:SetAttribute("checked", "")
+ else
+ input:RemoveAttribute("checked")
+ end
+ else
+ input:SetAttribute("value", options[id])
+ end
+end
+
+local lastFps = {}
+
+local function UpdateFps(newFps)
+ lastFps[#lastFps + 1] = newFps
+ if #lastFps >= 100 then
+ table.remove(lastFps, 1)
+ end
+ local smoothFps = 0
+ for i,v in ipairs(lastFps) do
+ smoothFps = smoothFps + v
+ end
+ smoothFps = smoothFps / #lastFps
+ return smoothFps
+end
+
+function UpdateUi()
+ local doc = {}
+ local uiDoc = {}
+ for i,d in ipairs(rmlui.contexts["default"].documents) do
+ if d.title == "Playing" then
+ doc = d
+ elseif d.title == "Options" then
+ uiDoc = d
+ end
+ end
+
+ if AC.GetGameState() and AC.GetGameState():GetPlayer() and AC.GetGameState():GetTimeStatus().worldAge > 0 then
+ local time = AC.GetTime()
+ local rawFps = 1.0 / time:GetRealDeltaS()
+ local smoothFps = UpdateFps(rawFps)
+ doc:GetElementById('dbg-fps').inner_rml = string.format("%.1f", smoothFps)
+
+ local playerEnt = AC.GetGameState():GetPlayer()
+ doc:GetElementById('dbg-pos').inner_rml = string.format("%.1f %.1f %.1f", playerEnt.pos.x, playerEnt.pos.y, playerEnt.pos.z)
+
+ local wrld = AC.GetGameState():GetWorld()
+ local selection = AC.GetGameState():GetSelectionStatus()
+ if selection.isBlockSelected then
+ bid = wrld:GetBlockId(selection.selectedBlock)
+ doc:GetElementById('dbg-select-pos').inner_rml = tostring(selection.selectedBlock)
+ doc:GetElementById('dbg-select-bid').inner_rml = string.format("%d:%d", bid.id, bid.state)
+ else
+ doc:GetElementById('dbg-select-pos').inner_rml = ""
+ doc:GetElementById('dbg-select-bid').inner_rml = ""
+ end
+
+ local player = AC.GetGameState():GetPlayerStatus()
+ local playerHp = string.format("%.0f", player.health)
+ doc:GetElementById('status-hp').inner_rml = playerHp
+ doc:GetElementById('status-hp-bar'):SetAttribute("value", playerHp)
+ end
+
+
+ local uiInit = optionsListenersAdded == nil
+ if uiInit then
+ AC.Settings.Load()
+ end
+
+ for i,v in pairs(options) do
+ local input = uiDoc:GetElementById(i)
+ local span = input.next_sibling
+
+ if uiInit then
+ span:AddEventListener("click", OptionsDefaultHandler, true)
+
+ if type(v) == "number" then
+ local val = AC.Settings.ReadDouble(i, v)
+ input:SetAttribute("value", tostring(val))
+ elseif type(v) == "boolean" then
+ local val = AC.Settings.ReadBool(i, v)
+ if val then
+ input:SetAttribute("checked", "")
+ else
+ input:RemoveAttribute("checked")
+ end
+ end
+ end
+
+ if type(v) == "number" then
+ local val = input:GetAttribute("value")
+ if v == math.floor(v) and i ~= "resolutionScale" then
+ span.inner_rml = string.format("%d (%d)", math.floor(val), v)
+ if i == "targetFps" and val == 301 then
+ span.inner_rml = string.format("∞ (%d)", v)
+ end
+ else
+ span.inner_rml = string.format("%.2f (%.2f)", val, v)
+ end
+ elseif type(v) == "boolean" then
+ if v then
+ span.inner_rml = "(on)"
+ else
+ span.inner_rml = "(off)"
+ end
+ end
+ end
+
+ if uiInit == true then
+ optionsListenersAdded = true
+ AC.SettingsUpdate()
+ end
+end
diff --git a/cwd/assets/altcraft/shaders/frag/rml.fs b/cwd/assets/altcraft/shaders/frag/rml.fs
new file mode 100644
index 0000000..54c3f36
--- /dev/null
+++ b/cwd/assets/altcraft/shaders/frag/rml.fs
@@ -0,0 +1,12 @@
+#version 330 core
+
+in VS_OUT {
+ vec4 color;
+ vec2 tex_coord;
+} fs_in;
+
+out vec4 fragColor;
+
+void main() {
+ fragColor = fs_in.color;
+}
diff --git a/cwd/assets/altcraft/shaders/frag/rmltex.fs b/cwd/assets/altcraft/shaders/frag/rmltex.fs
new file mode 100644
index 0000000..d885b3b
--- /dev/null
+++ b/cwd/assets/altcraft/shaders/frag/rmltex.fs
@@ -0,0 +1,14 @@
+#version 330 core
+
+uniform sampler2D fontTexture;
+
+in VS_OUT {
+ vec4 color;
+ vec2 tex_coord;
+} fs_in;
+
+out vec4 fragColor;
+
+void main() {
+ fragColor = fs_in.color * texture(fontTexture, fs_in.tex_coord);
+}
diff --git a/cwd/assets/altcraft/shaders/rml.json b/cwd/assets/altcraft/shaders/rml.json
new file mode 100644
index 0000000..0cd85cc
--- /dev/null
+++ b/cwd/assets/altcraft/shaders/rml.json
@@ -0,0 +1,8 @@
+{
+ "vert": "/altcraft/shaders/vert/rml",
+ "frag": "/altcraft/shaders/frag/rml",
+ "uniforms": [
+ "translation",
+ "viewportSize"
+ ]
+} \ No newline at end of file
diff --git a/cwd/assets/altcraft/shaders/rmltex.json b/cwd/assets/altcraft/shaders/rmltex.json
new file mode 100644
index 0000000..a8a1323
--- /dev/null
+++ b/cwd/assets/altcraft/shaders/rmltex.json
@@ -0,0 +1,9 @@
+{
+ "vert": "/altcraft/shaders/vert/rml",
+ "frag": "/altcraft/shaders/frag/rmltex",
+ "uniforms": [
+ "translation",
+ "viewportSize",
+ "fontTexture"
+ ]
+} \ No newline at end of file
diff --git a/cwd/assets/altcraft/shaders/vert/rml.vs b/cwd/assets/altcraft/shaders/vert/rml.vs
new file mode 100644
index 0000000..bdd3b71
--- /dev/null
+++ b/cwd/assets/altcraft/shaders/vert/rml.vs
@@ -0,0 +1,22 @@
+#version 330 core
+
+uniform uvec2 viewportSize;
+uniform vec2 translation;
+uniform mat4 rotationMat;
+
+layout (location = 0) in vec2 pos;
+layout (location = 1) in uvec4 color;
+layout (location = 2) in vec2 tex_coord;
+
+out VS_OUT {
+ vec4 color;
+ vec2 tex_coord;
+} vs_out;
+
+void main() {
+ float x = ((pos.x + translation.x) / viewportSize.x) * 2.0f - 1.0f;
+ float y = ((pos.y + translation.y) / viewportSize.y) * 2.0f - 1.0f;
+ gl_Position = vec4(x, -y, -1.0f, 1.0f);
+ vs_out.color = vec4(float(color.x) / 255.0f, float(color.y) / 255.0f, float(color.z) / 255.0f, float(color.w) / 255.0f);
+ vs_out.tex_coord = tex_coord;
+}
diff --git a/cwd/assets/altcraft/ui/hud-styles.rcss b/cwd/assets/altcraft/ui/hud-styles.rcss
new file mode 100644
index 0000000..61f4147
--- /dev/null
+++ b/cwd/assets/altcraft/ui/hud-styles.rcss
@@ -0,0 +1,56 @@
+.body-hud {
+
+}
+
+.dbg-hud {
+ background-color: #00000055;
+ border-color: black;
+ border-width: 2dp;
+ font-size: 20dp;
+ color: white;
+ padding: 3dp;
+ text-align: left;
+ margin: 3dp auto auto 3dp;
+ position: fixed;
+}
+
+p {
+ display: block;
+}
+
+span {
+ display: inline-block;
+}
+
+.status-hud {
+ background-color: #00000055;
+ border-color: black;
+ border-width: 2dp;
+ font-size: 20dp;
+ color: white;
+ padding: 2dp;
+ margin: 10dp;
+ text-align: center;
+ bottom: 0;
+ position: fixed;
+}
+
+#status-hp-bar {
+ background-color: maroon;
+ border-color: black;
+ margin-left: 5dp;
+ width: 200dp;
+ height: 10dp;
+}
+
+#status-hp-bar fill {
+ background-color: red;
+}
+
+.crosshair-hud {
+ display: table-cell;
+ color: white;
+ font-size: 50dp;
+ text-align: center;
+ vertical-align: middle;
+} \ No newline at end of file
diff --git a/cwd/assets/altcraft/ui/hud.rml b/cwd/assets/altcraft/ui/hud.rml
new file mode 100644
index 0000000..cbf5c86
--- /dev/null
+++ b/cwd/assets/altcraft/ui/hud.rml
@@ -0,0 +1,21 @@
+<rml>
+ <head>
+ <link type="text/rcss" href="mc-styles" />
+ <link type="text/rcss" href="hud-styles" />
+ <title>Playing</title>
+ </head>
+ <body class="body-hud">
+ <div class="dbg-hud">
+ <p>FPS: <span id="dbg-fps">∞?</span></p>
+ <p>Pos: <span id="dbg-pos">∞?</span></p>
+ <p>Select pos: <span id="dbg-select-pos">∞?</span></p>
+ <p>Select block: <span id="dbg-select-bid">∞?</span></p>
+ </div>
+ <div class="status-hud">
+ <p>HP: <span id="status-hp">∞?</span> <progress value="15" max="20" id="status-hp-bar" /> </p>
+ </div>
+ <div style="display: table; width:100%; height: 100%;">
+ <div class="crosshair-hud">+</div>
+ </div>
+ </body>
+</rml>
diff --git a/cwd/assets/altcraft/ui/main-menu-styles.rcss b/cwd/assets/altcraft/ui/main-menu-styles.rcss
new file mode 100644
index 0000000..8b8b9fb
--- /dev/null
+++ b/cwd/assets/altcraft/ui/main-menu-styles.rcss
@@ -0,0 +1,59 @@
+#body-main-menu {
+ background-color: #160f08;
+ color: white;
+}
+
+#title {
+ margin: 0% auto auto;
+ font-size: 20vh;
+}
+
+#disclaimer {
+ width: 70%;
+ margin: 0 auto;
+}
+
+#hostname-text {
+ width: 70%;
+ margin: 5% auto;
+}
+
+#hostname {
+ display: inline-block;
+ width: 45%;
+ height: 8%;
+ position: fixed;
+ margin: 0% auto auto;
+}
+
+#username {
+ display: inline-block;
+ width: 45%;
+ height: 8%;
+ position: fixed;
+ margin: 10% auto auto;
+}
+
+#connect {
+ display: inline-block;
+ width: 45%;
+ height: 8%;
+ position: fixed;
+ margin: 20% auto auto;
+}
+
+#options {
+ display: inline-block;
+ width: 22%;
+ height: 8%;
+ position: fixed;
+ margin: 33% auto auto 27.5%;
+}
+
+#exit {
+ display: inline-block;
+ width: 22%;
+ height: 8%;
+ position: fixed;
+ margin: 33% 27.5% auto auto;
+}
diff --git a/cwd/assets/altcraft/ui/main-menu.rml b/cwd/assets/altcraft/ui/main-menu.rml
new file mode 100644
index 0000000..c5d405d
--- /dev/null
+++ b/cwd/assets/altcraft/ui/main-menu.rml
@@ -0,0 +1,18 @@
+<rml>
+ <head>
+ <link type="text/rcss" href="mc-styles" />
+ <link type="text/rcss" href="main-menu-styles" />
+ <title>MainMenu</title>
+ <script src="/altcraft/scripts/ui"></script>
+ </head>
+ <body id="body-main-menu">
+ <strong class="mc-title" id="title">AltCraft</strong>
+ <p class="mc-p" id="disclaimer">AltCraft is currently not finished, but there is some buggy early testing going on.</p>
+ <p class="mc-p" id="hostname-text">Enter the hostname of a server and your username to connect to it:</p>
+ <input class="mc-text" id="hostname" value="127.0.0.1:25565"/>
+ <input class="mc-text" id="username"/>
+ <button class="mc-button" id="connect" onclick="ConnectToServer(document)">Connect</button>
+ <button type="button" class="mc-button" id="options" onclick="OpenOptions(document)">Options...</button>
+ <button class="mc-button" id="exit" onclick="AC.Exit()">Quit game</button>
+ </body>
+</rmL>
diff --git a/cwd/assets/altcraft/ui/mc-styles.rcss b/cwd/assets/altcraft/ui/mc-styles.rcss
new file mode 100644
index 0000000..3549180
--- /dev/null
+++ b/cwd/assets/altcraft/ui/mc-styles.rcss
@@ -0,0 +1,48 @@
+body {
+ font-family: "open sans";
+ width: 100%;
+ height: 100%;
+ text-align: center;
+}
+
+.mc-title {
+ color: #8e8e8e;
+ display: block;
+}
+
+.mc-p {
+ color: #d6d4d6;
+ display: block;
+ text-align: left;
+ font-size: 4vh;
+}
+
+.mc-text {
+ border-width: 2dp;
+ border-color: #9f9793;
+ background-color: #010001;
+ color: #d6d4d6;
+ text-align: center;
+ vertical-align: middle;
+ font-size: 5vh;
+}
+
+.mc-button {
+ border-width: 2dp;
+ border-color: #14110c;
+ background-color: #6e6f70;
+ color: #c5c6c7;
+ text-align: center;
+ vertical-align: middle;
+ font-size: 5vh;
+}
+
+.mc-button:hover {
+ background-color: #7e86bc;
+ color: #cfd69d;
+}
+
+.mc-button:disabled {
+ background-color: #2b2b2b;
+ color: #848484;
+}
diff --git a/cwd/assets/altcraft/ui/options-styles.rcss b/cwd/assets/altcraft/ui/options-styles.rcss
new file mode 100644
index 0000000..fbfc685
--- /dev/null
+++ b/cwd/assets/altcraft/ui/options-styles.rcss
@@ -0,0 +1,84 @@
+.body-options {
+ background-color: transparent;
+}
+
+form {
+ width: 70%;
+ display: block;
+ margin: 5% auto;
+ background-color: #211710;
+}
+
+.option {
+ display: block;
+ background-color: #0f0b07;
+ margin: 1vh;
+ padding: 0.5vh;
+ font-size: 4vh;
+ text-align: center;
+}
+
+label {
+
+}
+
+span {
+
+}
+
+span:hover {
+ color: #cfd69d;
+}
+
+input {
+ background-color: #2c2c2c;
+ height: 4vh;
+ margin-right: 1vh;
+ margin-left: 1vh;
+}
+
+input.checkbox {
+ border-width: 1vh;
+ border-color: #2c2c2c;
+}
+
+input.checkbox:checked {
+ background-color: #dcdadc;
+}
+
+input.checkbox:hover {
+ border-color: #6a6b70;
+}
+
+input.range:hover {
+ background-color: #6a6b70;
+}
+
+input.range sliderbar {
+ width: 3vh;
+ background-color: #9c9c9c;
+}
+
+input.range:hover sliderbar {
+ background-color: #e9e7e8;
+}
+
+input.range sliderbar:active {
+ background-color: #cfd69d;
+}
+
+input.range sliderarrowdec {
+ display: none;
+}
+
+input.range sliderarrowinc {
+ display: none;
+}
+
+#done {
+ display: block;
+ width: 45%;
+ height: 8%;
+ position: fixed;
+ margin: 5% auto auto;
+}
diff --git a/cwd/assets/altcraft/ui/options.rml b/cwd/assets/altcraft/ui/options.rml
new file mode 100644
index 0000000..485dcba
--- /dev/null
+++ b/cwd/assets/altcraft/ui/options.rml
@@ -0,0 +1,61 @@
+<rml>
+ <head>
+ <link type="text/rcss" href="mc-styles" />
+ <link type="text/rcss" href="options-styles" />
+ <script src="/altcraft/scripts/ui"></script>
+ <title>Options</title>
+ </head>
+ <body class="body-options">
+ <form>
+ <div class="option">
+ <label>Brightness</label>
+ <input type="range" min="0.0" max="1.0" step="0.01" id="brightness" />
+ <span id="brightness-val"></span>
+ </div>
+
+ <div class="option">
+ <label>Flight</label>
+ <input type="checkbox" id="flight" />
+ <span id="flight-val"></span>
+ </div>
+
+ <div class="option">
+ <label>Mouse sensetivity</label>
+ <input type="range" min="0.05" max="0.8" step="0.01" id="mouseSensetivity" />
+ <span id="mouseSensetivity-val"></span>
+ </div>
+
+ <div class="option">
+ <label>Render distance</label>
+ <input type="range" min="2" max="16" step="1" id="renderDistance" />
+ <span id="renderDistance-val"></span>
+ </div>
+
+ <div class="option">
+ <label>Resolution scale</label>
+ <input type="range" min="0.1" max="4.0" step="0.05" id="resolutionScale" />
+ <span id="resolutionScale-val"></span>
+ </div>
+
+ <div class="option">
+ <label>Fps limit</label>
+ <input type="range" min="15" max="301" step="1" id="targetFps" />
+ <span id="targetFps-val"></span>
+ </div>
+
+ <div class="option">
+ <label>VSync</label>
+ <input type="checkbox" id="vsync" />
+ <span id="vsync-val"></span>
+ </div>
+
+ <div class="option">
+ <label>Wireframe rendering</label>
+ <input type="checkbox" id="wireframe" />
+ <span id="wireframe-val"></span>
+ </div>
+
+ </form>
+ <button class="mc-button" id="done" onclick="CloseOptions(document)">Done</button>
+ </body>
+</rml>
diff --git a/cwd/assets/altcraft/ui/pause-styles.rcss b/cwd/assets/altcraft/ui/pause-styles.rcss
new file mode 100644
index 0000000..e8e5a08
--- /dev/null
+++ b/cwd/assets/altcraft/ui/pause-styles.rcss
@@ -0,0 +1,43 @@
+.body-pause {
+ background-color: #000000AA;
+}
+
+#continue {
+ display: inline-block;
+ width: 45%;
+ height: 8%;
+ position: fixed;
+ margin: 20% auto auto;
+}
+
+#advancements {
+ display: inline-block;
+ width: 22%;
+ height: 8%;
+ position: fixed;
+ margin: 30% auto auto 27.5%;
+}
+
+#statistics {
+ display: inline-block;
+ width: 22%;
+ height: 8%;
+ position: fixed;
+ margin: 30% 27.5% auto auto;
+}
+
+#options {
+ display: inline-block;
+ width: 45%;
+ height: 8%;
+ position: fixed;
+ margin: 43% auto auto;
+}
+
+#disconnect {
+ display: inline-block;
+ width: 45%;
+ height: 8%;
+ position: fixed;
+ margin: 53% auto auto;
+}
diff --git a/cwd/assets/altcraft/ui/pause.rml b/cwd/assets/altcraft/ui/pause.rml
new file mode 100644
index 0000000..5d652f9
--- /dev/null
+++ b/cwd/assets/altcraft/ui/pause.rml
@@ -0,0 +1,16 @@
+<rml>
+ <head>
+ <link type="text/rcss" href="mc-styles" />
+ <link type="text/rcss" href="pause-styles" />
+ <script src="/altcraft/scripts/ui"></script>
+ <title>Paused</title>
+ </head>
+ <body class="body-pause">
+ Press ESC to unpause
+ <button class="mc-button" onclick="AC.SetStatePlaying()" id="continue">Back to Game</button>
+ <input disabled type="button" class="mc-button" onclick="" id="advancements">Advancements</input>
+ <input disabled type="button" class="mc-button" onclick="" id="statistics">Statistics</input>
+ <button class="mc-button" onclick="OpenOptions(document)" id="options">Options...</button>
+ <button class="mc-button" onclick="AC.Disconnect()" id="disconnect">Disconnect</button>
+ </body>
+</rml>