Adonis Admin Setup Guide for Developers

A Developer’s Guide to Setting up the Adonis Administration System

Written By:

image @Expertcoder2, Adonis Developer on GitHub

Thanks to @ar_qx for the original guide. This is intended to be a more comprehensive and polished version.



adonis

:page_facing_up: Preface

Adonis is a major open source administration and moderation system for ROBLOX games, distributed under the MIT license.

Some features of Adonis include:

  • Over 400 commands including optional fun commands and utility commands for players

  • Highly configurable ranks and permissions system

  • Cross-server administration and extensive logging

  • Trello functionality to globally manage and sync configurations and permissions across games

  • Support for loader plugins with access to the rich and modular API for modifying functionality, implementing custom commands etc. (see documentation link below)

  • Support for custom UI themes and creation of your own Adonis-based UIs using the aforementioned API

  • Built with security against exploits, by design; we never simply obfuscate our code

  • [Experimental] WebPanel to manage your game servers remotely

Furthermore, Adonis is updated and maintained regularly by a community of contributors ie. volunteering devs. The original creator and developer is @Davey_Bones aka Sceleratis.

To learn more or receive quick support, make bug reports or feature requests, join our official Discord server from the link below.


:link: Relevant Links:


:warning: Advisory

It is known that there are many non-official copies of the Adonis admin loader found in the Studio toolbox and library. Many of these models are uploaded by individuals of malicious intent and may open up backdoors/viruses to games using them. Or, they may simply be outdated.

Anyways, just be sure you’re using the official loader taken from the link above, and you’ll be fine. Edit: In addition to malicious loaders/models, certain Studio plugins may also attempt to hijack your copy of the Adonis loader and modify it such as to redirect to another module. Therefore, always exercise caution when installing plugins from unknown sources.

:sparkles: Installation - Getting Started

  1. Grab the Adonis loader.

  2. Insert it into your game via the toolbox (Inventory tab).

  3. Optionally move it into ServerScriptService. It is best not to rename the “Adonis_Loader” model. You can, however, delete “ThumbnailCamera”.
    image

  4. Open the Config > Settings module script as highlighted above. In it, you’ll see something like this:

  5. Scroll down to the following lines. Change settings.DataStoreKey to any random string (random as in "q5'j#1uZrUC-" or equivalent, just make sure nobody can guess it).

Info - Why is the DataStoreKey important?

Because it specifies where persistent data such as permissions (ranks), warnings and bans assigned in-game, as well as settings/preferences for individual players (ie. player data) are saved by Adonis.

Having a randomized datastore key is a security measure against malicious server side scripts (or admins using the :s <code> command) attempting to tamper with the data, since the exact key is needed to access the data.

This is what you’ll get in-game if you leave the DataStoreKey as “CHANGE_THIS”:
image


:gear: Configuring Adonis

📑 Accepted Entry Formats for Permission Lists
  • "USERNAME" - "SomeRandomGuy"

  • "USERNAME:USER_ID" - "SomeRandomGuy:12345678"

  • "Group:GROUP_ID:GROUP_RANK - "Group:12345678:40"
    Note: place ‘-’ before the group rank to specify users of the rank and any ranks above, eg. Group:12345678:-100 which will give perms to people with rank 100+ in the group of ID 12345678.

  • "Item:ASSET_ID" - "Item:12345678"

  • "GamePass:GAMEPASS_ID" - "GamePass:12345678"

:grey_question: Hint

User, group, asset and gamepass IDs can be found in their Roblox website URLs. For instance:


:warning: Remember: Anything you set under the loader settings is considered permanent and cannot be modified in-game except by people of the Creators permission level. If you wish to assign temporary/provisional permissions, bans etc., do it in-game using commands.

📁 Assigning People to Ranks

To get started, simply edit the tables in settings.Ranks, as shown below (you may refer to the Accepted Entry Formats):

📁 Customizing the Hierarchy (Ranks) Structure

You can add custom ranks:

image

You can hide specific ranks from the in-game admin list UI (accessed via the :admins command):

image

:exclamation: Note on Renaming

If you wish to rename the existing default ranks, such as “Moderators” to “Mods”, you must first hide the existing rank in question before adding a rank of the same level, otherwise Adonis will still think that it exists as a separate rank. For example:

📁 Configuring Bans, Mutes, Blacklist and Whitelist

