COMMAND REGISTRATION WORKS
diff --git a/src/utils/client.ts b/src/utils/client.ts
index 1795cfa..7d608c7 100644
--- a/src/utils/client.ts
+++ b/src/utils/client.ts
@@ -1,13 +1,39 @@
-// @ts-expect-error
-import { HaikuClient } from "jshaiku";
-import { Intents } from "discord.js";
-import config from "../config/main.json" assert { type: "json" };
+import { Client } from 'discord.js';
+import { Logger } from "../utils/log.js";
+import Memory from "../utils/memory.js";
+import type { VerifySchema } from "../reflex/verify.js";
+import { Guilds, History, ModNotes, Premium } from "../utils/database.js";
+import EventScheduler from "../utils/eventScheduler.js";
+import type { RoleMenuSchema } from "../actions/roleMenu.js";
 
-const client = new HaikuClient(
-    {
-        intents: new Intents(32767).bitfield // This is a way of specifying all intents w/o having to type them out
-    },
-    config
-);
+
+class NucleusClient extends Client {
+    logger = Logger;
+    verify: Record<string, VerifySchema> = {};
+    roleMenu: Record<string, RoleMenuSchema> = {};
+    memory: Memory = new Memory() as Memory;
+    noLog: string[] = [];
+    database: {
+        guilds: Guilds;
+        history: History;
+        notes: ModNotes;
+        premium: Premium;
+        eventScheduler: EventScheduler;
+    };
+
+    constructor(database: typeof NucleusClient.prototype.database) {
+        super({ intents: 32767 });
+        this.database = database;
+    }
+}
+
+const client = new NucleusClient({
+    guilds: new Guilds(),
+    history: new History(),
+    notes: new ModNotes(),
+    premium: new Premium(),
+    eventScheduler: new EventScheduler()
+});
 
 export default client;
+export { NucleusClient };
\ No newline at end of file
diff --git a/src/utils/commandRegistration/getFilesInFolder.ts b/src/utils/commandRegistration/getFilesInFolder.ts
new file mode 100644
index 0000000..a669065
--- /dev/null
+++ b/src/utils/commandRegistration/getFilesInFolder.ts
@@ -0,0 +1,23 @@
+import fs from "fs";
+
+export default async function getSubcommandsInFolder(path: string) {
+    const files = fs.readdirSync(path, { withFileTypes: true }).filter(
+        file => !file.name.endsWith(".ts") && !file.name.endsWith(".map")
+    );
+    const subcommands = [];
+    const subcommandGroups = [];
+    for (const file of files) {
+        if (file.name === "_meta.js") continue;
+        // If its a folder
+        if (file.isDirectory()) {
+            // Get the _meta.ts file
+            console.log(`│ ├─ Loading subcommand group ${file.name}}`)
+            subcommandGroups.push((await import(`../../../${path}/${file.name}/_meta.js`)).command);
+        } else if (file.name.endsWith(".js")) {
+            // If its a file
+            console.log(`│ ├─ Loading subcommand ${file.name}}`)
+            subcommands.push((await import(`../../../${path}/${file.name}`)).command);
+        }
+    }
+    return {subcommands, subcommandGroups};
+}
diff --git a/src/utils/commandRegistration/register.ts b/src/utils/commandRegistration/register.ts
new file mode 100644
index 0000000..af0b5fc
--- /dev/null
+++ b/src/utils/commandRegistration/register.ts
@@ -0,0 +1,61 @@
+import { SlashCommandBuilder } from 'discord.js';
+import config from "../../config/main.json" assert { type: "json" };
+import client from "../client.js";
+import fs from "fs";
+
+
+async function registerCommands() {
+    const developmentMode = config.enableDevelopment;
+    const commands = [];
+
+    const files = fs.readdirSync(config.commandsFolder, { withFileTypes: true }).filter(
+        file => !file.name.endsWith(".ts") && !file.name.endsWith(".map")
+    );
+    console.log(`Registering ${files.length} commands`)
+    let i = 0;
+    for (const file of files) {
+        // Box drawing characters: | └ ─ ┌ ┐ ┘ ┬ ┤ ├ ┴ ┼
+        console.log(`├─ ${file.name}`)
+        if (file.isDirectory()) {
+            commands.push((await import(`../../../${config.commandsFolder}/${file.name}/_meta.js`)).command);
+        } else if (file.name.endsWith(".js")) {
+            commands.push((await import(`../../../${config.commandsFolder}/${file.name}`)).command);
+        }
+        i++;
+        console.log(`├─ Loaded ${file.name} [${i} / ${files.length}]`)
+    }
+    console.log(`Loaded ${commands.length} commands, processing...`)
+    const processed = []
+
+    for (const subcommand of commands) {
+        if (subcommand instanceof Function) {
+            processed.push(subcommand(new SlashCommandBuilder()))
+        } else {
+            processed.push(subcommand)
+        }
+    }
+
+    console.log(`Processed ${commands.length} commands, registering...`)
+
+    if (developmentMode) {
+        const guild = await client.guilds.fetch(config.developmentGuildID);
+        guild.commands.set([])
+        guild.commands.set(processed);
+        console.log(`Commands registered in ${guild.name}`)
+    } else {
+        client.application!.commands.set([])
+        client.application!.commands.set(processed);
+        console.log(`Commands registered globally`)
+    }
+
+};
+
+async function registerEvents() {
+    // pass
+};
+
+export default async function register() {
+    console.log("> Registering commands")
+    await registerCommands();
+    await registerEvents();
+};
diff --git a/src/utils/commandRegistration/slashCommandBuilder.ts b/src/utils/commandRegistration/slashCommandBuilder.ts
new file mode 100644
index 0000000..719855f
--- /dev/null
+++ b/src/utils/commandRegistration/slashCommandBuilder.ts
@@ -0,0 +1,37 @@
+import type { SlashCommandSubcommandGroupBuilder } from "@discordjs/builders";
+import type { SlashCommandBuilder } from "discord.js";
+import config from "../../config/main.json" assert { type: "json" };
+import getSubcommandsInFolder from "./getFilesInFolder.js";
+
+
+export async function group(name: string, description: string, path: string) {
+    const fetched = await getSubcommandsInFolder(config.commandsFolder + "/" + path)
+    return (subcommandGroup: SlashCommandSubcommandGroupBuilder) => {
+        subcommandGroup
+            .setName(name)
+            .setDescription(description)
+
+        for (const subcommand of fetched.subcommands) {
+            subcommandGroup.addSubcommand(subcommand);
+        };
+
+        return subcommandGroup;
+    };
+}
+
+export async function command(name: string, description: string, path: string) {
+    const fetched = await getSubcommandsInFolder(config.commandsFolder + "/" + path);
+    console.log(`│ ├─ Loaded ${fetched.subcommands.length} subcommands and ${fetched.subcommandGroups.length} subcommand groups for ${name}`)
+    return (command: SlashCommandBuilder) => {
+        command.setName(name)
+        command.setDescription(description)
+
+        for (const subcommand of fetched.subcommands) {
+            command.addSubcommand(subcommand);
+        }
+        for (const group of fetched.subcommandGroups) {
+            command.addSubcommandGroup(group);
+        };
+        return command;
+    };
+}
diff --git a/src/utils/log.ts b/src/utils/log.ts
index e4ac4cd..a578b69 100644
--- a/src/utils/log.ts
+++ b/src/utils/log.ts
@@ -7,58 +7,54 @@
 
 const wait = promisify(setTimeout);
 
