In simple terms, databases are basically files that hold values. What makes databases so special is that since values are stored on a file independent of Zandronum itself, they don't get "reset" like normal variables do in ACS after you close-out of Zandronum. So if you had a value stored on a database that says "x" = 5, then "x" will remain 5 even after the server shuts down.
IMPORTANT: For this feature to even work properly you need to create a database file for Zandronum to use, otherwise the values will be saved in a temporary file and deleted after Zandronum is closed. To create a database file, simply type in "databasefile namehere" on the server console. You will get a message afterwards if it was created successfully.
Zandronum's account system is a feature used to uniquely identify people. This is mainly used to link variables from the database to specific accounts. To use accounts, you need to provide an authentication server for users to login. Fortunately there are already authentication servers set up already so don't worry too much. Do keep in mind that if two Zandro servers are using different authentication servers (ie grandvoid and funcrusher), then user will have to create an account for both of them. Just remember, the only thing authentication servers do is log you in and tell the Zandronum server that you are who you are, it does not store database files~~~!!!
IMPORTANT: You must set an authentication server for this feature to even work. To set an authentication server just do authhostname "authhosturl:porthere". Don't use your own IP for this, I recommend using Zandronum's official authentication server as it has the most registered users. You also need to restart the server for this to take effect, if you cannot restart I recommend using a config. Adding an auth server to a config is simple; just add "authhostname auth.zandronum.com:16666" anywhere on your config if you wanna use Zandronum's official auth server.
If the user has created an account on the authentication server, then they can log-in by typing in "login username password" in the console, it will give you a message saying "login successful" if you did it right. Yes they must do this every time, I recommend either binding this to a key or use ZCC's automatic login feature instead of typing it out every time. Also keep in mind changing maps using the "map" command will force all users to be logged-off. I highly recommend that you disable map votes entirely and use changemap instead.
In my opinion, databasefiles and accounts are one of the best things to have ever come out of Zandronum. By being able to save values on a database and then link the values to an account allows us to create many features such as Hiscores, Shops, EXP systems, Statistics, etc - all with JUST acs.
Some notable examples are Funcrushers ranked duel ELO system, Idiotic LMS's hiscores, etc. There aren't really that many mods utilizing this amazing feature unfortunately. Hopefully this tutorial will change that.
Since this tutorial is aimed for beginners, the basic database ACS functions you need to know are stated here.
The account-related ACS functions you need to know are playerIsLoggedIn() and getPlayerAccountName().
You will also need to update your ACS compiler so it recognizes these commands, you can download the up-to-date compiler here.
I also recommend that you use database reading program such as sqlite browser to see what's in the databasefile for debugging. For example, here is what Idiotic LMS's database looks like.
For my first example, I'll create a simple script that permanently keeps track of how many times a user has died in non-cooperative gamemodes (So deathmatch). Note that this script will only run if you're using a valid authentication-server, a databasefile, and the user is logged-in. Also note that this script is NOT good but gets the job done. I will explain why below.
Here is the death-tracking script.
If you run this script and die a bunch of times, puking script 2 will show how many times you've died even if the server restarts. But there is a drawback. If you are new to the server and have never had a "deaths" counter made for you before, it has to be created for your account in the databasefile. This will cause the server to momentarily freeze until it has initialized the "deaths" variable for your account. In our case, the server will freeze momentarily on your first death to initialize the "deaths" variable for your account, but it won't freeze afterwards because it has been initialized. This means that for every new account's first death, the server will momentarily freeze.
This can be quite a problem in a live-game. Unfortunately there is no way to prevent the server from freezing, but we can control when the server freezes. What I usually do is keep track of deaths for each player using an array, and then add those deaths to the databasefile after the round is over so it doesn't interrupt the game. New code is marked as "[NEW]"
Here is a possible solution.
The benefits of this solution is that the server won't freeze during the game, and instead when the round ends. The drawback is that if the player disconnects mid-game his deaths won't be added to the counter. This is a trade-off that you will just have to deal with. But there is also one more improvement we can make.
Solution improved.
This improved solution only changes script 3, where we introduce two new functions called beginDBTransaction and endDBTransaction. These two functions causes script 3 to not run any database functions between beginDBTransaction and endDBTransaction, and instead merges the database functions into one big function and executes it when we hit endDBTransaction.
The main benefit of this is that it makes our script more efficient. To put it simply, beginDBTransaction and endDBTransaction allows us to merge multiple database functions into one call. This is good because then we're only writing to the database all at once instead of multiple times. Don't use this if you are only reading values from the database. Using this with getDBEntry is a big no no because that function doesn't actually write to the database.
That's all from me, here's an important message from AlexMax (the guy who actually coded this system) about the importance of incrementDBEntry.
Spoiler: AlexMax (Open)....And that's all for now. If you have questions, comment below.