settings.Banned - People who are permanently prohibited from joining the game.
settings.Muted - People who are permanently prevented from using the in-game chat.
settings.Blacklist - People who are always disallowed from running Adonis commands.
settings.Whitelist - People who are always allowed to join while server whitelist ie. serverlock is in effect.

(You may refer to the Accepted Entry Formats.)

📁 Customizing Command Permissions

You can modify the rank required to run certain commands with settings.Permissions (which is especially useful when implementing custom ranks).

  • To restrict command CMD to ranks of level LVL and higher: CMD:LVL
  • To restrict command CMD to ranks of exact levels LVL1, LVL2, LVL3… only: CMD:LVL1,LVL2,LVL3,... (no spaces after commas)
  • To allow command CMD to be run by everyone: CMD:0

Note: You do not have to include command prefixes (the “:” in “:kill all”) when configuring permissions.


📂 Additional Command-Related Settings

Refer to this for a list of possible values for settings.ConsoleKeyCode.

[boolean] settings.FunCommands - Whether or not entertaining but non-essential commands are enabled.
[boolean] settings.PlayerCommands - Whether or not player utility/informative commands (such as !notepad) are usable by players.
[boolean] settings.CrossServerCommands - Whether or not commands that affect more than one server (such as :globalvote) are enabled.
[boolean] settings.ChatCommands - Whether or not commands can be run from the chat. If set to false, the console will have to be used for commands.
[boolean] settings.Console - Whether or not the Adonis command console (an alternative interface to the chat for silently running commands, opened by pressing the key specified in settings.ConsoleKeyCode) is enabled.
[boolean] settings.Console_AdminsOnly - Whether or not the console can only be used by people with admin permissions.

This is NOT a comprehensive list of settings provided in the configuration module. The rest is up to you to explore. :slight_smile:

📂 Conveniently Implementing Custom Commands

Please refer to The Structure of an Adonis command near the bottom of this article for more information on scripting commands.

You can also replace commands here. To get an existing Adonis command’s index for overriding it, you’ll have to look for the command itself in MainModule > Server > Commands.

Using settings.Commands for adding custom commands is essentially equivalent to having a server plugin module placed in Adonis_Loader > Config > Plugins. (See Plugins section below.) However, plugins will still be needed if you’re looking to specifically modify parts of existing commands (such as Description, instead of overriding the entire command structure) or completely remove an existing command.


The Help Button

You may have noticed in-game that Adonis comes with a button at the bottom right corner of the screen that opens the userpanel when clicked:

image

This button is not intended to be a watermark and can be disabled or customized by the following settings:


Donor Perks

Adonis by default includes aesthetic perks for players who have purchased the donation pass/shirt (intended to support development), on the in-game donation panel:

These perks can be disabled if you wish, by configuring the following settings:


Anti-Exploit System

NOTE: This section may be outdated.

Adonis includes an optional and configurable system to counter a few simple exploits:

settings.AntiNil = true				-- Try's to prevent non-admins from hiding in "nil"
settings.AntiSpeed = true 			-- Attempts to detect speed exploits
settings.AntiNoclip = true			-- Attempts to detect noclipping and kills the player if found
settings.AntiParanoid = false		-- Attempts to detect paranoid and kills the player if found
settings.AntiBuildingTools = false	-- Attempts to detect any HopperBin(s)/Building Tools added to the client
settings.AntiLeak = false			-- Attempts to prevent place downloading/saving; Do not use if game saves

Note the following:

  • By design, Adonis will always attempt to protect itself from modification or tampering by exploiters/malicious scripts.

  • The additional anti-exploit features Adonis provides is not intended to be comprehensive or fully effective in stopping all known exploits, as Adonis is an administration and not a dedicated anticheat system.


:scroll: Using the Adonis Global API

Adonis provides an optional _G API for accessing the system from other scripts, allowing developers to connect it with their games for better integration.

If you require only basic access to functions such as _G.Adonis.CheckAdmin(player) (NOTE: actual documentation for the functions _G.Adonis provides has yet to be written; we’re still working on it), leaving settings.G_API = true will do.

However, for advanced access to the internals of Adonis (you probably don’t need this), settings.G_Access must be enabled and settings.G_Access_Key set to something secret/random. You can then expose Adonis core modules in other scripts using _G.Adonis.Access("SomeRandomKey", "Admin/Functions/Variables/Logs/UI etc.").

Refer to the API documentation for in-depth usage information.