-export class Logger {
+
+export const Logger = {
     renderUser(user: Discord.User | string) {
         if (typeof user === "string") return `${user} [<@${user}>]`;
         return `${user.username} [<@${user.id}>]`;
-    }
+    },
     renderTime(t: number) {
         t = Math.floor((t /= 1000));
         return `<t:${t}:D> at <t:${t}:T>`;
-    }
+    },
     renderDelta(t: number) {
         t = Math.floor((t /= 1000));
         return `<t:${t}:R> (<t:${t}:D> at <t:${t}:T>)`;
-    }
+    },
     renderNumberDelta(num1: number, num2: number) {
         const delta = num2 - num1;
         return `${num1} -> ${num2} (${delta > 0 ? "+" : ""}${delta})`;
-    }
+    },
     entry(value: string, displayValue: string): { value: string; displayValue: string } {
         return { value: value, displayValue: displayValue };
-    }
+    },
     renderChannel(channel: Discord.GuildChannel | Discord.ThreadChannel) {
         return `${channel.name} [<#${channel.id}>]`;
-    }
+    },
     renderRole(role: Discord.Role) {
         return `${role.name} [<@&${role.id}>]`;
-    }
+    },
     renderEmoji(emoji: Discord.GuildEmoji) {
         return `<${emoji.animated ? "a" : ""}:${emoji.name}:${emoji.id}> [\`:${emoji.name}:\`]`;
-    }
-
-    public readonly NucleusColors: Record<string, number> = {
+    },
+    NucleusColors: {
         red: 0xf27878,
         yellow: 0xf2d478,
         green: 0x68d49e
-    };
-
-    async getAuditLog(
-        guild: Discord.Guild,
-        event: Discord.GuildAuditLogsResolvable
-    ): Promise<Discord.GuildAuditLogsEntry[]> {
+    },
+    async getAuditLog(guild: Discord.Guild, event: Discord.GuildAuditLogsResolvable): Promise<Discord.GuildAuditLogsEntry[]> {
         await wait(250);
         const auditLog = await guild.fetchAuditLogs({ type: event });
         return auditLog as unknown as Discord.GuildAuditLogsEntry[];
-    }
-
+    },
     // eslint-disable-next-line @typescript-eslint/no-explicit-any
     async log(log: any): Promise<void> {
         const config = await client.database.guilds.read(log.hidden.guild);
         if (!config.logging.logs.enabled) return;
         if (!(log.meta.calculateType === true)) {
             if (!toHexArray(config.logging.logs.toLog).includes(log.meta.calculateType))
-                return console.log("Not logging this type of event");
+                console.log("Not logging this type of event");
+            return;
         }
         if (config.logging.logs.channel) {
             const channel = (await client.channels.fetch(config.logging.logs.channel)) as Discord.TextChannel | null;
@@ -79,8 +75,8 @@
                     .setTitle(`${getEmojiByName(log.meta.emoji)} ${log.meta.displayName}`)
                     .setDescription(
                         (log.separate.start ? log.separate.start + "\n" : "") +
-                            generateKeyValueList(description) +
-                            (log.separate.end ? "\n" + log.separate.end : "")
+                        generateKeyValueList(description) +
+                        (log.separate.end ? "\n" + log.separate.end : "")
                     )
                     .setTimestamp(log.meta.timestamp)
                     .setColor(log.meta.color);
@@ -88,6 +84,7 @@
             }
         }
     }
-}
+};
+
 
 export default {};