diff --git a/src/main/java/me/chayapak1/testingbot/Utilities.java b/src/main/java/me/chayapak1/testingbot/Utilities.java
index ce0a7bd..d57300a 100644
--- a/src/main/java/me/chayapak1/testingbot/Utilities.java
+++ b/src/main/java/me/chayapak1/testingbot/Utilities.java
@@ -6,6 +6,8 @@ import net.kyori.adventure.text.format.NamedTextColor;
 
 import java.io.PrintWriter;
 import java.io.StringWriter;
+import java.nio.ByteBuffer;
+import java.util.UUID;
 
 // all in 1 class unlike ChomeNS Bot because laziness
 public class Utilities {
@@ -40,7 +42,7 @@ public class Utilities {
                     character == '\u007f' ||
 
                             // check if character is a control code, also space is the first character after
-                            // the control characters so this is why we can do `character < ' '`
+                            // the control characters so this is why we can do `character < ' '
                             character < ' '
             ) continue;
 
@@ -50,4 +52,30 @@ public class Utilities {
 
         return replaced.toString();
     }
+
+    // uuid
+
+    public static int[] intArray (final UUID uuid) {
+        final ByteBuffer buffer = ByteBuffer.wrap(new byte[16]);
+        buffer.putLong(0, uuid.getMostSignificantBits());
+        buffer.putLong(8, uuid.getLeastSignificantBits());
+
+        final int[] intArray = new int[4];
+        for (int i = 0; i < intArray.length; i++) intArray[i] = buffer.getInt();
+
+        return intArray;
+    }
+
+    public static String snbt (final UUID uuid) {
+        final int[] array = intArray(uuid);
+        return String.format(
+                "[I;%d,%d,%d,%d]",
+                array[0],
+                array[1],
+                array[2],
+                array[3]
+        );
+    }
+
+    public static String selector (final UUID uuid) { return "@n[nbt={UUID:" + snbt(uuid) + "}]"; }
 }
diff --git a/src/main/java/me/chayapak1/testingbot/bots/VMBot.java b/src/main/java/me/chayapak1/testingbot/bots/VMBot.java
index 2695098..28d24f8 100644
--- a/src/main/java/me/chayapak1/testingbot/bots/VMBot.java
+++ b/src/main/java/me/chayapak1/testingbot/bots/VMBot.java
@@ -1,9 +1,10 @@
 package me.chayapak1.testingbot.bots;
 
+import me.chayapak1.testingbot.ComponentParser;
 import me.chayapak1.testingbot.Utilities;
 import me.chayapak1.testingbot.base.BaseBot;
 import me.chayapak1.testingbot.base.Core;
-import net.kyori.adventure.text.Component;
+import org.cloudburstmc.math.vector.Vector3i;
 import org.geysermc.mcprotocollib.network.Session;
 import org.geysermc.mcprotocollib.network.event.session.SessionAdapter;
 import org.geysermc.mcprotocollib.network.packet.Packet;
@@ -13,6 +14,7 @@ import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.OutputStream;
+import java.util.*;
 
 // requires qemu-system-x86_64 in /usr/bin/
 // image.iso = cdrom, you can just `touch image.iso` if you don't want it