:jigsaw: Plugins

Plugins allow developers to modify Adonis without needing to edit the MainModule. This means that, along with UI themes, they allow for integrations of nearly limitless possibilities, from adding custom commands and modifying/removing existing commands, to altering core functionality and behavior. Plugins run in an environment such that they have full access to the Adonis API.

There are two types of Adonis plugins: client plugins and server plugins. Server plugins are most often used to implement custom commands.

Plugins go under Adonis_Loader > Config > Plugins:

image

Important: In order for Adonis to determine whether each loader plugin belongs to the client or server, their module names must be prefixed with “Client/Server-” or "Client/Server: ". For example, “Server-MyCommands” or “Client: MyRandomPlugin”.

:wrench: Making Plugins

Plugin development is explained in the API documentation linked at the top of this page.

Some scripting knowledge may be necessary.


:art: UI Themes

Adonis comes with the following themes by default:

Default


image

image

Mobilius

Essentially Default with some non-mobile-friendly elements removed.

Rounded

Simply modifies the default theme to add UICorners to each element. And also includes a different-looking command console.


image

Colorize

With animated rainbow effect.

Aero

Designed by me! With sound effects and animations.


image

Unity



Windows XP


image

BasicAdmin

(Modifies only message UIs.)


Legacy Themes (unmaintained)

Some older themes Adonis once included (Steampunk, Hydris, etc.) but got removed for lack of quality/use can be found and downloaded here.


You can specify the game theme from the following loader settings:

Note: By default, individual players are still able to change their own displayed theme in-game under the Client tab of the userpanel:


The “Game Theme” option refers to the theme specified by settings.Theme.

Implementing Custom Themes

To add a custom Adonis UI theme that can be used in your game, place the theme folder in Adonis_Loader > Config > Themes:

image

Remember to edit the loader settings to apply your theme as desired:

:paintbrush: Creating Custom Themes

The actual process of making an Adonis theme is rather challenging to describe. Also, it typically requires some capability in scripting/UI design, and, as with plugin development, even more exploration and familiarization with the Adonis internal API and UI framework.

To achieve this and understand how everything works, you’d want to look into the built-in themes themselves which are stored under MainModule > Client > UI:

image

Some useful explanation is provided in the code modules responsible for each theme’s appearance and behavior.

The official API documentation as linked at the top of this page may also help. Otherwise, feel free to ask for help in the Adonis community server.

An example of a theme that I produced


:page_facing_up: Additional Information

:exclamation: A note on forking Adonis (the MainModule)

Some developers have been known to edit the MainModule itself to customize Adonis for their own games. This is actually almost always not necessary, as loader plugins and themes are already capable of changing nearly anything conceivable inside Adonis without making an entire copy of the MainModule. Unless you’re at this level, it isn’t wise to maintain such a thing which means having to manually port updates/patches over from mainstream Adonis.

Reference: The structure of an Adonis command (read to understand making custom commands)

Here’s how an Adonis command looks like:

ExampleCommand1 = {								--// The index & table of the command
	Prefix = Settings.Prefix;				--// The prefix the command will use, this is the ':' in ':ff me'
	Commands = {"examplecommand1", "examplealias1", "examplealias2"};	--// A table containing the command strings (the things you chat in-game to run the command, the 'ff' in ':ff me')
	Args = {"arg1", "arg2", "etc"};	--// Command arguments, these will be available in order as args[1], args[2], args[3], etc; This is the 'me' in ':ff me'
	Description = "Example command";--// The description of the command
	AdminLevel = 100; -- Moderators	--// The commands minimum admin level; This can also be a table containing specific levels rather than a minimum level: {124, 152, "HeadAdmins", etc};
	-- Alternative option: AdminLevel = "Moderators"
	Filter = true;									--// Should user supplied text passed to this command be filtered automatically? Use this if you plan to display a user-defined message to other players
	Hidden = true;									--// Should this command be hidden from the command list?
	Disabled = true;								--// Should this command be unusable?
	Function = function(plr: Player, args: {string}, data: {})	--// The command's function; This is the actual code of the command which runs when you run the command
			--// "plr" is the player running the command
			--// "args" is a table containing command arguments supplied by the user
			--// "data" is a table containing information related to the command and the player running it, such as data.PlayerData.Level (the player's admin level)
			print("This is 'arg1':", args[1])
			print("This is 'arg2':", args[2])
			print("This is 'etc'(arg 3):", args[3])
			error("this is an example error :o !")
	end
};

