Made it clearer how to run the bot yourself, and changed some formatting in the json
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
deleted file mode 100644
index f0b55ae..0000000
--- a/CODE_OF_CONDUCT.md
+++ /dev/null
@@ -1,128 +0,0 @@
-# Contributor Covenant Code of Conduct
-
-## Our Pledge
-
-We as members, contributors, and leaders pledge to make participation in our
-community a harassment-free experience for everyone, regardless of age, body
-size, visible or invisible disability, ethnicity, sex characteristics, gender
-identity and expression, level of experience, education, socio-economic status,
-nationality, personal appearance, race, religion, or sexual identity
-and orientation.
-
-We pledge to act and interact in ways that contribute to an open, welcoming,
-diverse, inclusive, and healthy community.
-
-## Our Standards
-
-Examples of behavior that contributes to a positive environment for our
-community include:
-
-* Demonstrating empathy and kindness toward other people
-* Being respectful of differing opinions, viewpoints, and experiences
-* Giving and gracefully accepting constructive feedback
-* Accepting responsibility and apologizing to those affected by our mistakes,
-  and learning from the experience
-* Focusing on what is best not just for us as individuals, but for the
-  overall community
-
-Examples of unacceptable behavior include:
-
-* The use of sexualized language or imagery, and sexual attention or
-  advances of any kind
-* Trolling, insulting or derogatory comments, and personal or political attacks
-* Public or private harassment
-* Publishing others' private information, such as a physical or email
-  address, without their explicit permission
-* Other conduct which could reasonably be considered inappropriate in a
-  professional setting
-
-## Enforcement Responsibilities
-
-Community leaders are responsible for clarifying and enforcing our standards of
-acceptable behavior and will take appropriate and fair corrective action in
-response to any behavior that they deem inappropriate, threatening, offensive,
-or harmful.
-
-Community leaders have the right and responsibility to remove, edit, or reject
-comments, commits, code, wiki edits, issues, and other contributions that are
-not aligned to this Code of Conduct, and will communicate reasons for moderation
-decisions when appropriate.
-
-## Scope
-
-This Code of Conduct applies within all community spaces, and also applies when
-an individual is officially representing the community in public spaces.
-Examples of representing our community include using an official e-mail address,
-posting via an official social media account, or acting as an appointed
-representative at an online or offline event.
-
-## Enforcement
-
-Instances of abusive, harassing, or otherwise unacceptable behavior may be
-reported to the community leaders responsible for enforcement at
-https://discord.gg/bPaNnxe.
-All complaints will be reviewed and investigated promptly and fairly.
-
-All community leaders are obligated to respect the privacy and security of the
-reporter of any incident.
-
-## Enforcement Guidelines
-
-Community leaders will follow these Community Impact Guidelines in determining
-the consequences for any action they deem in violation of this Code of Conduct:
-
-### 1. Correction
-
-**Community Impact**: Use of inappropriate language or other behavior deemed
-unprofessional or unwelcome in the community.
-
-**Consequence**: A private, written warning from community leaders, providing
-clarity around the nature of the violation and an explanation of why the
-behavior was inappropriate. A public apology may be requested.
-
-### 2. Warning
-
-**Community Impact**: A violation through a single incident or series
-of actions.
-
-**Consequence**: A warning with consequences for continued behavior. No
-interaction with the people involved, including unsolicited interaction with
-those enforcing the Code of Conduct, for a specified period of time. This
-includes avoiding interactions in community spaces as well as external channels
-like social media. Violating these terms may lead to a temporary or
-permanent ban.
-
-### 3. Temporary Ban
-
-**Community Impact**: A serious violation of community standards, including
-sustained inappropriate behavior.
-
-**Consequence**: A temporary ban from any sort of interaction or public
-communication with the community for a specified period of time. No public or
-private interaction with the people involved, including unsolicited interaction
-with those enforcing the Code of Conduct, is allowed during this period.
-Violating these terms may lead to a permanent ban.
-
-### 4. Permanent Ban
-
-**Community Impact**: Demonstrating a pattern of violation of community
-standards, including sustained inappropriate behavior,  harassment of an
-individual, or aggression toward or disparagement of classes of individuals.
-
-**Consequence**: A permanent ban from any sort of public interaction within
-the community.
-
-## Attribution
-
-This Code of Conduct is adapted from the [Contributor Covenant][homepage],
-version 2.0, available at
-https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
-
-Community Impact Guidelines were inspired by [Mozilla's code of conduct
-enforcement ladder](https://github.com/mozilla/diversity).
-
-[homepage]: https://www.contributor-covenant.org
-
-For answers to common questions about this code of conduct, see the FAQ at
-https://www.contributor-covenant.org/faq. Translations are available at
-https://www.contributor-covenant.org/translations.
diff --git a/README.md b/README.md
index b2a680c..175654c 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@
 - [Commands](#commands)
 - [Verification](#verification)
 - [Privacy](#privacy)
-- [Legal](#legal)
+- [Self hosting and Legal](#self-hosting)
 
 ### About
 
@@ -48,15 +48,15 @@
 - `/user avatar` Shows the user avatar.
 - `/user track` Allows you to move a user up and down a role track.
 
-- `/tags create` Creates a tag
-- `/tags edit` Edits a tag
-- `/tags delete` Deletes a tag
+- `/tags create` Creates a tag.
+- `/tags edit` Edits a tag.
+- `/tags delete` Deletes a tag.
 
 - `/verify` Verifies a member to give them access to the server.
 - `/help` Shows all commands on Nucleus.
 - `/privacy` Information and options for server and user privacy.
 - `/rolemenu` Lets users select roles, similar to reaction roles.
-- `/tag` Lets users use tags created with `/tags create`
+- `/tag` Lets users use tags created with `/tags create`.
 
 
 ### Verification
@@ -67,10 +67,10 @@
 
 ### Privacy
 
-You can run `/privacy` to view and manage all data stored about your server
+You can run `/privacy` to view and manage all data stored about your server.
 
 You should always know what we know and store about you, so here is the complete list.
 
-### Legal
+### Self hosting
 
-Before copying, modifying or running our code, please read [COPYING](https://github.com/ClicksMinutePer/Nucleus/blob/development/COPYING.md)
+Nucleus is fully open source, and you can run your own copy. Read [COPYING.md](https://github.com/ClicksMinutePer/Nucleus/blob/development/COPYING.md) for the legal requirements and a guide for how to configure your own copy.
diff --git a/src/actions/roleMenu.ts b/src/actions/roleMenu.ts
index 7432a3a..21e97ec 100644
--- a/src/actions/roleMenu.ts
+++ b/src/actions/roleMenu.ts
@@ -63,7 +63,7 @@
                     .setLabel("Online")
                     .setStyle("LINK")
                     .setDisabled(!up)
-                    .setURL(`${client.config.baseUrl}/nucleus/rolemenu?code=${code}`),
+                    .setURL(`${client.config.baseUrl}nucleus/rolemenu?code=${code}`),
                 new MessageButton()
                     .setLabel("Manual")
                     .setStyle("PRIMARY")
diff --git a/src/config/format.js b/src/config/format.js
new file mode 100644
index 0000000..f87c9f7
--- /dev/null
+++ b/src/config/format.js
@@ -0,0 +1,96 @@
+import fs from 'fs';
+import * as readLine from 'node:readline/promises';
+import { exec } from 'node:child_process';
+
+const defaultDict = {
+    "token": "Your bot token",
+    "developmentToken": "Your development bot token",
+    "managementGuildID": "Your management guild ID",
+    "developmentGuildID": "Your development guild ID",
+    "enableDevelopment": true,
+    "owners": [],
+    "verifySecret": "If using verify, enter a code here which matches your website if needed",
+    "mongoUrl": "Your Mongo connection string, e.g. mongodb://127.0.0.1:27017",
+    "baseUrl": "Your website where buttons such as Verify will link to, e.g. https://example.com",
+    "pastebinApiKey": "An API key for pastebin (optional)",
+    "pastebinUsername": "Your pastebin username (optional)",
+    "pastebinPassword": "Your pastebin password (optional)",
+}
+
+const readline = readLine.createInterface({
+    input: process.stdin,
+    output: process.stdout,
+});
+
+async function getInput(prompt) {
+    process.stdout.write(prompt);
+
+    const answer = await readline.question(prompt);
+    return answer.toString();
+}
+
+
+export default async function(walkthrough = false) {
+    if (walkthrough) {
+        console.log("\x1b[33m🛈  Entering walkthrough mode for any missing values.");
+        console.log("   \x1b[2mIf you don't want to enter a value, just hit enter.\x1b[0m\n");
+
+        // let toUse = await getInput("\x1b[36m[Installing packages] Use Yarn or NPM? \x1b[0m(\x1b[32my\x1b[0m/\x1b[31mN\x1b[0m) > ");
+        // toUse = toUse.toLowerCase() === "y" ? "yarn install" : "npm i";
+        // if ((await getInput(`\x1b[36m[Installing packages] Run ${toUse}? \x1b[0m(\x1b[32mY\x1b[0m/\x1b[31mn\x1b[0m) > `)).toLowerCase() !== "n") {
+        //     console.log(`\x1b[32m[Installing packages] Running ${toUse}...\x1b[0m`);
+        //     await exec(toUse);
+        //     console.log(`\x1b[32m[Installing packages] Installed\x1b[0m`);
+        // } else {
+        //     console.log("\x1b[32m[Installing packages] Skipping...\x1b[0m");
+        // }
+    }
+
+    let json;
+    let out = true
+    try {
+        json = JSON.parse(fs.readFileSync('./src/config/main.json', 'utf8'));
+    } catch (e) {
+        console.log("\x1b[31mâš  No main.json found, creating one.")
+        console.log("  \x1b[2mYou can edit src/config/main.json directly using template written to the file.\x1b[0m\n")
+        out = false
+        json = {}
+    }
+    for (const key in defaultDict) {
+        if (!json[key]) {
+            if (walkthrough) {
+                switch (key) {
+                    case "enableDevelopment": {
+                        json[key] = (await getInput("\x1b[36mEnable development mode? \x1b[0m(\x1b[32mY\x1b[0m/\x1b[31mn\x1b[0m) > ") || "Y").toLowerCase() === "y"; break;
+                    } case "owners": {
+                        let chosen = "!";
+                        let toWrite = []
+                        while (chosen !== "") {
+                            chosen = await getInput("\x1b[36mEnter an owner ID \x1b[0m(\x1b[35mleave blank to finish\x1b[0m) > ");
+                            if (chosen !== "") { toWrite.push(chosen); }
+                        }
+                        json[key] = toWrite; break;
+                    } default: {
+                        json[key] = await getInput(`\x1b[36m${key} \x1b[0m(\x1b[35m${defaultDict[key]}\x1b[0m) > `);
+                    }
+                }
+            }
+            else { json[key] = defaultDict[key] }
+        }
+    }
+    if (!json.mongoUrl.endsWith("/")) json.mongoUrl += "/";
+    if (!json.baseUrl.endsWith("/")) json.baseUrl += "/";
+    let hosts = fs.readFileSync('/etc/hosts', 'utf8').toString().split("\n");
+    let localhost = hosts.find(line => line.split(" ")[1] === "localhost");
+    if (localhost) { localhost = localhost.split(" ")[0]; }
+    else { localhost = "127.0.0.1" }
+    json.mongoUrl = json.mongoUrl.replace("localhost", localhost);
+    json.baseUrl = json.baseUrl.replace("localhost", localhost);
+
+    fs.writeFileSync("./src/config/main.json", JSON.stringify(json, null, 4))
+
+    if (walkthrough) {
+        console.log("\x1b[32m✓ All properties added.\x1b[0m")
+    }
+    return out;
+}
diff --git a/src/reflex/verify.ts b/src/reflex/verify.ts
index b95cdb7..b95d5db 100644
--- a/src/reflex/verify.ts
+++ b/src/reflex/verify.ts
@@ -133,6 +133,6 @@
     ], components: [new Discord.MessageActionRow().addComponents([new Discord.MessageButton()
         .setLabel("Verify")
         .setStyle("LINK")
-        .setURL(`${client.config.baseUrl}/nucleus/verify?code=${code}`)
+        .setURL(`${client.config.baseUrl}nucleus/verify?code=${code}`)
     ])]});
 }
diff --git a/tsconfig.json b/tsconfig.json
index 591467f..e38a3bc 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -11,6 +11,6 @@
         "moduleResolution": "node",
         "skipLibCheck": true
     },
-    "include": ["src/**/*"],
+    "include": ["src/**/*", "isntaller.js"],
     "exclude": []
 }
\ No newline at end of file