@@ -24,14 +26,44 @@ public class VMBot extends SessionAdapter {
 
     private Process process;
 
+    private final TruncatingStringBuilder buffer = new TruncatingStringBuilder(128);
+
+    private final UUID textDisplayUUID = UUID.randomUUID();
+
+    private String lastOutput = "";
+
+    private final Vector3i position = Vector3i.from(
+            Integer.parseInt(System.getProperty("x")),
+            Integer.parseInt(System.getProperty("y")),
+            Integer.parseInt(System.getProperty("z"))
+    );
+
     public VMBot () {
+        Runtime.getRuntime().addShutdownHook(new Thread(this::cleanup));
+
         this.bot = new BaseBot("vm");
 
+        final Timer timer = new Timer();
+        final TimerTask recreateTask = new TimerTask() {
+            @Override
+            public void run () {
+                recreate();
+            }
+        };
+        final TimerTask tickTask = new TimerTask() {
+            @Override
+            public void run () {
+                tick();
+            }
+        };
+        timer.schedule(recreateTask, 500, 2 * 1000);
+        timer.schedule(tickTask, 50, 50);
+
         bot.session.addListener(this);
 
         bot.core.addListener(new Core.Listener() {
             @Override
-            public void refilled() {
+            public void refilled () {
                 VMBot.this.coreRefilled();
             }
         });
@@ -39,11 +71,54 @@ public class VMBot extends SessionAdapter {
         bot.connect();
     }
 
+    private void recreate () {
+        if (!bot.loggedIn) return;
+
+        bot.core.run(String.format(
+                "summon text_display %d %d %d {UUID:%s}",
+
+                position.getX(),
+                position.getY(),
+                position.getZ(),
+
+                Utilities.snbt(textDisplayUUID)
+        ));
+
+        bot.core.run(String.format(
+                "minecraft:data merge entity %s {alignment:left,line_width:1024,shadow:1b,background:-16777216}",
+                Utilities.selector(textDisplayUUID)
+        ));
+    }
+
+    private void tick () {
+        if (!bot.loggedIn) return;
+
+        final String output = buffer.getString();
+
+        if (output.equals(lastOutput)) return;
+
+        lastOutput = output;
+
+        bot.core.run(String.format(
+                "data modify entity %s text set value '\"%s\"'",
+                Utilities.selector(textDisplayUUID),
+                output
+                        // insane regex
+                        .replaceAll("[\\u001B\\u009B][\\[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?(?:\\u0007|\\u001B\\u005C|\\u009C))|(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))", "")
+                        .replace("\r", "")
+                        .replace("\\", "\\\\\\\\")
+                        .replace("'", "\\'")
+                        .replace("\"", "\\\\")
+        ));
+    }
+
     private void coreRefilled () {
         if (started) return;
 
         started = true;
 
+        tick(); // creates the text display
+
         new Thread(() -> {
             try {
                 process = new ProcessBuilder(
@@ -72,25 +147,31 @@ public class VMBot extends SessionAdapter {
 
                 final BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
 
-                String output;
+                int character;
 
-                while ((output = reader.readLine()) != null) {
-                    if (output.isBlank()) continue;
-
-                    System.out.println(output);
-
-                    bot.chat.tellraw(
-                            Component.text(
-                                    output
-                                            // INSANE regex.
-                                            .replaceAll("[\\u001B\\u009B][\\[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?(?:\\u0007|\\u001B\\u005C|\\u009C))|(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))", "")
-                            )
-                    );
+                while ((character = reader.read()) != -1) {
+                    final char[] chars = Character.toChars(character);
+                    final String string = new String(chars);
+                    System.out.print(string);
+                    buffer.append(string);
                 }
             } catch (final IOException e) {
                 bot.chat.tellraw(Utilities.getErrorComponent(e));
             }
-        }).start();
+        }, "VM Process Thread").start();
+    }
+
+    private void cleanup () {
+        System.out.println("\n\nCleaning up...");
+
+        bot.core.run(String.format(
+                "kill %s",
+                Utilities.selector(textDisplayUUID)
+        ));
+
+        try {
+            Thread.sleep(500);
+        } catch (final InterruptedException ignored) { }
     }
 
     @Override
@@ -107,10 +188,6 @@ public class VMBot extends SessionAdapter {
             final OutputStream output = process.getOutputStream();
 
             if (content.trim().equalsIgnoreCase("sendc")) {
-                // ALSO clear the core queue
-
-                bot.core.clearQueue();
-
                 output.write("\u0003".getBytes());
                 output.flush();
 
@@ -127,4 +204,41 @@ public class VMBot extends SessionAdapter {
             bot.chat.tellraw(Utilities.getErrorComponent(e));
         }
     }
+
+    // chatgpt ahh code
+    private final static class TruncatingStringBuilder {
+        private final StringBuilder sb = new StringBuilder();
+        private final Deque<Integer> newlineIndices = new ArrayDeque<>();
+        private final int maxNewlines;
+
+        public TruncatingStringBuilder (final int maxNewlines) {
+            this.maxNewlines = maxNewlines;
+        }
+
+        public void append (final String str) {
+            for (int i = 0; i < str.length(); i++) {
+                final char c = str.charAt(i);
+                sb.append(c);
+
+                if (c == '\n') {
+                    newlineIndices.addLast(sb.length() - 1);
+
+                    if (newlineIndices.size() > maxNewlines) {
+                        final Integer cutoffIndex = newlineIndices.pollFirst(); // remove the oldest newline
+                        if (cutoffIndex == null) continue;
+                        sb.delete(0, cutoffIndex + 1);
+
+                        // Shift all stored newline indices accordingly
+                        for (int j = 0; j < newlineIndices.size(); j++) {
+                            newlineIndices.addLast(newlineIndices.pollFirst() - (cutoffIndex + 1));
+                        }
+                    }
+                }
+            }
+        }
+
+        public String getString () {
+            return sb.toString();
+        }
+    }
 }