All commands are contained with the server.Commands table.

  • ExampleCommand1

This is the index and table of the command, a unique internal identifier as in server.Commands.ExampleCommand1.

Note: In Adonis plugins and custom command code you can use this to refer to specific other commands for doing something with them. Changes to the server.Commands dictionary (which ultimately contains all registered commands) are live in the game so it’s possible to make, for instance, a command that disables another command by server.Commands.ExampleCommand1.Disabled = true.

  • Prefix: string

This is the prefix used to run the command, eg. the “:” in “:kill someplayer”. Setting this to (server.)Settings.Prefix will tell Adonis to use the prefix configured in the loader settings. For player-use commands, this should (but need not) be set to (server.)Settings.PlayerPrefix. The default player prefix used would be “!” as in “!notepad”.

  • Commands: {string}

This is an array of names or aliases that can be used to run/refer to the same command. For example, {"removetools", "notools"} so that running “:notools” in-game is the same as running “:removetools”. This can also be used to implement shorthands such as “m” for the “message” command. The first string in the array will be the name listed the commands list UI (:cmds).

  • Args: {string}

This is an array of the names of arguments the command expects to take during execution. For example, Args = {"player", "tool"} for a “:give <player> <tool>” command. The first argument “player” tells the command function which player(s) to give to, and the second argument “tool” specifies the name of the tool to give. More about arguments will be explained ahead.

If your command doesn’t require any arguments behind it, such as the “:savemap” or “!notepad” commands, simply leave Args = {} (empty table). If your command accepts optional arguments, as many do, just include them in Args and handle them later in the Function.

  • Description: string

This is what you want to tell your players/admins what the command does when run. It will be shown in the in-game command list (:cmds) and command info (:cmdinfo <command>) UIs.

  • AdminLevel: number|string|{number|string}

This determines the permission required for people to execute the command. It can be any of the following:

  1. A number specifying the minimum admin rank allowed, such as 100 for “Moderators” (by default)

  2. A string that is the name of the minimum admin rank allowed, such as "Moderators"

  3. A table containing specific allowed levels rather than a minimum level: {100, 150, "HeadAdmins", etc} (only the specified ranks will be allowed to run the command)

  • Filter: boolean? = false

If this is set to true, any string arguments a player specifies according to the Args table will be filtered by ROBLOX before being passed to the command’s Function (see below) This is a simple way for filtering message/publicly-visible text input without having to handle it in the Function later.

  • Hidden: boolean? = false

If set to true, the command will not be shown on the in-game command list (:cmds) and will not appear in the console autocomplete (by default). This feature is useful for hiding secret commands!

  • Disabled: boolean? = false

If set to true, the command will not be usable.

  • Function: (plr: Player?, args: {string}, data: {}) -> ()

This is where all the action happens when the command is executed. plr is the player running the command (or nil if run by the system) and args is an array of strings containing the raw string arguments passed in sequence behind the command (delimited by Settings.SplitKey in the loader settings).

For example, Player1 runs “:pm player2 Hello there!”. This will result in

plr = Player1 --(the Player object)

and

args = {[1] = "player2", [2] = "Hello there!"}

being passed to the Function.

Note that the arguments fed to the Function in args are in strings as what the player typed out. You’ll have to interpret and convert them to the relevant types in the Function code. If the desired argument type is a player/set of target players to be selected for running the command on (such as in “:kill <player(s)>”), use the following code to obtain the desired players from the raw string argument:

for _, v: Player in ipairs(service:GetPlayers(plr, args[1])) do
	--// Sample code using the Adonis API (server.Remote)
	--// The stuff below runs on the selected players according to the args[1] string (first command argument)
	server.Remote.MakeGui(v, "Notification", {
		Title = "Hello, "..v.DisplayName;
		Message = "You are about to get respawned!";
		Time = 10;
	})
	v:LoadCharacter() --respawn
end

You may have noticed the plr being supplied in service:GetPlayers(plr, args[1]). This is to facilitate player selections such as “me” or “others” that depend on the player running the command.

Finally, data is a table containing information related to the command and the player running it, such as data.PlayerData.Level (the player’s admin level). For in-depth info on this, please refer to the API documentation.

Adonis catches errors from command Functions and displays them in the form of an error message UI to the player running the command (if any). This can be used with error or assert to express errors such as for invalid arguments supplied.

Once again, refer to the API docs for details and useful built-in functions Adonis provides that can be used in your command/plugin code.


End of Guide

Questions? Comments? Suggestions? Criticisms? Reply to this topic or join our community server!

14 Likes

Excellent in depth tutorial, mine was intended for extremely new people that need admin help and wanted it straight to the point; I’m assuming you’re making a more advance tutorial going into plugins and external scripts working together with adonis? Either way I’ll link you tutorial as a more advance version on my post! Thank you for @'ing me too! It means a lot.

note: i did read this and are still assuming what i said

3 Likes

This guide is

1 Like

I had no idea that these were possible, thanks for the tutorial

1 Like

Go more in depth with custom commands and arguments please and thank you. Like for commands you don’t want arguments for what would you do? How would you do it?

1 Like

If you don’t require arguments for a command, just leave the Args table empty? There isn’t much to say about this really, and the info needed to work with custom Adonis commands is provided in API docs assuming prior scripting knowledge. But I do agree that more about that can be covered here to give developers a useful start and clarify how things work. Will begin writing right away edit: I’ve just expanded the section about the command table structure, thanks!

2 Likes

Adonis 2.0? Cringe.
Aside from that, _G documentation please???

1 Like

Hello noob kind sir,
What does the “MIT” License mean?

Hi I am trying to make a new command. How would I go about making a GUI For this?

xp = {
		Prefix = Settings.PlayerPrefix;
		Commands = {"xp"};
		Args = {};
		Hidden = false;
		Description = "Shows your current XP in NHC concepts.";
		Fun = false;
		AdminLevel = "Players";
		Function = function(plr, args, data)
			
			Remote.MakeGui(plr, "Notification", {
				Title = "Hello, "..plr.DisplayName;
				Message = "XP varible will be here";
				Time = 10;
			})


		end
		};

I have no idea how to access the remote variable or the server variable to make the adonis GUI

Turns out I have found a solution.

Remote.MakeGui(plr, "Notification", {
				Title = "Hello, "..plr.DisplayName;
				Message = "XP varible will be here";
				Time = 10;
			})

I just did

server.Remote.MakeGui(plr, "Notification", {
				Title = "Hello, "..plr.DisplayName;
				Message = "XP varible will be here";
				Time = 10;
			})

I should probably do a lot more digging before I post. But here is the solution if anyone is still figuring it out

1 Like

In an Adonis script environment, the server global variable is a large table containing server resources and core modules such as Remote (for handling of server-client communications), Commands (table containing Adonis commands), Admin (for handling permissions and ranks-related stuff) and several others.

Read more into depth here:

If you wanted to overide some of the commands could you just do it in the settings module or do you have to fork the main module?

You can do it from a server plugin module in the loader. For example:

--// ModuleScript named "Server-SomeRandomPlugin" placed under Adonis_Loader > Config > Plugins

server, service = nil, nil
return function()

    --// override the behavior of :kill
    server.Commands.Kill.Function = function(plr: Player, args: {string})
        print(plr.DisplayName, "tried to kill:", args[1])
    end

    --// another way to disable :kill
    server.Commands.Kill.Disabled = true

    --// override the description of :kill
    server.Commands.Kill.Description = "OOFs the target player(s)"

    --// Refer to the Structure of an Adonis Command section in my guide for more relevant info.

    --// You may have to check the MainModule to get a command's index (unique identifier) in server.Commands
    --// ex: server.Commands.Resize for the ":size" cmd where "Resize" is the index

end

Remember, you never have to fork the MainModule.

Wow, really nice in-depth tutorial. I’ve been using Adonis Admin for at least 2 years but this helped with stuff like Trello to understand it more.

quick question. what’s this?

Basically a website (adonis.dev) that lets you control your game and configure Adonis from it. Unfortunately its backend is closed-source and worked on by a solo developer so it rarely gets updated these days, leading to some aspects of the webpanel becoming fairly outdated and incomplete overall. Which is why I didn’t go into detail in my article about the webpanel feature.

If you do want to try it out, however, you can get information on how to set it up by visiting the Adonis/Epix Incorporated discord server.

Screenshots:

A revamped version is coming sometime but we don’t know when.

How do I join the discord? The link is expired.

Oops, we had to change the invite link due to a recent issue.

Just updated it with the new one that should work, try again.

1 Like