<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://oldwiki.devbox.themanaworld.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Exceptionfault</id>
	<title>The Mana World - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://oldwiki.devbox.themanaworld.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Exceptionfault"/>
	<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/wiki/Special:Contributions/Exceptionfault"/>
	<updated>2026-05-06T06:03:36Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.8</generator>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=Setting_up_tmwAthena_on_Linux&amp;diff=13544</id>
		<title>Setting up tmwAthena on Linux</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=Setting_up_tmwAthena_on_Linux&amp;diff=13544"/>
		<updated>2009-10-17T10:13:52Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: /* Cloning and compiling */ added troubleshooting when trying to compile under ubuntu x64&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This article describes setting up eAthena on a Linux system. For how to set up eAthena on Windows refer to [[Building and running eAthena on Windows]].&lt;br /&gt;
&lt;br /&gt;
== Cloning and compiling ==&lt;br /&gt;
&lt;br /&gt;
Start with cloning eAthena from our [[Git Repository|Git repository]] and compiling it, then compile the eathena-monitor utility. If you are compiling for FreeBSD, use gmake instead of make. Also note that you will need bison and flex installed.&lt;br /&gt;
&lt;br /&gt;
 $ git clone git://gitorious.org/tmw-eathena/mainline.git eathena&lt;br /&gt;
 $ cd eathena&lt;br /&gt;
 $ make&lt;br /&gt;
 $ gcc -o eathena-monitor eathena-monitor.c&lt;br /&gt;
&lt;br /&gt;
There&#039;s probably lots of warnings while compiling the server executables, but you can just ignore that. If you are having problems cloning eAthena, there are other URLs in the [[Git Repository|Git repository]] article (the push URL will only work if you are a TMW developer). Once this step is successful, let&#039;s grab the eAthena data from Git as well. This is where we keep all the server side configuration, scripts and other data.&lt;br /&gt;
&lt;br /&gt;
We&#039;ll check it out to a &amp;lt;code&amp;gt;eathena-data&amp;lt;/code&amp;gt; directory, but note that using &amp;lt;code&amp;gt;$HOME/tmwserver&amp;lt;/code&amp;gt; requires less editing of configuration files later, since this is the default.&lt;br /&gt;
&lt;br /&gt;
 $ cd ..&lt;br /&gt;
 $ git clone git://gitorious.org/tmw-eathena-data/mainline.git eathena-data&lt;br /&gt;
 $ cd eathena-data&lt;br /&gt;
&lt;br /&gt;
If you are having problems cloning eathena-data, there are other URLs in the [[Git Repository|Git repository]] article.&lt;br /&gt;
&lt;br /&gt;
Copy over the server executables and monitor:&lt;br /&gt;
&lt;br /&gt;
 $ cp -iv ../eathena/*-server .&lt;br /&gt;
 $ cp -iv ../eathena/eathena-monitor .&lt;br /&gt;
&lt;br /&gt;
Optional step. If you did not check out the &amp;lt;code&amp;gt;server-data&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;$HOME/tmwserver&amp;lt;/code&amp;gt; you can add a symbolic link, so that it looks like you did check it out there:&lt;br /&gt;
&lt;br /&gt;
 $ cd $HOME&lt;br /&gt;
 $ ln -s &amp;lt;span style=&amp;quot;color:darkgreen;&amp;quot;&amp;gt;&#039;&#039;&#039;&#039;&#039;path/to/were/you/put/eathena-data/&#039;&#039;&#039;&#039;&#039;&amp;lt;/span&amp;gt; tmwserver&lt;br /&gt;
&lt;br /&gt;
=== Troubleshooting ===&lt;br /&gt;
&lt;br /&gt;
When having trouble compiling eathena under Ubuntu x86_64 and receiving an error like &amp;quot;Error: gnu/stubs-32.h: No such file or directory&amp;quot;, just install the following lib:&lt;br /&gt;
 sudo apt-get install libc6-dev-i386&lt;br /&gt;
&lt;br /&gt;
== Mandatory configuration ==&lt;br /&gt;
Now we need to edit some configuration specific to our setup.&lt;br /&gt;
&lt;br /&gt;
=== Logging ===&lt;br /&gt;
Create a directory where server log files will be stored, usually just do &amp;lt;code&amp;gt;mkdir log&amp;lt;/code&amp;gt; in the directory where your servers are located.&lt;br /&gt;
&lt;br /&gt;
=== General configuration ===&lt;br /&gt;
First go to the &amp;lt;code&amp;gt;eathena-data/conf&amp;lt;/code&amp;gt; directory and make a copy of each file ending in &amp;lt;code&amp;gt;.example&amp;lt;/code&amp;gt;, removing that extension. These files are generally server-specific and we don&#039;t want changes made in the Git repository to unexpectedly affect your local configuration.&lt;br /&gt;
&lt;br /&gt;
If you are just going to use the server yourself you can enter &amp;lt;code&amp;gt;127.0.0.1&amp;lt;/code&amp;gt; as the value for all IP addresses. Also, if you have no clue about what ports are or which you will be using, leave the default values as they are.&lt;br /&gt;
&lt;br /&gt;
The local configurations needed for the three servers are as follow:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;login_local.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
* Set a password for the &amp;lt;code&amp;gt;ladmin&amp;lt;/code&amp;gt; tool at &amp;lt;code&amp;gt;admin_pass&amp;lt;/code&amp;gt;, or disable remote administration at &amp;lt;code&amp;gt;admin_state&amp;lt;/code&amp;gt;.&lt;br /&gt;
** You should configure the file &amp;lt;code&amp;gt;ladmin_local.conf&amp;lt;/code&amp;gt; accordingly, if you choose to leave this tool enabled.&lt;br /&gt;
* Also don&#039;t forget to set a game master password at &amp;lt;code&amp;gt;gm_pass&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;char_local.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
* Set a username and password to be used for inter-server communication at &amp;lt;code&amp;gt;userid&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;passwd&amp;lt;/code&amp;gt;.&lt;br /&gt;
* You may optionally want to customize your server name at &amp;lt;code&amp;gt;server_name&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Specify the IP address and, if you changed it, the port of the login server as seen from the host on which you run the character server at &amp;lt;code&amp;gt;login_ip&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;login_port&amp;lt;/code&amp;gt; (if they are on the same machine, use 127.0.0.1).&lt;br /&gt;
* Specify the IP address of the character server as seen from the clients connecting to your server at &amp;lt;code&amp;gt;char_ip&amp;lt;/code&amp;gt;. This should usually be your internet IP address.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;map_local.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
* Set the same inter-server communication username and password as you did in &amp;lt;code&amp;gt;char_local.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Specify the IP address and, if you changed, the port of the character server as seen from the host on which you run the map server at &amp;lt;code&amp;gt;char_ip&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;char_port&amp;lt;/code&amp;gt; (if they are on the same machine, use 127.0.0.1).&lt;br /&gt;
* Specify the IP address of the map server as seen from the clients connecting to your server at &amp;lt;code&amp;gt;map_ip&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Lastly, go to &amp;lt;code&amp;gt;save/&amp;lt;/code&amp;gt; and copy the account.txt.example file (as account.txt). If you changed the inter-server passwords, you need to change the username &amp;lt;code style=&amp;quot;color:darkgreen;&amp;quot;&amp;gt;&#039;&#039;&#039;&#039;&#039;s1&#039;&#039;&#039;&#039;&#039;&amp;lt;/code&amp;gt; and the password &amp;lt;code style=&amp;quot;color:darkgreen;&amp;quot;&amp;gt;&#039;&#039;&#039;&#039;&#039;p1&#039;&#039;&#039;&#039;&#039;&amp;lt;/code&amp;gt; of account 0. Don&#039;t change anything else about it.&lt;br /&gt;
&lt;br /&gt;
Now make sure everything works by doing a test run of the eAthena server before you make any optional changes.&lt;br /&gt;
&lt;br /&gt;
=== Path to server data ===&lt;br /&gt;
Please note, if you have checked out out the &amp;lt;code&amp;gt;eathena-data&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;$HOME/tmwserver&amp;lt;/code&amp;gt; or have a symbolic link pointing here, you can skip these steps.&lt;br /&gt;
&lt;br /&gt;
* Edit eathena.sh and set &amp;lt;code&amp;gt;SRVHOMEDIR&amp;lt;/code&amp;gt; to the location of your server-data checkout. Probably something like &amp;lt;code&amp;gt;$HOME/.../eathena-data&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Edit &amp;lt;code&amp;gt;conf/eathena-monitor.conf&amp;lt;/code&amp;gt; and adjust the paths according to the &amp;lt;code&amp;gt;SRVHOMEDIR&amp;lt;/code&amp;gt; you previously set in &amp;lt;code&amp;gt;eathena.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Optional configuration ==&lt;br /&gt;
Here are some pointers if you want to configure your server in other ways than the official TMW server. Feel free to browse any of the other configuration files to see what else you may want to change.&lt;br /&gt;
&lt;br /&gt;
* The maps and NPCs that should be available are set in &amp;lt;code&amp;gt;map_athena.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
* The starting location and the starting equipment for the player are set in &amp;lt;code&amp;gt;char_athena.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Access levels to GM commands are set in &amp;lt;code&amp;gt;atcommand_local.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
* â€œThe message of todayâ€ text shown at login can be changed in &amp;lt;code&amp;gt;motd.txt&amp;lt;/code&amp;gt;.&lt;br /&gt;
* The command help texts can be changed in &amp;lt;code&amp;gt;help.txt&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Specifying your own update host ===&lt;br /&gt;
When you want to provide your players with a different world from the official server, you need to set up your own update host. You can specify a different update host in &amp;lt;code&amp;gt;conf/login_local.conf&amp;lt;/code&amp;gt; at &amp;lt;code&amp;gt;update_host&amp;lt;/code&amp;gt;. The client stores updates downloaded from the update host in an update-host specific directory, in order to avoid filename collisions.&lt;br /&gt;
&lt;br /&gt;
TODO: Provide more information about the files that an update host needs to server.&lt;br /&gt;
&lt;br /&gt;
== Running your server ==&lt;br /&gt;
We have two convenient scripts that allow us to start and stop the server with single commands. The &amp;lt;code&amp;gt;eathena-monitor&amp;lt;/code&amp;gt; launches all servers and restarts them when they crash. The &amp;lt;code&amp;gt;eathena.sh&amp;lt;/code&amp;gt; shell script is used to start/stop the &amp;lt;code&amp;gt;eathena-monitor&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 $ ./eathena.sh start&lt;br /&gt;
 $ ./eathena.sh restart&lt;br /&gt;
 $ ./eathena.sh stop&lt;br /&gt;
&lt;br /&gt;
Note that there are also GM commands that allow you to restart for example the map server. This is preferred over using &amp;lt;code&amp;gt;./eathena.sh restart&amp;lt;/code&amp;gt;. Also be sure to announce the restart to your players, since this doesn&#039;t happen automatically.&lt;br /&gt;
&lt;br /&gt;
Connect with your client and create your first account to test if everything works fine.&lt;br /&gt;
&lt;br /&gt;
If you manually run the servers, the char server will segfault the first time it&#039;s able to connect with the login server. This is fine. Just restart it. The monitor will handle this automatically.&lt;br /&gt;
&lt;br /&gt;
=== Troubleshooting ===&lt;br /&gt;
If your server fails to run and/or you cannot connect to it with your client, it is likely to be caused by one or several of the below points. But before you do anything else, check the [[#Logging|logfile]] as it may say what is the cause.&lt;br /&gt;
&lt;br /&gt;
* Forgotten or mismatching usernames, passwords, ip addresses and ports.&lt;br /&gt;
*# Check that you have followed all [[#Mandatory configuration|mandatory configuration steps]].&lt;br /&gt;
* Unavailable files.&lt;br /&gt;
*# Check where you did download the server-data. If you did not put in the default directory, please make sure that you have either [[#Checking out and compiling|created a symlink]] that points to the default directory or that you have [[#Path to server data|changed]] the needed configuration files.&lt;br /&gt;
*# Check whether you have [[#Checking out and compiling|created symlinks]] to the three server executables.&lt;br /&gt;
&lt;br /&gt;
=== Making yourself a GM ===&lt;br /&gt;
Specify your account ID as found in &amp;lt;code&amp;gt;save/account.txt&amp;lt;/code&amp;gt; (usually 2000000 for the first account) in &amp;lt;code&amp;gt;conf/gm_account.txt&amp;lt;/code&amp;gt;. The level 99 should be the highest. You can set up the GM commands in &amp;lt;code&amp;gt;conf/atcommand_athena.conf&amp;lt;/code&amp;gt;.&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=User:Exceptionfault/tmwencyclopedia&amp;diff=13276</id>
		<title>User:Exceptionfault/tmwencyclopedia</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=User:Exceptionfault/tmwencyclopedia&amp;diff=13276"/>
		<updated>2009-09-11T17:37:32Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: /* Todo */ finished ncps and map warps&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= TMW Encyclopedia =&lt;br /&gt;
&lt;br /&gt;
I&#039;ve started a small project based on tmwweb (aka [[Account Manager]]) called TMWEncyclopedia.&lt;br /&gt;
It&#039;s intention is to provide a mostly dynamically generated encyclopedia of all known&lt;br /&gt;
maps, monsters, items and npcs.&lt;br /&gt;
&lt;br /&gt;
You can have a look at an early preview under http://tmwweb-test.mericet.de&lt;br /&gt;
Just click on &amp;quot;items&amp;quot; in the navigation pane, search for a common icon like&lt;br /&gt;
&amp;quot;Bug Leg&amp;quot; and click on its name. Welcome to the Encyclopedia!&lt;br /&gt;
&lt;br /&gt;
TMWE consists of two components. The data gathering module and the data visualization&lt;br /&gt;
module. &lt;br /&gt;
&lt;br /&gt;
== Data gathering ==&lt;br /&gt;
&lt;br /&gt;
The data currently available in the encyclopedia comes from the following files:&lt;br /&gt;
&lt;br /&gt;
* tmwserv-data\items.xml&lt;br /&gt;
* tmwdata\monsters.xml&lt;br /&gt;
* tmwdata\maps\*.tmx&lt;br /&gt;
&lt;br /&gt;
To have a faster access to this data, the files get scanned by a ruby script&lt;br /&gt;
and stored in a relational sqlite database. This ruby script has to be executed &lt;br /&gt;
whenever the base data has changed, e.g. if new items were added.&lt;br /&gt;
&lt;br /&gt;
Find the code of the ruby script here http://gitorious.org/~Exceptionfault/tmwweb/excfs-sandbox/trees/master/utils/TMWEnzyklopedia via [[git]] &lt;br /&gt;
&lt;br /&gt;
== Data visualization ==&lt;br /&gt;
&lt;br /&gt;
The frontend of the encyclopedia will be tightly integrated in the [[Account Manager]].&lt;br /&gt;
Its an optional extension which could be enabled in the configuration files.&lt;br /&gt;
&lt;br /&gt;
== Todo ==&lt;br /&gt;
&lt;br /&gt;
* Show warps between maps&lt;br /&gt;
** &amp;lt;s&amp;gt;Data gathering and storage&amp;lt;/s&amp;gt;&lt;br /&gt;
** &amp;lt;s&amp;gt;Frontend / Visualization&amp;lt;/s&amp;gt;&lt;br /&gt;
* Show NPCs on maps &lt;br /&gt;
** &amp;lt;s&amp;gt;Data gathering and storage&amp;lt;/s&amp;gt;&lt;br /&gt;
** &amp;lt;s&amp;gt;Frontend / Visualization&amp;lt;/s&amp;gt;&lt;br /&gt;
* Show more informations on items&lt;br /&gt;
** Data gathering and storage&lt;br /&gt;
** Frontend / Visualization&lt;br /&gt;
* Show more informations on monsters&lt;br /&gt;
** Data gathering and storage&lt;br /&gt;
** Frontend / Visualization&lt;br /&gt;
* Create mechanism to be able to extend the dynamic content with manual written informations&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=User:Exceptionfault&amp;diff=13267</id>
		<title>User:Exceptionfault</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=User:Exceptionfault&amp;diff=13267"/>
		<updated>2009-09-10T11:05:55Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: /* Contributions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About me==&lt;br /&gt;
&lt;br /&gt;
This text is stolen from my personal blog and translated by myself for you all, so enjoy...&lt;br /&gt;
&lt;br /&gt;
I&#039;m born in 1981 in Heidelberg, Germany. Since 2003 I work as a software- and database developer with focus on Oracle databases and Microsoft .NET technologies at the headquarter of one of the biggest german food discounter. Advantaged by my well-founded education as DBA, I form the &#039;&#039;interface&#039;&#039; between our DBA&#039;s and our developers; sometimes with more or less understanding of their individual problems with each other ;-) .&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Proposals ==&lt;br /&gt;
&lt;br /&gt;
All of these proposals apply to the development branch 0.1.* as I think this should take up the most effort in implementing new features.&lt;br /&gt;
&lt;br /&gt;
* [[Individual item attributes]]&lt;br /&gt;
* &#039;&#039;advanced database layout with better relational approach&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Contributions ==&lt;br /&gt;
&lt;br /&gt;
I&#039;ve contributed to the following projects, articles or efforts in The Mana World:&lt;br /&gt;
&lt;br /&gt;
* [[Account_Manager|Account Manager]] aka tmwweb&lt;br /&gt;
* [[User:Exceptionfault/tmwencyclopedia|TMW Encyclopedia]]&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=User:Exceptionfault/tmwenclopedia&amp;diff=13266</id>
		<title>User:Exceptionfault/tmwenclopedia</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=User:Exceptionfault/tmwenclopedia&amp;diff=13266"/>
		<updated>2009-09-10T11:05:29Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: User:Exceptionfault/tmwenclopedia moved to User:Exceptionfault/tmwencyclopedia: misspelled&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[User:Exceptionfault/tmwencyclopedia]]&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=User:Exceptionfault/tmwencyclopedia&amp;diff=13265</id>
		<title>User:Exceptionfault/tmwencyclopedia</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=User:Exceptionfault/tmwencyclopedia&amp;diff=13265"/>
		<updated>2009-09-10T11:05:29Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: User:Exceptionfault/tmwenclopedia moved to User:Exceptionfault/tmwencyclopedia: misspelled&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= TMW Encyclopedia =&lt;br /&gt;
&lt;br /&gt;
I&#039;ve started a small project based on tmwweb (aka [[Account Manager]]) called TMWEncyclopedia.&lt;br /&gt;
It&#039;s intention is to provide a mostly dynamically generated encyclopedia of all known&lt;br /&gt;
maps, monsters, items and npcs.&lt;br /&gt;
&lt;br /&gt;
You can have a look at an early preview under http://tmwweb-test.mericet.de&lt;br /&gt;
Just click on &amp;quot;items&amp;quot; in the navigation pane, search for a common icon like&lt;br /&gt;
&amp;quot;Bug Leg&amp;quot; and click on its name. Welcome to the Encyclopedia!&lt;br /&gt;
&lt;br /&gt;
TMWE consists of two components. The data gathering module and the data visualization&lt;br /&gt;
module. &lt;br /&gt;
&lt;br /&gt;
== Data gathering ==&lt;br /&gt;
&lt;br /&gt;
The data currently available in the encyclopedia comes from the following files:&lt;br /&gt;
&lt;br /&gt;
* tmwserv-data\items.xml&lt;br /&gt;
* tmwdata\monsters.xml&lt;br /&gt;
* tmwdata\maps\*.tmx&lt;br /&gt;
&lt;br /&gt;
To have a faster access to this data, the files get scanned by a ruby script&lt;br /&gt;
and stored in a relational sqlite database. This ruby script has to be executed &lt;br /&gt;
whenever the base data has changed, e.g. if new items were added.&lt;br /&gt;
&lt;br /&gt;
Find the code of the ruby script here http://gitorious.org/~Exceptionfault/tmwweb/excfs-sandbox/trees/master/utils/TMWEnzyklopedia via [[git]] &lt;br /&gt;
&lt;br /&gt;
== Data visualization ==&lt;br /&gt;
&lt;br /&gt;
The frontend of the encyclopedia will be tightly integrated in the [[Account Manager]].&lt;br /&gt;
Its an optional extension which could be enabled in the configuration files.&lt;br /&gt;
&lt;br /&gt;
== Todo ==&lt;br /&gt;
&lt;br /&gt;
* Show warps between maps&lt;br /&gt;
** &amp;lt;s&amp;gt;Data gathering and storage&amp;lt;/s&amp;gt;&lt;br /&gt;
** Frontend / Visualization&lt;br /&gt;
* Show NPCs on maps &lt;br /&gt;
** &amp;lt;s&amp;gt;Data gathering and storage&amp;lt;/s&amp;gt;&lt;br /&gt;
** Frontend / Visualization&lt;br /&gt;
* Show more informations on items&lt;br /&gt;
** Data gathering and storage&lt;br /&gt;
** Frontend / Visualization&lt;br /&gt;
* Show more informations on monsters&lt;br /&gt;
** Data gathering and storage&lt;br /&gt;
** Frontend / Visualization&lt;br /&gt;
* Create mechanism to be able to extend the dynamic content with manual written informations&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=User:Exceptionfault&amp;diff=13264</id>
		<title>User:Exceptionfault</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=User:Exceptionfault&amp;diff=13264"/>
		<updated>2009-09-10T08:07:43Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: /* Contributions */ added link to tmwencyclopedia&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About me==&lt;br /&gt;
&lt;br /&gt;
This text is stolen from my personal blog and translated by myself for you all, so enjoy...&lt;br /&gt;
&lt;br /&gt;
I&#039;m born in 1981 in Heidelberg, Germany. Since 2003 I work as a software- and database developer with focus on Oracle databases and Microsoft .NET technologies at the headquarter of one of the biggest german food discounter. Advantaged by my well-founded education as DBA, I form the &#039;&#039;interface&#039;&#039; between our DBA&#039;s and our developers; sometimes with more or less understanding of their individual problems with each other ;-) .&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Proposals ==&lt;br /&gt;
&lt;br /&gt;
All of these proposals apply to the development branch 0.1.* as I think this should take up the most effort in implementing new features.&lt;br /&gt;
&lt;br /&gt;
* [[Individual item attributes]]&lt;br /&gt;
* &#039;&#039;advanced database layout with better relational approach&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Contributions ==&lt;br /&gt;
&lt;br /&gt;
I&#039;ve contributed to the following projects, articles or efforts in The Mana World:&lt;br /&gt;
&lt;br /&gt;
* [[Account_Manager|Account Manager]] aka tmwweb&lt;br /&gt;
* [[User:Exceptionfault/tmwenclopedia|TMW Encyclopedia]]&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=User:Exceptionfault/tmwencyclopedia&amp;diff=13263</id>
		<title>User:Exceptionfault/tmwencyclopedia</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=User:Exceptionfault/tmwencyclopedia&amp;diff=13263"/>
		<updated>2009-09-10T08:06:38Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: some words and ideas to TMWEncyclopedia&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= TMW Encyclopedia =&lt;br /&gt;
&lt;br /&gt;
I&#039;ve started a small project based on tmwweb (aka [[Account Manager]]) called TMWEncyclopedia.&lt;br /&gt;
It&#039;s intention is to provide a mostly dynamically generated encyclopedia of all known&lt;br /&gt;
maps, monsters, items and npcs.&lt;br /&gt;
&lt;br /&gt;
You can have a look at an early preview under http://tmwweb-test.mericet.de&lt;br /&gt;
Just click on &amp;quot;items&amp;quot; in the navigation pane, search for a common icon like&lt;br /&gt;
&amp;quot;Bug Leg&amp;quot; and click on its name. Welcome to the Encyclopedia!&lt;br /&gt;
&lt;br /&gt;
TMWE consists of two components. The data gathering module and the data visualization&lt;br /&gt;
module. &lt;br /&gt;
&lt;br /&gt;
== Data gathering ==&lt;br /&gt;
&lt;br /&gt;
The data currently available in the encyclopedia comes from the following files:&lt;br /&gt;
&lt;br /&gt;
* tmwserv-data\items.xml&lt;br /&gt;
* tmwdata\monsters.xml&lt;br /&gt;
* tmwdata\maps\*.tmx&lt;br /&gt;
&lt;br /&gt;
To have a faster access to this data, the files get scanned by a ruby script&lt;br /&gt;
and stored in a relational sqlite database. This ruby script has to be executed &lt;br /&gt;
whenever the base data has changed, e.g. if new items were added.&lt;br /&gt;
&lt;br /&gt;
Find the code of the ruby script here http://gitorious.org/~Exceptionfault/tmwweb/excfs-sandbox/trees/master/utils/TMWEnzyklopedia via [[git]] &lt;br /&gt;
&lt;br /&gt;
== Data visualization ==&lt;br /&gt;
&lt;br /&gt;
The frontend of the encyclopedia will be tightly integrated in the [[Account Manager]].&lt;br /&gt;
Its an optional extension which could be enabled in the configuration files.&lt;br /&gt;
&lt;br /&gt;
== Todo ==&lt;br /&gt;
&lt;br /&gt;
* Show warps between maps&lt;br /&gt;
** &amp;lt;s&amp;gt;Data gathering and storage&amp;lt;/s&amp;gt;&lt;br /&gt;
** Frontend / Visualization&lt;br /&gt;
* Show NPCs on maps &lt;br /&gt;
** &amp;lt;s&amp;gt;Data gathering and storage&amp;lt;/s&amp;gt;&lt;br /&gt;
** Frontend / Visualization&lt;br /&gt;
* Show more informations on items&lt;br /&gt;
** Data gathering and storage&lt;br /&gt;
** Frontend / Visualization&lt;br /&gt;
* Show more informations on monsters&lt;br /&gt;
** Data gathering and storage&lt;br /&gt;
** Frontend / Visualization&lt;br /&gt;
* Create mechanism to be able to extend the dynamic content with manual written informations&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Database_specifications&amp;diff=13146</id>
		<title>Archive:Database specifications</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Database_specifications&amp;diff=13146"/>
		<updated>2009-08-23T11:30:29Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: Added table tmw_transactions and tmw_transaction_code&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Category_programming}}&lt;br /&gt;
&lt;br /&gt;
Current version of database structure in [[git]]: 5&lt;br /&gt;
&lt;br /&gt;
== SQL table specifications ==&lt;br /&gt;
&lt;br /&gt;
[[Image:Database specification proposal.png|thumb|200px|The current database model.]]&lt;br /&gt;
&lt;br /&gt;
=== User accounts ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_accounts}}&lt;br /&gt;
{{sqltablerow| id            | INTEGER     | PRIMARY KEY      | | unique id of an account}}                       }}&lt;br /&gt;
{{sqltablerow|username       | TEXT        | NOT NULL UNIQUE  | | username / loginname of an user                 }}&lt;br /&gt;
{{sqltablerow|password       | TEXT        | NOT NULL         | | password of an user (sha256 encoded)            }}&lt;br /&gt;
{{sqltablerow|email          | TEXT        | NOT NULL         | | email (sha256 encoded, only for pwd recovery)   }}&lt;br /&gt;
{{sqltablerow|level          | INTEGER     | NOT NULL         | | numeric level of the user account               }}&lt;br /&gt;
{{sqltablerow|banned         | INTEGER     | NOT NULL         | | unixtimestamp until when the account is banned  }}&lt;br /&gt;
{{sqltablerow|registration   | INTEGER     | NOT NULL         | | unixtimestamp of account registration           }}&lt;br /&gt;
{{sqltablerow|lastlogin      | INTEGER     | NOT NULL         | | unixtimestamp of last login with client         }}&lt;br /&gt;
{{sqltablerow|authorization  | TEXT        |                  | | secret key used for password recovery           }}&lt;br /&gt;
{{sqltablerow|expiration     | INTEGER     |                  | | unixtimestamp defining expiration of secret key }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Details ====&lt;br /&gt;
* email&lt;br /&gt;
** The email is stored as a one-way sha256 hash value. This ensures, that the email address a user enters cannot be used to send spam mails. It is only used to validate the mailaddress during password recovery procedure.&lt;br /&gt;
* level&lt;br /&gt;
** describes the user rights in the game (10 = normal user, 50 = gm, 99 = administrator)&lt;br /&gt;
* authorization and expiration &lt;br /&gt;
** these fields are used by TMWWEB to store a secret key and the time of expiration if the user has requested to reset its password. The secret key is sent via mail to the user.&lt;br /&gt;
&lt;br /&gt;
=== Characters ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_characters}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY      |                 | unique id of the character                              }}&lt;br /&gt;
{{sqltablerow|user_id        | INTEGER     | NOT NULL         | tmw_accounts.id | id of the owner                                         }}&lt;br /&gt;
{{sqltablerow|name           | TEXT        | NOT NULL UNIQUE  |                 | name of the character                                   }}&lt;br /&gt;
{{sqltablerow|gender         | INTEGER     | NOT NULL         |                 | gender of the character (0/1)                           }}&lt;br /&gt;
{{sqltablerow|hair_style     | INTEGER     | NOT NULL         |                 | id of the hair sprite                                   }}&lt;br /&gt;
{{sqltablerow|hair_color     | INTEGER     | NOT NULL         |                 | id of the hair color                                    }}&lt;br /&gt;
{{sqltablerow|level          | INTEGER     | NOT NULL         |                 | experience level of the character                       }}&lt;br /&gt;
{{sqltablerow|char_pts       | INTEGER     | NOT NULL         |                 | available points to raise attributes                    }}&lt;br /&gt;
{{sqltablerow|correct_pts    | INTEGER     | NOT NULL         |                 | available points to lower attributes and regain char_pts}}&lt;br /&gt;
{{sqltablerow|money          | INTEGER     | NOT NULL         |                 | GP of the character                                     }}&lt;br /&gt;
{{sqltablerow|x              | INTEGER     | NOT NULL         |                 | x position of the character on the map                  }}&lt;br /&gt;
{{sqltablerow|y              | INTEGER     | NOT NULL         |                 | y position of the character on the map                  }}&lt;br /&gt;
{{sqltablerow|map_id         | INTEGER     | NOT NULL         | tmw_maps.id     | id of the current map the character is located          }}&lt;br /&gt;
{{sqltablerow|str            | INTEGER     | NOT NULL         |                 | strength of the character                               }}&lt;br /&gt;
{{sqltablerow|agi            | INTEGER     | NOT NULL         |                 | agility of the character                                }}&lt;br /&gt;
{{sqltablerow|dex            | INTEGER     | NOT NULL         |                 | dexternity of the character                             }}&lt;br /&gt;
{{sqltablerow|vit            | INTEGER     | NOT NULL         |                 | vitality of the character                               }}&lt;br /&gt;
{{sqltablerow|int            | INTEGER     | NOT NULL         |                 | intelligence of the character                           }}&lt;br /&gt;
{{sqltablerow|will           | INTEGER     | NOT NULL         |                 | willpower of the character                              }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Concerns ====&lt;br /&gt;
&lt;br /&gt;
* The way experience is part of this table really won&#039;t scale and isn&#039;t flexible in any way. It&#039;s currently already way too many variables in one table row, and these are just the weapon skills. So I think we should really have a separate table for storing skill levels similar to the character inventory table below. So something that has { character_id, skill_id, experience }. The &amp;lt;code&amp;gt;skill_id&amp;lt;/code&amp;gt; should point to a &amp;lt;code&amp;gt;skills.xml&amp;lt;/code&amp;gt; file which describes (and categorizes) each skill. In that way we&#039;ll be able to easily change the set of skills and their names later. --[[User:BjÃ¸rn|BjÃ¸rn]] 18:09, 12 September 2008 (CEST)&lt;br /&gt;
** I think the same should be done with the attributes (str .. will). In theory almost every attribute in this table could be handled that way, it might look like a mess, but would be really friendly in customizing the gameplay elements. --[[User:Kess|kess]] 19:54, 12 September 2008 (CEST)&lt;br /&gt;
** I agree with that completely as this will give us more flexibility and a much more relational database design. I&#039;ve extended the &amp;quot;DAL improvements&amp;quot; task in mantis: #424 --[[User:Exceptionfault|Exceptionfault]] 15:50, 14 September 2008 (CEST)&lt;br /&gt;
*** Thanks for taking out the skills from this table. However, I disagree about generalizing stuff on the level of attributes, unless there would be any plan of putting infrastructure in place to make this possible. For now we can&#039;t even finish a server for The Mana World within years, so please don&#039;t try to build a server that supports any online RPG just yet. I only suggested we take out the skills because it would be completely unmanageable as part of this table, but the list of attribute is not expected to change for now. --[[User:BjÃ¸rn|BjÃ¸rn]] 15:55, 22 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
=== Character attributes ===&lt;br /&gt;
&lt;br /&gt;
This table is intended to store skills and experiences of each character. &lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_char_skills}}&lt;br /&gt;
{{sqltablerow|char_id         | INTEGER     | NOT NULL | tmw_characters.id | reference to the character                    }}&lt;br /&gt;
{{sqltablerow|skill_id        | INTEGER     | NOT NULL | (skills.xml)      | reference to the skill                        }}&lt;br /&gt;
{{sqltablerow|exp             | INTEGER     | NOT NULL |                   | current experience of the char in this skill  }} &lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Concerns ====&lt;br /&gt;
&lt;br /&gt;
* I&#039;m not sure, if an INTEGER does the job for column exp? --[[User:Exceptionfault|Exceptionfault]] 14:40, 19 September 2008 (CEST)&lt;br /&gt;
** What is the range? I would expect it to be enough. --[[User:BjÃ¸rn|BjÃ¸rn]] 15:56, 22 September 2008 (CEST)&lt;br /&gt;
*** Hereâ€™s some basic info:&lt;br /&gt;
***: &#039;&#039;&#039;MySQL:&#039;&#039;&#039; INTEGER (INT) may be signed or unsigned and is 4 bytes large, MySQL also have 1, 2, 3 and 8 byte integer variants (TINYINT, SMALLINT, MEDIUMINT and BIGINT) [http://dev.mysql.com/doc/refman/6.0/en/numeric-types.html]&lt;br /&gt;
***: &#039;&#039;&#039;PostgreSQL:&#039;&#039;&#039; INTEGER (INT, INT4) is signed and 4 bytes large, PostgreSQL also have 2 and 8 byte integer variants (SMALLINT and BIGINT) [http://www.postgresql.org/docs/8.3/interactive/datatype-numeric.html]&lt;br /&gt;
***: &#039;&#039;&#039;SQLite:&#039;&#039;&#039; INTEGER is signed and size is either 1, 2, 3, 4, 6 or 8 bytes depending on the size of the value [http://sqlite.org/datatype3.html]&lt;br /&gt;
***: So, the largest integer type supported should be of 8 byte size (signed): from -9,223,372,036,854,775,808 to +9,223,372,036,854,775,807, while the â€œstandardâ€ (of the SQL variants above) signed 4 byte integer ranges from -2,147,483,648 to +2,147,483,647. --[[User:Kess|kess]] 21:18, 22 September 2008 (CEST)&lt;br /&gt;
*** Although we plan to have no fixed level cap I considered a skill level of about 100 to be the highest reasonable value a player can archieve. Level 100 requires an exp sum of 10 million with the current exp formula (levelÂ³ * 10) which fits into a 4 byte integer easily. We won&#039;t get in trouble with 32bit signed integers until the players get near skill level 600 (2.16 billion). The server and the netcode also use 32 bit integers internally.&lt;br /&gt;
&lt;br /&gt;
=== Character Inventory ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_inventories}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY      |                   | unique id of the item                          }}&lt;br /&gt;
{{sqltablerow|owner_id       | INTEGER     | NOT NULL         | tmw_characters.id | id of the owning character                     }}&lt;br /&gt;
{{sqltablerow|slot           | INTEGER     | NOT NULL         |                   | inventory slot where the item is equipped      }}&lt;br /&gt;
{{sqltablerow|class_id       | INTEGER     | NOT NULL         |                   | type of the item, see items.xml file of tmwserv}}&lt;br /&gt;
{{sqltablerow|amount         | INTEGER     | NOT NULL         |                   | amount of items per slot                       }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Comments ====&lt;br /&gt;
* While I havenâ€™t looked how this table is used (my C++ knowledge is rather basic) it seems quite rigid and unflexible (as BjÃ¸rn noted above for the &#039;&#039;&#039;tmw_characters&#039;&#039;&#039; table). I think it would be nicer to have something like {&#039;&#039;owner_id&#039;&#039; FK, &#039;&#039;slot&#039;&#039;, &#039;&#039;item_id&#039;&#039; FK, &#039;&#039;amount&#039;&#039;, PK owner_id + slot}, where class_id shouldnâ€™t directly be needed in this table. --[[User:Kess|kess]] 19:49, 12 September 2008 (CEST)&lt;br /&gt;
* Concerning new features like houses, bank accounts, chests or similar, i think the design of this table needs some more roundtrips. You will need a column which indicates if the item is carried by the character or stored in a chest or in a house; as it makes no sense to have a table for every possible storage type or location. Another point is, that items should be more individualizable (is this a real word? :)). Think about custom colored shirts. So we will need at least one additional table to store individual attributes of items. --[[User:Exceptionfault|Exceptionfault]] 16:02, 14 September 2008 (CEST)&lt;br /&gt;
** We want all equipment to be completely individual with completely unique stats. --[[User:Crush2|Crush2]] 16:13, 14 September 2008 (CEST)&lt;br /&gt;
*** Good to know, so I will extend the DAL improvement task in mantis. --[[User:Exceptionfault|Exceptionfault]] 16:20, 14 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
=== Guilds ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_guilds}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY     |  | unique id of the guid   }}&lt;br /&gt;
{{sqltablerow|name           | TEXT        | NOT NULL UNIQUE |  | unique name of the guild}}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Guild memberships ====&lt;br /&gt;
&lt;br /&gt;
The table &#039;&#039;tmw_guild_members&#039;&#039; stores informations which character is member in which guild and which rights does he has.&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_guild_members}}&lt;br /&gt;
{{sqltablerow|guild_id        | INTEGER     | NOT NULL | tmw_guilds.id     | reference to the guild                                                }}&lt;br /&gt;
{{sqltablerow|member_id       | INTEGER     | NOT NULL | tmw_characters.id | reference to the characters                                           }}&lt;br /&gt;
{{sqltablerow|rights          | INTEGER     | NOT NULL |                   | id showing the rights a character has in this guild (member, admin...)}}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== World state ===&lt;br /&gt;
&lt;br /&gt;
The table &#039;&#039;tmw_world_state&#039;&#039; is used to store persistent informations about the world or individual maps.&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_world_state}}&lt;br /&gt;
{{sqltablerow| state_name      | TEXT     | PRIMARY KEY |             | unique name of a state variable        }} &lt;br /&gt;
{{sqltablerow| map_id          | INTEGER  | NULL        | tmw_maps.id | reference to a map, see details        }}&lt;br /&gt;
{{sqltablerow| value           | TEXT     | NULL        |             | string value of the state              }}&lt;br /&gt;
{{sqltablerow| moddate         | INTEGER  | NOT NULL    |             | date and time of the last modification }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Details ====&lt;br /&gt;
&lt;br /&gt;
* The column &#039;&#039;state_name&#039;&#039; forms the primary key of the table. If &#039;&#039;map_id&#039;&#039; is null, the variable is used globally in the world, otherwise the variable is specific for a map.&lt;br /&gt;
* &#039;&#039;moddate&#039;&#039; is for informational use only as it contains the unixtimestamp of the last modification.&lt;br /&gt;
&lt;br /&gt;
==== Comments ====&lt;br /&gt;
&lt;br /&gt;
* It seems that SQLite doesn&#039;t support composite primary keys (span PK over multiple columns). Therefore it is not possible to allow multiple &#039;&#039;state_name&#039;&#039;s with different &#039;&#039;map_id&#039;&#039;s. So we set a &#039;&#039;state_name&#039;&#039; to unique and use &#039;&#039;map_id&#039;&#039; as notifier if this variable is globally used or just locally for a specific map. --[[User:Exceptionfault|Exceptionfault]] 11:05, 15 September 2008 (CEST)&lt;br /&gt;
** This table is ready for usage, commited as rev. 4629 --[[User:Exceptionfault|Exceptionfault]] 13:51, 15 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Quest states ===&lt;br /&gt;
&lt;br /&gt;
This table is used to store states of quests per character, e.g. if a character has just finished a quest or is currently at the second part of the long journey...&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_quests}}&lt;br /&gt;
{{sqltablerow|owner_id        | INTEGER     | NOT NULL | tmw_characters.id | reference to the character         }}&lt;br /&gt;
{{sqltablerow|name            | TEXT        | NOT NULL |                   | name of the quest variable         }}&lt;br /&gt;
{{sqltablerow|value           | TEXT        | NOT NULL |                   | current value of the quest variable}} &lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Comments ====&lt;br /&gt;
&lt;br /&gt;
* Unless this table is adapted so that it stores the state of a particular quest, this one should have a name which makes it move obvious that it&#039;s storing custom values for &#039;&#039;characters&#039;&#039;. I consider that different from quests variables, which I would expect to be scoped to a certain quest (global quest variables) or quest instance (local quest variables). --[[User:BjÃ¸rn|BjÃ¸rn]] 18:16, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* We might want to have a similar table to this to store custom values for item instances, and also one for custom world-state variables. --[[User:BjÃ¸rn|BjÃ¸rn]] 18:16, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* I always wondered why Silene used the terminology &amp;quot;Quest&amp;quot; for what is basically a system to store/querry persistent character-bound integer variables which can be used for countless purposes, not just quests. I think we should rename this whole system to &amp;quot;character variable&amp;quot; in the database, server source and script bindings. --[[User:Crush2|Crush2]] 23:28, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* I agree with BjÃ¸rn concerning the additional tables for custom item values and custom world-state values. Although the name &amp;quot;tmw_quests&amp;quot; is a little bit confusing and should be renamed, I suggest keeping a table as such to store only quest states of characters and not to mix up with other persistent states. Instead we should provide a much cleaner documentation about the available quests and their persistent states that are possible. I envision something like a questbook in game, where each player can have a look at his finished quests and currently open quests, maybe with hints on the minimap, a todo list .... Besides that, we should be aware of dividing quests into &amp;quot;per-character&amp;quot;, &amp;quot;per-party&amp;quot; or global world quests.  --[[User:Exceptionfault|Exceptionfault]] 16:20, 14 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* I am not sure I understand everything which have been said above, so I will just sketch how I would do it. The table would have one &#039;&#039;owner_id&#039;&#039; (mandatory unique integer: a character; possibly either a character, an account, a guild etc.) and a number of &#039;&#039;variable&#039;&#039;s (mandatory non-uniqe datatype: holding a number of quest states). The variables would simply be named &#039;&#039;variable1&#039;&#039; and so on, and added as necessary.&lt;br /&gt;
** In the Lua quest scripts the bit masks would be hidden and the quest states themselves would be assigned and checked through general functions.&lt;br /&gt;
** An XML file &amp;lt;code&amp;gt;quests.xml&amp;lt;/code&amp;gt; or otherfashionly named would hold the general information regarding the quests and their states so that there could be content updates (of a stripped down version of the server file). By requesting the quest states from the server the clients would show the info with a nice GUI.&lt;br /&gt;
: What I do not understand above is the need to split the quest variable into name and value... But Iâ€™m merely a beginner in database designs and you surely have a clever reason why far beyond my own grasp of the matter.&lt;br /&gt;
: âœŽâ€ˆ[[User:Kess|Kess]]&amp;lt;sup&amp;gt;[[User talk:Kess|â˜½]]&amp;lt;/sup&amp;gt; 15:25, 23 May 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
=== Auctions ===&lt;br /&gt;
&lt;br /&gt;
Inspired by the ManaBay auction system developed by Qoal, it is planned to build a trading platform for the whole community of players using item auctions.&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_auctions}}&lt;br /&gt;
{{sqltablerow| auction_id    | INTEGER     | PRIMARY KEY      |                     | unique id of an auction                    }}&lt;br /&gt;
{{sqltablerow| auction_state | INTEGER     | NOT NULL         |                     | current state of the auction               }}&lt;br /&gt;
{{sqltablerow| char_id       | INTEGER     | NOT NULL         | tmw_characters (id) | owner of the auction                       }}&lt;br /&gt;
{{sqltablerow| itemclass_id  | INTEGER     | NOT NULL         | items.xml           | id of the item                             }}&lt;br /&gt;
{{sqltablerow| amount        | INTEGER     | NOT NULL         |                     | amount of items to trade                   }}&lt;br /&gt;
{{sqltablerow| start_time    | INTEGER     | NOT NULL         |                     | date of creation or start of auction       }}&lt;br /&gt;
{{sqltablerow| end_time      | INTEGER     | NOT NULL         |                     | end of auction (unixtimestamp)             }}&lt;br /&gt;
{{sqltablerow| start_price   | INTEGER     | NOT NULL         |                     | minimum price for the first bid            }}&lt;br /&gt;
{{sqltablerow| min_price     | INTEGER     | NULL             |                     | minimum price for the final bid to succeed }}&lt;br /&gt;
{{sqltablerow| buyout_price  | INTEGER     | NULL             |                     | price for direct buy of bidded item        }}&lt;br /&gt;
{{sqltablerow| description   | TEXT        | NULL             |                     | optional description of an auction         }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Annotations ====&lt;br /&gt;
&lt;br /&gt;
* auction_state can have the following values:&lt;br /&gt;
** 0 = The auction is published and ready for bidders&lt;br /&gt;
** 1 = The auction has finished and closed&lt;br /&gt;
* start_time contains the creation date of the auction. Format: Unixtimestamp&lt;br /&gt;
&lt;br /&gt;
==== Bids on Auctions ====&lt;br /&gt;
&lt;br /&gt;
This table stores bids made by characters to a specific auction.&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_auctions}}&lt;br /&gt;
{{sqltablerow| bid_id        | INTEGER     | PRIMARY KEY      |                     | unique id of a bid                         }}&lt;br /&gt;
{{sqltablerow| auction_id    | INTEGER     | NOT NULL         | tmw_auctions        | unique id of an auction                    }}&lt;br /&gt;
{{sqltablerow| char_id       | INTEGER     | NOT NULL         | tmw_characters      | owner of the bid                           }}&lt;br /&gt;
{{sqltablerow| bid_time      | INTEGER     | NOT NULL         |                     | time of the bid, used for sorting bids     }}&lt;br /&gt;
{{sqltablerow| bid_price     | INTEGER     | NOT NULL         |                     | price bidded by the character              }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
===== Annotations =====&lt;br /&gt;
&lt;br /&gt;
* bid_time holds the date and time of the bid as Unixtimestamp. Regarding 2 bids can be placed at the same second, the higher bid_price is relevant. If the bid_price is also equal, the smallest bid_id counts, as this is the record first inserted into the database.&lt;br /&gt;
&lt;br /&gt;
=== Postal system ===&lt;br /&gt;
&lt;br /&gt;
==== Letters ====&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_post}}&lt;br /&gt;
{{sqltablerow| letter_id        | INTEGER | PRIMARY KEY |                | unique id of the letter }} &lt;br /&gt;
{{sqltablerow| sender_id        | INTEGER | NOT NULL    | tmw_characters | sending character of the letter }}&lt;br /&gt;
{{sqltablerow| receiver_id      | INTEGER | NOT NULL    | tmw_characters | receiving character of the letter }}&lt;br /&gt;
{{sqltablerow| letter_type      | INTEGER | NOT NULL    |                | type of the letter (unused atm) }}&lt;br /&gt;
{{sqltablerow| expiration_date  | INTEGER | NOT NULL    |                | date and time of expiration }}&lt;br /&gt;
{{sqltablerow| sending_date     | INTEGER | NOT NULL    |                | date and time of sending }}&lt;br /&gt;
{{sqltablerow| letter_text      | TEXT    |     NULL    |                | text }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Item attachments ====&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_post_attachments}}&lt;br /&gt;
{{sqltablerow| attachment_id | INTEGER | PRIMARY KEY |                    | unique id of the attachment }} &lt;br /&gt;
{{sqltablerow| letter_id     | INTEGER | NOT NULL    | tmw_post           | reference to the letter }}&lt;br /&gt;
{{sqltablerow| item_id       | INTEGER | NOT NULL    | tmw_item_instances | attached itema }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Miscellaneous ===&lt;br /&gt;
&lt;br /&gt;
==== Transactions ====&lt;br /&gt;
&lt;br /&gt;
Each transaction like creating a new character or picking up an item is logged in the table twm_transactions.&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_transactions}}&lt;br /&gt;
{{sqltablerow| id            | INTEGER | PRIMARY KEY |                       | unique id of the transaction }} &lt;br /&gt;
{{sqltablerow| char_id       | INTEGER | NOT NULL    | tmw_characters        | reference to the character   }}&lt;br /&gt;
{{sqltablerow| action        | INTEGER | NOT NULL    | tmw_transaction_codes | reference to the action      }}&lt;br /&gt;
{{sqltablerow| message       | TEXT    |             |                       | an informational text about the action }}&lt;br /&gt;
{{sqltablerow| time          | INTEGER | NOT NULL    |                       | unixtimestamp / transaction time }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
===== Transaction codes =====&lt;br /&gt;
&lt;br /&gt;
The transactions from the table tmw_transactions use a numeric code to define the action that has happened. This&lt;br /&gt;
table contains a description of all available actions.&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_transaction_codes}}&lt;br /&gt;
{{sqltablerow| id            | INTEGER | PRIMARY KEY | | unique id of the transaction code }} &lt;br /&gt;
{{sqltablerow| description   | TEXT    | NOT NULL    | | a short description of the action }}&lt;br /&gt;
{{sqltablerow| category      | TEXT    | NOT NULL    | | a short categorization of the action }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== List of online users ====&lt;br /&gt;
&lt;br /&gt;
TMWSERV maintains a list of online users. You can select this table directly to find out who is online, or use the services provided by TMWWEB.&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_online_list}}&lt;br /&gt;
{{sqltablerow| char_id          | INTEGER | PRIMARY KEY | tmw_characters | unique id of the character }} &lt;br /&gt;
{{sqltablerow| login_date       | INTEGER | NOT NULL    |  | Unix time-stamp of login }}&lt;br /&gt;
{{endsqltable}}&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Database_specifications&amp;diff=13145</id>
		<title>Archive:Database specifications</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Database_specifications&amp;diff=13145"/>
		<updated>2009-08-23T11:17:41Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: /* User accounts */ added columns authorization and expiration&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Category_programming}}&lt;br /&gt;
&lt;br /&gt;
== SQL table specifications ==&lt;br /&gt;
&lt;br /&gt;
[[Image:Database specification proposal.png|thumb|200px|The current database model.]]&lt;br /&gt;
&lt;br /&gt;
=== User accounts ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_accounts}}&lt;br /&gt;
{{sqltablerow| id            | INTEGER     | PRIMARY KEY      | | unique id of an account}}                       }}&lt;br /&gt;
{{sqltablerow|username       | TEXT        | NOT NULL UNIQUE  | | username / loginname of an user                 }}&lt;br /&gt;
{{sqltablerow|password       | TEXT        | NOT NULL         | | password of an user (sha256 encoded)            }}&lt;br /&gt;
{{sqltablerow|email          | TEXT        | NOT NULL         | | email (sha256 encoded, only for pwd recovery)   }}&lt;br /&gt;
{{sqltablerow|level          | INTEGER     | NOT NULL         | | numeric level of the user account               }}&lt;br /&gt;
{{sqltablerow|banned         | INTEGER     | NOT NULL         | | unixtimestamp until when the account is banned  }}&lt;br /&gt;
{{sqltablerow|registration   | INTEGER     | NOT NULL         | | unixtimestamp of account registration           }}&lt;br /&gt;
{{sqltablerow|lastlogin      | INTEGER     | NOT NULL         | | unixtimestamp of last login with client         }}&lt;br /&gt;
{{sqltablerow|authorization  | TEXT        |                  | | secret key used for password recovery           }}&lt;br /&gt;
{{sqltablerow|expiration     | INTEGER     |                  | | unixtimestamp defining expiration of secret key }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Details ====&lt;br /&gt;
* email&lt;br /&gt;
** The email is stored as a one-way sha256 hash value. This ensures, that the email address a user enters cannot be used to send spam mails. It is only used to validate the mailaddress during password recovery procedure.&lt;br /&gt;
* level&lt;br /&gt;
** describes the user rights in the game (10 = normal user, 50 = gm, 99 = administrator)&lt;br /&gt;
* authorization and expiration &lt;br /&gt;
** these fields are used by TMWWEB to store a secret key and the time of expiration if the user has requested to reset its password. The secret key is sent via mail to the user.&lt;br /&gt;
&lt;br /&gt;
=== Characters ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_characters}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY      |                 | unique id of the character                              }}&lt;br /&gt;
{{sqltablerow|user_id        | INTEGER     | NOT NULL         | tmw_accounts.id | id of the owner                                         }}&lt;br /&gt;
{{sqltablerow|name           | TEXT        | NOT NULL UNIQUE  |                 | name of the character                                   }}&lt;br /&gt;
{{sqltablerow|gender         | INTEGER     | NOT NULL         |                 | gender of the character (0/1)                           }}&lt;br /&gt;
{{sqltablerow|hair_style     | INTEGER     | NOT NULL         |                 | id of the hair sprite                                   }}&lt;br /&gt;
{{sqltablerow|hair_color     | INTEGER     | NOT NULL         |                 | id of the hair color                                    }}&lt;br /&gt;
{{sqltablerow|level          | INTEGER     | NOT NULL         |                 | experience level of the character                       }}&lt;br /&gt;
{{sqltablerow|char_pts       | INTEGER     | NOT NULL         |                 | available points to raise attributes                    }}&lt;br /&gt;
{{sqltablerow|correct_pts    | INTEGER     | NOT NULL         |                 | available points to lower attributes and regain char_pts}}&lt;br /&gt;
{{sqltablerow|money          | INTEGER     | NOT NULL         |                 | GP of the character                                     }}&lt;br /&gt;
{{sqltablerow|x              | INTEGER     | NOT NULL         |                 | x position of the character on the map                  }}&lt;br /&gt;
{{sqltablerow|y              | INTEGER     | NOT NULL         |                 | y position of the character on the map                  }}&lt;br /&gt;
{{sqltablerow|map_id         | INTEGER     | NOT NULL         | tmw_maps.id     | id of the current map the character is located          }}&lt;br /&gt;
{{sqltablerow|str            | INTEGER     | NOT NULL         |                 | strength of the character                               }}&lt;br /&gt;
{{sqltablerow|agi            | INTEGER     | NOT NULL         |                 | agility of the character                                }}&lt;br /&gt;
{{sqltablerow|dex            | INTEGER     | NOT NULL         |                 | dexternity of the character                             }}&lt;br /&gt;
{{sqltablerow|vit            | INTEGER     | NOT NULL         |                 | vitality of the character                               }}&lt;br /&gt;
{{sqltablerow|int            | INTEGER     | NOT NULL         |                 | intelligence of the character                           }}&lt;br /&gt;
{{sqltablerow|will           | INTEGER     | NOT NULL         |                 | willpower of the character                              }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Concerns ====&lt;br /&gt;
&lt;br /&gt;
* The way experience is part of this table really won&#039;t scale and isn&#039;t flexible in any way. It&#039;s currently already way too many variables in one table row, and these are just the weapon skills. So I think we should really have a separate table for storing skill levels similar to the character inventory table below. So something that has { character_id, skill_id, experience }. The &amp;lt;code&amp;gt;skill_id&amp;lt;/code&amp;gt; should point to a &amp;lt;code&amp;gt;skills.xml&amp;lt;/code&amp;gt; file which describes (and categorizes) each skill. In that way we&#039;ll be able to easily change the set of skills and their names later. --[[User:BjÃ¸rn|BjÃ¸rn]] 18:09, 12 September 2008 (CEST)&lt;br /&gt;
** I think the same should be done with the attributes (str .. will). In theory almost every attribute in this table could be handled that way, it might look like a mess, but would be really friendly in customizing the gameplay elements. --[[User:Kess|kess]] 19:54, 12 September 2008 (CEST)&lt;br /&gt;
** I agree with that completely as this will give us more flexibility and a much more relational database design. I&#039;ve extended the &amp;quot;DAL improvements&amp;quot; task in mantis: #424 --[[User:Exceptionfault|Exceptionfault]] 15:50, 14 September 2008 (CEST)&lt;br /&gt;
*** Thanks for taking out the skills from this table. However, I disagree about generalizing stuff on the level of attributes, unless there would be any plan of putting infrastructure in place to make this possible. For now we can&#039;t even finish a server for The Mana World within years, so please don&#039;t try to build a server that supports any online RPG just yet. I only suggested we take out the skills because it would be completely unmanageable as part of this table, but the list of attribute is not expected to change for now. --[[User:BjÃ¸rn|BjÃ¸rn]] 15:55, 22 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
=== Character attributes ===&lt;br /&gt;
&lt;br /&gt;
This table is intended to store skills and experiences of each character. &lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_char_skills}}&lt;br /&gt;
{{sqltablerow|char_id         | INTEGER     | NOT NULL | tmw_characters.id | reference to the character                    }}&lt;br /&gt;
{{sqltablerow|skill_id        | INTEGER     | NOT NULL | (skills.xml)      | reference to the skill                        }}&lt;br /&gt;
{{sqltablerow|exp             | INTEGER     | NOT NULL |                   | current experience of the char in this skill  }} &lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Concerns ====&lt;br /&gt;
&lt;br /&gt;
* I&#039;m not sure, if an INTEGER does the job for column exp? --[[User:Exceptionfault|Exceptionfault]] 14:40, 19 September 2008 (CEST)&lt;br /&gt;
** What is the range? I would expect it to be enough. --[[User:BjÃ¸rn|BjÃ¸rn]] 15:56, 22 September 2008 (CEST)&lt;br /&gt;
*** Hereâ€™s some basic info:&lt;br /&gt;
***: &#039;&#039;&#039;MySQL:&#039;&#039;&#039; INTEGER (INT) may be signed or unsigned and is 4 bytes large, MySQL also have 1, 2, 3 and 8 byte integer variants (TINYINT, SMALLINT, MEDIUMINT and BIGINT) [http://dev.mysql.com/doc/refman/6.0/en/numeric-types.html]&lt;br /&gt;
***: &#039;&#039;&#039;PostgreSQL:&#039;&#039;&#039; INTEGER (INT, INT4) is signed and 4 bytes large, PostgreSQL also have 2 and 8 byte integer variants (SMALLINT and BIGINT) [http://www.postgresql.org/docs/8.3/interactive/datatype-numeric.html]&lt;br /&gt;
***: &#039;&#039;&#039;SQLite:&#039;&#039;&#039; INTEGER is signed and size is either 1, 2, 3, 4, 6 or 8 bytes depending on the size of the value [http://sqlite.org/datatype3.html]&lt;br /&gt;
***: So, the largest integer type supported should be of 8 byte size (signed): from -9,223,372,036,854,775,808 to +9,223,372,036,854,775,807, while the â€œstandardâ€ (of the SQL variants above) signed 4 byte integer ranges from -2,147,483,648 to +2,147,483,647. --[[User:Kess|kess]] 21:18, 22 September 2008 (CEST)&lt;br /&gt;
*** Although we plan to have no fixed level cap I considered a skill level of about 100 to be the highest reasonable value a player can archieve. Level 100 requires an exp sum of 10 million with the current exp formula (levelÂ³ * 10) which fits into a 4 byte integer easily. We won&#039;t get in trouble with 32bit signed integers until the players get near skill level 600 (2.16 billion). The server and the netcode also use 32 bit integers internally.&lt;br /&gt;
&lt;br /&gt;
=== Character Inventory ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_inventories}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY      |                   | unique id of the item                          }}&lt;br /&gt;
{{sqltablerow|owner_id       | INTEGER     | NOT NULL         | tmw_characters.id | id of the owning character                     }}&lt;br /&gt;
{{sqltablerow|slot           | INTEGER     | NOT NULL         |                   | inventory slot where the item is equipped      }}&lt;br /&gt;
{{sqltablerow|class_id       | INTEGER     | NOT NULL         |                   | type of the item, see items.xml file of tmwserv}}&lt;br /&gt;
{{sqltablerow|amount         | INTEGER     | NOT NULL         |                   | amount of items per slot                       }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Comments ====&lt;br /&gt;
* While I havenâ€™t looked how this table is used (my C++ knowledge is rather basic) it seems quite rigid and unflexible (as BjÃ¸rn noted above for the &#039;&#039;&#039;tmw_characters&#039;&#039;&#039; table). I think it would be nicer to have something like {&#039;&#039;owner_id&#039;&#039; FK, &#039;&#039;slot&#039;&#039;, &#039;&#039;item_id&#039;&#039; FK, &#039;&#039;amount&#039;&#039;, PK owner_id + slot}, where class_id shouldnâ€™t directly be needed in this table. --[[User:Kess|kess]] 19:49, 12 September 2008 (CEST)&lt;br /&gt;
* Concerning new features like houses, bank accounts, chests or similar, i think the design of this table needs some more roundtrips. You will need a column which indicates if the item is carried by the character or stored in a chest or in a house; as it makes no sense to have a table for every possible storage type or location. Another point is, that items should be more individualizable (is this a real word? :)). Think about custom colored shirts. So we will need at least one additional table to store individual attributes of items. --[[User:Exceptionfault|Exceptionfault]] 16:02, 14 September 2008 (CEST)&lt;br /&gt;
** We want all equipment to be completely individual with completely unique stats. --[[User:Crush2|Crush2]] 16:13, 14 September 2008 (CEST)&lt;br /&gt;
*** Good to know, so I will extend the DAL improvement task in mantis. --[[User:Exceptionfault|Exceptionfault]] 16:20, 14 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
=== Guilds ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_guilds}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY     |  | unique id of the guid   }}&lt;br /&gt;
{{sqltablerow|name           | TEXT        | NOT NULL UNIQUE |  | unique name of the guild}}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Guild memberships ===&lt;br /&gt;
&lt;br /&gt;
The table &#039;&#039;tmw_guild_members&#039;&#039; stores informations which character is member in which guild and which rights does he has.&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_guild_members}}&lt;br /&gt;
{{sqltablerow|guild_id        | INTEGER     | NOT NULL | tmw_guilds.id     | reference to the guild                                                }}&lt;br /&gt;
{{sqltablerow|member_id       | INTEGER     | NOT NULL | tmw_characters.id | reference to the characters                                           }}&lt;br /&gt;
{{sqltablerow|rights          | INTEGER     | NOT NULL |                   | id showing the rights a character has in this guild (member, admin...)}}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== World state ===&lt;br /&gt;
&lt;br /&gt;
The table &#039;&#039;tmw_world_state&#039;&#039; is used to store persistent informations about the world or individual maps.&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_world_state}}&lt;br /&gt;
{{sqltablerow| state_name      | TEXT     | PRIMARY KEY |             | unique name of a state variable        }} &lt;br /&gt;
{{sqltablerow| map_id          | INTEGER  | NULL        | tmw_maps.id | reference to a map, see details        }}&lt;br /&gt;
{{sqltablerow| value           | TEXT     | NULL        |             | string value of the state              }}&lt;br /&gt;
{{sqltablerow| moddate         | INTEGER  | NOT NULL    |             | date and time of the last modification }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Details ====&lt;br /&gt;
&lt;br /&gt;
* The column &#039;&#039;state_name&#039;&#039; forms the primary key of the table. If &#039;&#039;map_id&#039;&#039; is null, the variable is used globally in the world, otherwise the variable is specific for a map.&lt;br /&gt;
* &#039;&#039;moddate&#039;&#039; is for informational use only as it contains the unixtimestamp of the last modification.&lt;br /&gt;
&lt;br /&gt;
==== Comments ====&lt;br /&gt;
&lt;br /&gt;
* It seems that SQLite doesn&#039;t support composite primary keys (span PK over multiple columns). Therefore it is not possible to allow multiple &#039;&#039;state_name&#039;&#039;s with different &#039;&#039;map_id&#039;&#039;s. So we set a &#039;&#039;state_name&#039;&#039; to unique and use &#039;&#039;map_id&#039;&#039; as notifier if this variable is globally used or just locally for a specific map. --[[User:Exceptionfault|Exceptionfault]] 11:05, 15 September 2008 (CEST)&lt;br /&gt;
** This table is ready for usage, commited as rev. 4629 --[[User:Exceptionfault|Exceptionfault]] 13:51, 15 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Quest states ===&lt;br /&gt;
&lt;br /&gt;
This table is used to store states of quests per character, e.g. if a character has just finished a quest or is currently at the second part of the long journey...&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_quests}}&lt;br /&gt;
{{sqltablerow|owner_id        | INTEGER     | NOT NULL | tmw_characters.id | reference to the character         }}&lt;br /&gt;
{{sqltablerow|name            | TEXT        | NOT NULL |                   | name of the quest variable         }}&lt;br /&gt;
{{sqltablerow|value           | TEXT        | NOT NULL |                   | current value of the quest variable}} &lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Comments ====&lt;br /&gt;
&lt;br /&gt;
* Unless this table is adapted so that it stores the state of a particular quest, this one should have a name which makes it move obvious that it&#039;s storing custom values for &#039;&#039;characters&#039;&#039;. I consider that different from quests variables, which I would expect to be scoped to a certain quest (global quest variables) or quest instance (local quest variables). --[[User:BjÃ¸rn|BjÃ¸rn]] 18:16, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* We might want to have a similar table to this to store custom values for item instances, and also one for custom world-state variables. --[[User:BjÃ¸rn|BjÃ¸rn]] 18:16, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* I always wondered why Silene used the terminology &amp;quot;Quest&amp;quot; for what is basically a system to store/querry persistent character-bound integer variables which can be used for countless purposes, not just quests. I think we should rename this whole system to &amp;quot;character variable&amp;quot; in the database, server source and script bindings. --[[User:Crush2|Crush2]] 23:28, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* I agree with BjÃ¸rn concerning the additional tables for custom item values and custom world-state values. Although the name &amp;quot;tmw_quests&amp;quot; is a little bit confusing and should be renamed, I suggest keeping a table as such to store only quest states of characters and not to mix up with other persistent states. Instead we should provide a much cleaner documentation about the available quests and their persistent states that are possible. I envision something like a questbook in game, where each player can have a look at his finished quests and currently open quests, maybe with hints on the minimap, a todo list .... Besides that, we should be aware of dividing quests into &amp;quot;per-character&amp;quot;, &amp;quot;per-party&amp;quot; or global world quests.  --[[User:Exceptionfault|Exceptionfault]] 16:20, 14 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* I am not sure I understand everything which have been said above, so I will just sketch how I would do it. The table would have one &#039;&#039;owner_id&#039;&#039; (mandatory unique integer: a character; possibly either a character, an account, a guild etc.) and a number of &#039;&#039;variable&#039;&#039;s (mandatory non-uniqe datatype: holding a number of quest states). The variables would simply be named &#039;&#039;variable1&#039;&#039; and so on, and added as necessary.&lt;br /&gt;
** In the Lua quest scripts the bit masks would be hidden and the quest states themselves would be assigned and checked through general functions.&lt;br /&gt;
** An XML file &amp;lt;code&amp;gt;quests.xml&amp;lt;/code&amp;gt; or otherfashionly named would hold the general information regarding the quests and their states so that there could be content updates (of a stripped down version of the server file). By requesting the quest states from the server the clients would show the info with a nice GUI.&lt;br /&gt;
: What I do not understand above is the need to split the quest variable into name and value... But Iâ€™m merely a beginner in database designs and you surely have a clever reason why far beyond my own grasp of the matter.&lt;br /&gt;
: âœŽâ€ˆ[[User:Kess|Kess]]&amp;lt;sup&amp;gt;[[User talk:Kess|â˜½]]&amp;lt;/sup&amp;gt; 15:25, 23 May 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
=== Auctions ===&lt;br /&gt;
&lt;br /&gt;
Inspired by the ManaBay auction system developed by Qoal, it is planned to build a trading platform for the whole community of players using item auctions.&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_auctions}}&lt;br /&gt;
{{sqltablerow| auction_id    | INTEGER     | PRIMARY KEY      |                     | unique id of an auction                    }}&lt;br /&gt;
{{sqltablerow| auction_state | INTEGER     | NOT NULL         |                     | current state of the auction               }}&lt;br /&gt;
{{sqltablerow| char_id       | INTEGER     | NOT NULL         | tmw_characters (id) | owner of the auction                       }}&lt;br /&gt;
{{sqltablerow| itemclass_id  | INTEGER     | NOT NULL         | items.xml           | id of the item                             }}&lt;br /&gt;
{{sqltablerow| amount        | INTEGER     | NOT NULL         |                     | amount of items to trade                   }}&lt;br /&gt;
{{sqltablerow| start_time    | INTEGER     | NOT NULL         |                     | date of creation or start of auction       }}&lt;br /&gt;
{{sqltablerow| end_time      | INTEGER     | NOT NULL         |                     | end of auction (unixtimestamp)             }}&lt;br /&gt;
{{sqltablerow| start_price   | INTEGER     | NOT NULL         |                     | minimum price for the first bid            }}&lt;br /&gt;
{{sqltablerow| min_price     | INTEGER     | NULL             |                     | minimum price for the final bid to succeed }}&lt;br /&gt;
{{sqltablerow| buyout_price  | INTEGER     | NULL             |                     | price for direct buy of bidded item        }}&lt;br /&gt;
{{sqltablerow| description   | TEXT        | NULL             |                     | optional description of an auction         }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Annotations ====&lt;br /&gt;
&lt;br /&gt;
* auction_state can have the following values:&lt;br /&gt;
** 0 = The auction is published and ready for bidders&lt;br /&gt;
** 1 = The auction has finished and closed&lt;br /&gt;
* start_time contains the creation date of the auction. Format: Unixtimestamp&lt;br /&gt;
&lt;br /&gt;
==== Bids on Auctions ====&lt;br /&gt;
&lt;br /&gt;
This table stores bids made by characters to a specific auction.&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_auctions}}&lt;br /&gt;
{{sqltablerow| bid_id        | INTEGER     | PRIMARY KEY      |                     | unique id of a bid                         }}&lt;br /&gt;
{{sqltablerow| auction_id    | INTEGER     | NOT NULL         | tmw_auctions        | unique id of an auction                    }}&lt;br /&gt;
{{sqltablerow| char_id       | INTEGER     | NOT NULL         | tmw_characters      | owner of the bid                           }}&lt;br /&gt;
{{sqltablerow| bid_time      | INTEGER     | NOT NULL         |                     | time of the bid, used for sorting bids     }}&lt;br /&gt;
{{sqltablerow| bid_price     | INTEGER     | NOT NULL         |                     | price bidded by the character              }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
===== Annotations =====&lt;br /&gt;
&lt;br /&gt;
* bid_time holds the date and time of the bid as Unixtimestamp. Regarding 2 bids can be placed at the same second, the higher bid_price is relevant. If the bid_price is also equal, the smallest bid_id counts, as this is the record first inserted into the database.&lt;br /&gt;
&lt;br /&gt;
=== Postal system ===&lt;br /&gt;
&lt;br /&gt;
==== Letters ====&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_post}}&lt;br /&gt;
{{sqltablerow| letter_id        | INTEGER | PRIMARY KEY |                | unique id of the letter }} &lt;br /&gt;
{{sqltablerow| sender_id        | INTEGER | NOT NULL    | tmw_characters | sending character of the letter }}&lt;br /&gt;
{{sqltablerow| receiver_id      | INTEGER | NOT NULL    | tmw_characters | receiving character of the letter }}&lt;br /&gt;
{{sqltablerow| letter_type      | INTEGER | NOT NULL    |                | type of the letter (unused atm) }}&lt;br /&gt;
{{sqltablerow| expiration_date  | INTEGER | NOT NULL    |                | date and time of expiration }}&lt;br /&gt;
{{sqltablerow| sending_date     | INTEGER | NOT NULL    |                | date and time of sending }}&lt;br /&gt;
{{sqltablerow| letter_text      | TEXT    |     NULL    |                | text }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Item attachments ====&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_post_attachments}}&lt;br /&gt;
{{sqltablerow| attachment_id | INTEGER | PRIMARY KEY |                    | unique id of the attachment }} &lt;br /&gt;
{{sqltablerow| letter_id     | INTEGER | NOT NULL    | tmw_post           | reference to the letter }}&lt;br /&gt;
{{sqltablerow| item_id       | INTEGER | NOT NULL    | tmw_item_instances | attached itema }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Miscellaneous ===&lt;br /&gt;
&lt;br /&gt;
==== List of online users ====&lt;br /&gt;
&lt;br /&gt;
TMWSERV maintains a list of online users. You can select this table directly to find out who is online, or use the services provided by TMWWEB.&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_online_list}}&lt;br /&gt;
{{sqltablerow| char_id          | INTEGER | PRIMARY KEY | tmw_characters | unique id of the character }} &lt;br /&gt;
{{sqltablerow| login_date       | INTEGER | NOT NULL    |  | Unix time-stamp of login }}&lt;br /&gt;
{{endsqltable}}&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=Git&amp;diff=10923</id>
		<title>Git</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=Git&amp;diff=10923"/>
		<updated>2008-12-08T07:32:38Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: Make the wiki more searchable&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Git Repository]]&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:TMWWeb_Connector&amp;diff=10873</id>
		<title>Archive:TMWWeb Connector</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:TMWWeb_Connector&amp;diff=10873"/>
		<updated>2008-12-03T12:40:33Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: /* List of online users (onlineuser) */ added csv as output format&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What is a TMWWEB Connector? ==&lt;br /&gt;
&lt;br /&gt;
The TMWWEB Connector is a package of methods provided by TMWWEB to allow foreign applications to access data of the running tmwserv server. A common example is a list of online users that are currently connected to the server. TMWWEB is able to deliver the data in different formats to be as open as possible for all kinds of applications, e.g. plain text or xml.&lt;br /&gt;
&lt;br /&gt;
== FAQ ==&lt;br /&gt;
&lt;br /&gt;
=== How can I connect to the Connector? ===&lt;br /&gt;
&lt;br /&gt;
Until today, ther is no public installation of the [[Account Manager]] respective the connector. If you set up an installation of your own, just navigate your browser to the mainpage of tmwweb and add a &amp;quot;index.php/connector/&amp;quot; to the URL. The URL might look like that:&lt;br /&gt;
 &lt;br /&gt;
   http://localhost/tmwweb/index.php/connector/&lt;br /&gt;
&lt;br /&gt;
This is the root URL of the connector. Now you have to extend the URL with the name of the connector function you wan&#039;t to execute, e.g. &#039;&#039;onlineuser&#039;&#039; which will give you a URL like this:&lt;br /&gt;
&lt;br /&gt;
   http://localhost/tmwweb/index.php/connector/onlineuser/&lt;br /&gt;
&lt;br /&gt;
Some methods probaly need input parameters or support different output formats. All parameters have to be added with a &amp;quot;/&amp;quot; to the url similar as the method name. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Method Specification ==&lt;br /&gt;
&lt;br /&gt;
=== List of online users (onlineuser) ===&lt;br /&gt;
&lt;br /&gt;
This will give you a list of all users online and connected with a char to the tmwserv Server.&lt;br /&gt;
&lt;br /&gt;
==== Parameters ====&lt;br /&gt;
# Output format:&lt;br /&gt;
#* &amp;quot;plain&amp;quot; (default) will return a plain textfile with a character name per line.&lt;br /&gt;
#* &amp;quot;xml&amp;quot; will return a xml file with more detailed informations about online characters.&lt;br /&gt;
#* &amp;quot;csv&amp;quot; will return a plain textfile with detailed informations about online characters, separated by a &amp;quot;,&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Plain text example&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
   name&lt;br /&gt;
   name2&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;XML example&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;users&amp;gt;&lt;br /&gt;
      &amp;lt;user name=&amp;quot;[string]&amp;quot; &lt;br /&gt;
            gender=&amp;quot;[number]&amp;quot; &lt;br /&gt;
            map=&amp;quot;[number]&amp;quot; &lt;br /&gt;
            login_timestamp=&amp;quot;[number]&amp;quot;&lt;br /&gt;
            login_date=&amp;quot;[string]&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;user ...&amp;gt;&lt;br /&gt;
   &amp;lt;/users&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CSV example&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
   &amp;quot;name&amp;quot;,gender,map,login_timestamp,&amp;quot;login_date&amp;quot;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;name&#039;&#039;: Name of the character&lt;br /&gt;
* &#039;&#039;gender&#039;&#039;: 0 = male, 1 = female&lt;br /&gt;
* &#039;&#039;map&#039;&#039;: ID of the current location (see [[Configuration file:maps.xml]])&lt;br /&gt;
* &#039;&#039;login_timestamp&#039;&#039;: Unix time-stamp the character logged in&lt;br /&gt;
* &#039;&#039;login_date&#039;&#039;: Time-stamp of login in ISO 8601 format (e.g. 2004-02-12T15:19:21+00:00) &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Usage ====&lt;br /&gt;
   connector/onlineuser/[plain|xml|csv]&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:TMWWeb_Connector&amp;diff=10872</id>
		<title>Archive:TMWWeb Connector</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:TMWWeb_Connector&amp;diff=10872"/>
		<updated>2008-12-03T11:52:57Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What is a TMWWEB Connector? ==&lt;br /&gt;
&lt;br /&gt;
The TMWWEB Connector is a package of methods provided by TMWWEB to allow foreign applications to access data of the running tmwserv server. A common example is a list of online users that are currently connected to the server. TMWWEB is able to deliver the data in different formats to be as open as possible for all kinds of applications, e.g. plain text or xml.&lt;br /&gt;
&lt;br /&gt;
== FAQ ==&lt;br /&gt;
&lt;br /&gt;
=== How can I connect to the Connector? ===&lt;br /&gt;
&lt;br /&gt;
Until today, ther is no public installation of the [[Account Manager]] respective the connector. If you set up an installation of your own, just navigate your browser to the mainpage of tmwweb and add a &amp;quot;index.php/connector/&amp;quot; to the URL. The URL might look like that:&lt;br /&gt;
 &lt;br /&gt;
   http://localhost/tmwweb/index.php/connector/&lt;br /&gt;
&lt;br /&gt;
This is the root URL of the connector. Now you have to extend the URL with the name of the connector function you wan&#039;t to execute, e.g. &#039;&#039;onlineuser&#039;&#039; which will give you a URL like this:&lt;br /&gt;
&lt;br /&gt;
   http://localhost/tmwweb/index.php/connector/onlineuser/&lt;br /&gt;
&lt;br /&gt;
Some methods probaly need input parameters or support different output formats. All parameters have to be added with a &amp;quot;/&amp;quot; to the url similar as the method name. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Method Specification ==&lt;br /&gt;
&lt;br /&gt;
=== List of online users (onlineuser) ===&lt;br /&gt;
&lt;br /&gt;
This will give you a list of all users online and connected with a char to the tmwserv Server.&lt;br /&gt;
&lt;br /&gt;
==== Parameters ====&lt;br /&gt;
# Output format:&lt;br /&gt;
#* &amp;quot;plain&amp;quot; (default) will return a plain textfile with a character name per line.&lt;br /&gt;
#* &amp;quot;xml&amp;quot; will return a xml file with more detailed informations about online characters.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;XML Spec&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;users&amp;gt;&lt;br /&gt;
      &amp;lt;user name=&amp;quot;[string]&amp;quot; &lt;br /&gt;
            gender=&amp;quot;[number]&amp;quot; &lt;br /&gt;
            map=&amp;quot;[number]&amp;quot; &lt;br /&gt;
            login_timestamp=&amp;quot;[number]&lt;br /&gt;
            login_date=&amp;quot;[string] /&amp;gt;&lt;br /&gt;
      &amp;lt;user ...&amp;gt;&lt;br /&gt;
   &amp;lt;/users&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each online user will result in its own &#039;&#039;user&#039;&#039; element. The following list explains the provided attributes per charcter:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;name&#039;&#039;: Name of the character&lt;br /&gt;
* &#039;&#039;gender&#039;&#039;: 0 = male, 1 = female&lt;br /&gt;
* &#039;&#039;map&#039;&#039;: ID of the current location (see [[Configuration file:maps.xml]])&lt;br /&gt;
* &#039;&#039;number&#039;&#039;: Unix time-stamp the character logged in&lt;br /&gt;
* &#039;&#039;login_date&#039;&#039;: Time-stamp of login in ISO 8601 format (e.g. 2004-02-12T15:19:21+00:00) &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Usage ====&lt;br /&gt;
   connector/onlineuser/[plain|xml]&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Account_Manager&amp;diff=10871</id>
		<title>Archive:Account Manager</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Account_Manager&amp;diff=10871"/>
		<updated>2008-12-03T11:15:31Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: added hint to tmwweb connector&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== The Mana World Account Manager ==&lt;br /&gt;
&lt;br /&gt;
The Account Manager also known as TMWWEB is the web interface for users and administrators to manage their accounts from outside the game. Users can reset their password, see their character stats, and change the email associated with the account. &lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
To install you need to clone tmwweb from our sourcecode repository. See: [[Git Repository]].&lt;br /&gt;
&lt;br /&gt;
You will need a web server running PHP 5.1 or later. If your accountserver uses SQLite as backend you have to enable pdo_sqlite for php.&lt;br /&gt;
On FreeBSD you will need to install ports databases/php5-pdo_sqlite and security/pecl-hash along with lang/php5.&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
&lt;br /&gt;
To get TMWWEB up and running there are several configuration steps to do. After uploading all scripts to your wwwroot, navigate with your browser to the root of the scripts ending with &#039;&#039;setup.php&#039;&#039;. This script will guide you through the setup progress and will tell you what to do next and why. If a task is red, fix it and reload the page until everything is in status green.&lt;br /&gt;
&lt;br /&gt;
=== Single tasks ===&lt;br /&gt;
&lt;br /&gt;
There are several config files that have to be prepared for your specific environment. You can find all config files under ./system/application/config&lt;br /&gt;
&lt;br /&gt;
Tmwweb comes with a default configuration file called &amp;quot;config.default.php&amp;quot; You should use this file as template to set up your individual configuration. Make a copy of this file and name rename it to &amp;quot;config.php&amp;quot;. In general you have to modify the following settings:&lt;br /&gt;
&lt;br /&gt;
    set the &amp;quot;base_url&amp;quot; to the url of your installation.&lt;br /&gt;
    define the desired &amp;quot;log_threshold&amp;quot; to your needs&lt;br /&gt;
&lt;br /&gt;
Do the same with the file &amp;quot;database.default.php&amp;quot; and &amp;quot;email.default.php&amp;quot;. Rename them to &amp;quot;database.php&amp;quot; and &amp;quot;email.php&amp;quot; configure the options inside for your needs.&lt;br /&gt;
    &lt;br /&gt;
The following configuration files are shipped with defaults that may or may not be suitable for you. &lt;br /&gt;
&lt;br /&gt;
    menu.php&lt;br /&gt;
    tmw_config.php&lt;br /&gt;
    &lt;br /&gt;
Instead of modifying the files directly you should make a copy of them and rename them to &amp;lt;prefix&amp;gt;.user.php, so &amp;quot;menu.php&amp;quot; gets &amp;quot;menu.user.php&amp;quot;. Tmwweb first loads menu.php, afterwards menu.user.php (if it exists) and overrides the default values with your custom settings. The advantage of this method is, that upgrading tmwweb won&#039;t break your configuration. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Hint: You should only define values in the *.user.php files that differ from the default! Remove every entry from those files that match the default!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;All other files in the config directory shouldn`t get touched by you!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
After proper configuration of all files you have to ensure that the webserver has write access to the ./system/logs, the ./images/items and ./data directory. &lt;br /&gt;
&lt;br /&gt;
    chmod 777 ./system/logs&lt;br /&gt;
    chmod 777 ./data&lt;br /&gt;
    chmod 777 ./images/items&lt;br /&gt;
    &lt;br /&gt;
Tmwweb tries to store cached data read from other modules like tmwserv in the data directory for faster access. Therefore you should allow the webserver to create files there. The logs directory is used for logging as you can think. &lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
After uploading and configuring tmwweb it might happen that every site you call is only white and blank. Lets set loglevel in config.php to 4 and after refreshing your site in the browser have a look at the logfiles under ./system/logs&lt;br /&gt;
If there is no file except index.html please recheck your directory permissions. Again, the webserver needs write permissions to ./system/logs. If you cannot find a file that is named &amp;quot;config.php&amp;quot;, please go back to the chapter [[#Configuration]] and read it more carefully!&lt;br /&gt;
&lt;br /&gt;
== Translations ==&lt;br /&gt;
&lt;br /&gt;
Tmwweb has a simple multilanguage support integrated. During login into your account you can choose one of the currently translated languages. If your native language is not available yet, feel free to support the dev team and translate tmwweb.&lt;br /&gt;
&lt;br /&gt;
=== Howto translate into your language ===&lt;br /&gt;
To start with a new language there are two simple steps to do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Copy the directoy &amp;lt;tt&amp;gt;./system/application/language/english&amp;lt;/tt&amp;gt; as it is the shipped language with tmwweb and should contain all necessary strings. Also you have to copy ./system/language/english to your new language. This directory contains strings comming from CodeIgniter, the used php framework. &lt;br /&gt;
&lt;br /&gt;
Ensure not to copy the hidden directory .svn if you checked out from subversion. Each php file ending with *_lang.php needs to be translated.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;       &lt;br /&gt;
       $lang[&#039;character&#039;] = &#039;&amp;lt;put your translation here&amp;gt;&#039;;        &lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Ensure to double quote inside of your strings if necessary.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Lastly you have to add your new language to the config file &amp;lt;tt&amp;gt;tmwweb/system/application/conf/tmw_conf.php&amp;lt;/tt&amp;gt;. Just add your language to the array &amp;lt;tt&amp;gt;$_tmw_languages&amp;lt;/tt&amp;gt; like shown below. The parameter &#039;dir&#039; has to be the name of your added directory, e.g. &#039;german&#039;. The parameter &#039;name&#039; is the displayed string during login. This should be the native name of the language, like &#039;deutsch&#039;.&lt;br /&gt;
&lt;br /&gt;
Don&#039;t forget a comma to separate language arrays.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;       &lt;br /&gt;
       $_tmw_languages = array( &lt;br /&gt;
          array(&#039;dir&#039;=&amp;gt;&#039;english&#039;, &#039;name&#039;=&amp;gt;&#039;english&#039;),&lt;br /&gt;
          array(&#039;dir&#039;=&amp;gt;&#039;german&#039;, &#039;name&#039;=&amp;gt;&#039;deutsch&#039;)&lt;br /&gt;
       );&lt;br /&gt;
&lt;br /&gt;
== Maintenance ==&lt;br /&gt;
&lt;br /&gt;
The intention of tmwweb is to be a slim, administrative frontend for tmwserv. Therfor it is natural to use as much as data, information and configuration we can get from tmwserv. Because tmwserv makes extensive use of xml configuration files, which would be too expensive to parse on every page request, tmwweb uses different methods to cache those informations for faster access.&lt;br /&gt;
&lt;br /&gt;
From time to time, if the data in tmwserv was modified, a admin user has to refresh the caches of tmwweb. Therefor you can find a menuoption &amp;quot;maintenance&amp;quot; when logged in with an administrative account. This page shows you all caches and allows you to refresh them with a single click.&lt;br /&gt;
&lt;br /&gt;
=== items.xml ===&lt;br /&gt;
&lt;br /&gt;
Refreshing the items database is a bit special, thats why it is mentioned here additionally.&lt;br /&gt;
To show the inventory of a character, the images of those items have to be available for a webbrowser. Therfore they have to reside somewhere under the DOCUMENT_ROOT of your webserver. To keep all things together, we decided to store them under ./images/items. When refreshing the items database, tmwweb looks in that directory and compares the images located there to all items in the database. If a image is missing, tmwweb tries to copy this image from your tmwdata path, you can configure in tmw_config.php (see chapter 2).&lt;br /&gt;
&lt;br /&gt;
To copy those images, the webserver needs write permission to the images/items directory. If tmwweb can&#039;t find the image in the tmwdata directory is is not allowed to write to the ./images/items directory, the refresh procedure will show you a list with all missing images. Then you will have to copy those images yourself.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== TMWWEB Connector ==&lt;br /&gt;
&lt;br /&gt;
The TMWWEB Connector is a package of methods provided by TMWWEB to allow foreign applications to access data of the running tmwserv server. A common example is a list of online users that are currently connected to the server. See [[TMWWEB Connector]] for a detailed description of available methods.&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Account_Manager&amp;diff=10870</id>
		<title>Archive:Account Manager</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Account_Manager&amp;diff=10870"/>
		<updated>2008-12-03T11:10:23Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: generally updated and fixed for git&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== The Mana World Account Manager ==&lt;br /&gt;
&lt;br /&gt;
The Account Manager also known as TMWWEB is the web interface for users and administrators to manage their accounts from outside the game. Users can reset their password, see their character stats, and change the email associated with the account. &lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
To install you need to clone tmwweb from our sourcecode repository. See: [[Git Repository]].&lt;br /&gt;
&lt;br /&gt;
You will need a web server running PHP 5.1 or later. If your accountserver uses SQLite as backend you have to enable pdo_sqlite for php.&lt;br /&gt;
On FreeBSD you will need to install ports databases/php5-pdo_sqlite and security/pecl-hash along with lang/php5.&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
&lt;br /&gt;
To get TMWWEB up and running there are several configuration steps to do. After uploading all scripts to your wwwroot, navigate with your browser to the root of the scripts ending with &#039;&#039;setup.php&#039;&#039;. This script will guide you through the setup progress and will tell you what to do next and why. If a task is red, fix it and reload the page until everything is in status green.&lt;br /&gt;
&lt;br /&gt;
=== Single tasks ===&lt;br /&gt;
&lt;br /&gt;
There are several config files that have to be prepared for your specific environment. You can find all config files under ./system/application/config&lt;br /&gt;
&lt;br /&gt;
Tmwweb comes with a default configuration file called &amp;quot;config.default.php&amp;quot; You should use this file as template to set up your individual configuration. Make a copy of this file and name rename it to &amp;quot;config.php&amp;quot;. In general you have to modify the following settings:&lt;br /&gt;
&lt;br /&gt;
    set the &amp;quot;base_url&amp;quot; to the url of your installation.&lt;br /&gt;
    define the desired &amp;quot;log_threshold&amp;quot; to your needs&lt;br /&gt;
&lt;br /&gt;
Do the same with the file &amp;quot;database.default.php&amp;quot; and &amp;quot;email.default.php&amp;quot;. Rename them to &amp;quot;database.php&amp;quot; and &amp;quot;email.php&amp;quot; configure the options inside for your needs.&lt;br /&gt;
    &lt;br /&gt;
The following configuration files are shipped with defaults that may or may not be suitable for you. &lt;br /&gt;
&lt;br /&gt;
    menu.php&lt;br /&gt;
    tmw_config.php&lt;br /&gt;
    &lt;br /&gt;
Instead of modifying the files directly you should make a copy of them and rename them to &amp;lt;prefix&amp;gt;.user.php, so &amp;quot;menu.php&amp;quot; gets &amp;quot;menu.user.php&amp;quot;. Tmwweb first loads menu.php, afterwards menu.user.php (if it exists) and overrides the default values with your custom settings. The advantage of this method is, that upgrading tmwweb won&#039;t break your configuration. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Hint: You should only define values in the *.user.php files that differ from the default! Remove every entry from those files that match the default!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;All other files in the config directory shouldn`t get touched by you!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
After proper configuration of all files you have to ensure that the webserver has write access to the ./system/logs, the ./images/items and ./data directory. &lt;br /&gt;
&lt;br /&gt;
    chmod 777 ./system/logs&lt;br /&gt;
    chmod 777 ./data&lt;br /&gt;
    chmod 777 ./images/items&lt;br /&gt;
    &lt;br /&gt;
Tmwweb tries to store cached data read from other modules like tmwserv in the data directory for faster access. Therefore you should allow the webserver to create files there. The logs directory is used for logging as you can think. &lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
After uploading and configuring tmwweb it might happen that every site you call is only white and blank. Lets set loglevel in config.php to 4 and after refreshing your site in the browser have a look at the logfiles under ./system/logs&lt;br /&gt;
If there is no file except index.html please recheck your directory permissions. Again, the webserver needs write permissions to ./system/logs. If you cannot find a file that is named &amp;quot;config.php&amp;quot;, please go back to the chapter [[#Configuration]] and read it more carefully!&lt;br /&gt;
&lt;br /&gt;
== Translations ==&lt;br /&gt;
&lt;br /&gt;
Tmwweb has a simple multilanguage support integrated. During login into your account you can choose one of the currently translated languages. If your native language is not available yet, feel free to support the dev team and translate tmwweb.&lt;br /&gt;
&lt;br /&gt;
=== Howto translate into your language ===&lt;br /&gt;
To start with a new language there are two simple steps to do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Copy the directoy &amp;lt;tt&amp;gt;./system/application/language/english&amp;lt;/tt&amp;gt; as it is the shipped language with tmwweb and should contain all necessary strings. Also you have to copy ./system/language/english to your new language. This directory contains strings comming from CodeIgniter, the used php framework. &lt;br /&gt;
&lt;br /&gt;
Ensure not to copy the hidden directory .svn if you checked out from subversion. Each php file ending with *_lang.php needs to be translated.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;       &lt;br /&gt;
       $lang[&#039;character&#039;] = &#039;&amp;lt;put your translation here&amp;gt;&#039;;        &lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Ensure to double quote inside of your strings if necessary.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Lastly you have to add your new language to the config file &amp;lt;tt&amp;gt;tmwweb/system/application/conf/tmw_conf.php&amp;lt;/tt&amp;gt;. Just add your language to the array &amp;lt;tt&amp;gt;$_tmw_languages&amp;lt;/tt&amp;gt; like shown below. The parameter &#039;dir&#039; has to be the name of your added directory, e.g. &#039;german&#039;. The parameter &#039;name&#039; is the displayed string during login. This should be the native name of the language, like &#039;deutsch&#039;.&lt;br /&gt;
&lt;br /&gt;
Don&#039;t forget a comma to separate language arrays.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;       &lt;br /&gt;
       $_tmw_languages = array( &lt;br /&gt;
          array(&#039;dir&#039;=&amp;gt;&#039;english&#039;, &#039;name&#039;=&amp;gt;&#039;english&#039;),&lt;br /&gt;
          array(&#039;dir&#039;=&amp;gt;&#039;german&#039;, &#039;name&#039;=&amp;gt;&#039;deutsch&#039;)&lt;br /&gt;
       );&lt;br /&gt;
&lt;br /&gt;
== Maintenance ==&lt;br /&gt;
&lt;br /&gt;
The intention of tmwweb is to be a slim, administrative frontend for tmwserv. Therfor it is natural to use as much as data, information and configuration we can get from tmwserv. Because tmwserv makes extensive use of xml configuration files, which would be too expensive to parse on every page request, tmwweb uses different methods to cache those informations for faster access.&lt;br /&gt;
&lt;br /&gt;
From time to time, if the data in tmwserv was modified, a admin user has to refresh the caches of tmwweb. Therefor you can find a menuoption &amp;quot;maintenance&amp;quot; when logged in with an administrative account. This page shows you all caches and allows you to refresh them with a single click.&lt;br /&gt;
&lt;br /&gt;
=== items.xml ===&lt;br /&gt;
&lt;br /&gt;
Refreshing the items database is a bit special, thats why it is mentioned here additionally.&lt;br /&gt;
To show the inventory of a character, the images of those items have to be available for a webbrowser. Therfore they have to reside somewhere under the DOCUMENT_ROOT of your webserver. To keep all things together, we decided to store them under ./images/items. When refreshing the items database, tmwweb looks in that directory and compares the images located there to all items in the database. If a image is missing, tmwweb tries to copy this image from your tmwdata path, you can configure in tmw_config.php (see chapter 2).&lt;br /&gt;
&lt;br /&gt;
To copy those images, the webserver needs write permission to the images/items directory. If tmwweb can&#039;t find the image in the tmwdata directory is is not allowed to write to the ./images/items directory, the refresh procedure will show you a list with all missing images. Then you will have to copy those images yourself.&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Upgrade_Database&amp;diff=10865</id>
		<title>Archive:Upgrade Database</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Upgrade_Database&amp;diff=10865"/>
		<updated>2008-12-01T08:39:39Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: provide error message if version mismatches between account server and database&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;From time to time, the database model used by tmwserv will be extended or modified. To prevent inconsistencies between the database model and the account server, the database model has its own version number which has to match the known version of the account server. That means, if you upgrade you database model, you also have to update tmwserv and vice versa. If the version of your database is incompatible with you version of the account server, the account server will print out a message like this on startup:&lt;br /&gt;
&lt;br /&gt;
   [FTL] Error opening the database: Database version is not supported. Needed version: &#039;1&#039;, current version: &#039;2&#039;&lt;br /&gt;
&lt;br /&gt;
In this case, the version of your database is newer, than the version of the account server. You have to get the latest sources of the account server.&lt;br /&gt;
&lt;br /&gt;
==== Determine the database version ====&lt;br /&gt;
&lt;br /&gt;
To find out which version your current database is of, try the following SELECT statement, which should work well independent of your database backend.&lt;br /&gt;
&lt;br /&gt;
   SELECT value FROM tmw_world_states WHERE state_name = &#039;database_version&#039;;&lt;br /&gt;
&lt;br /&gt;
This should give you a numeric value which represents your current database version. When using SQLite try the following statement:&lt;br /&gt;
&lt;br /&gt;
   sqlite3 tmw.db &amp;quot;SELECT value FROM tmw_world_states WHERE state_name = &#039;database_version&#039;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
==== How to upgrade my database ====&lt;br /&gt;
&lt;br /&gt;
According to your chosen database backend, you will find a subdirectory called &amp;quot;updates&amp;quot; under &amp;quot;tmwserv/src/sql/&amp;lt;db_backend&amp;gt;&amp;quot;. The update scripts follow a naming scheme like &amp;quot;update_&amp;lt;old_version&amp;gt;_to_&amp;lt;new_version&amp;gt;.sql&amp;quot;. So if your current version is &amp;quot;1&amp;quot; and you want to upgrade to &amp;quot;2&amp;quot;, find the script called &amp;quot;update_1_to_2.sql&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Steps to execute the script depends on your backend. For SQLite just move to the folder where your current database file &amp;quot;tmw.db&amp;quot; lies and type:&lt;br /&gt;
&lt;br /&gt;
  sqlite3 tmw.db &amp;lt; src/sql/sqlite/updates/update_1_to_2.sql&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention: The scripts don&#039;t matter what version you are running, so check it before running a script!&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Database_specifications&amp;diff=10864</id>
		<title>Archive:Database specifications</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Database_specifications&amp;diff=10864"/>
		<updated>2008-12-01T08:25:51Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: added table tmw_online_list to store online users&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Category_programming}}&lt;br /&gt;
&lt;br /&gt;
== SQL table specifications ==&lt;br /&gt;
&lt;br /&gt;
[[Image:Database specification proposal.png|thumb|200px|The current database model.]]&lt;br /&gt;
&lt;br /&gt;
=== User accounts ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_accounts}}&lt;br /&gt;
{{sqltablerow| id            | INTEGER     | PRIMARY KEY      | | unique id of an account}}                      }}&lt;br /&gt;
{{sqltablerow|username       | TEXT        | NOT NULL UNIQUE  | | username / loginname of an user                }}&lt;br /&gt;
{{sqltablerow|password       | TEXT        | NOT NULL         | | password of an user (sha256 encoded)           }}&lt;br /&gt;
{{sqltablerow|email          | TEXT        | NOT NULL         | | email (sha256 encoded, only for pwd recovery)  }}&lt;br /&gt;
{{sqltablerow|level          | INTEGER     | NOT NULL         | | numeric level of the user account              }}&lt;br /&gt;
{{sqltablerow|banned         | INTEGER     | NOT NULL         | | unixtimestamp until when the account is banned }}&lt;br /&gt;
{{sqltablerow|registration   | INTEGER     | NOT NULL         | | unixtimestamp of account registration          }}&lt;br /&gt;
{{sqltablerow|lastlogin      | INTEGER     | NOT NULL         | | unixtimestamp of last login with client        }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Details ====&lt;br /&gt;
* email&lt;br /&gt;
** The email is stored as a one-way sha256 hash value. This ensures, that the email address a user enters cannot be used to send spam mails. It is only used to validate the mailaddress during password recovery procedure.&lt;br /&gt;
* level&lt;br /&gt;
** describes the user rights in the game (10 = normal user, 50 = gm, 99 = administrator)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Characters ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_characters}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY      |                 | unique id of the character                              }}&lt;br /&gt;
{{sqltablerow|user_id        | INTEGER     | NOT NULL         | tmw_accounts.id | id of the owner                                         }}&lt;br /&gt;
{{sqltablerow|name           | TEXT        | NOT NULL UNIQUE  |                 | name of the character                                   }}&lt;br /&gt;
{{sqltablerow|gender         | INTEGER     | NOT NULL         |                 | gender of the character (0/1)                           }}&lt;br /&gt;
{{sqltablerow|hair_style     | INTEGER     | NOT NULL         |                 | id of the hair sprite                                   }}&lt;br /&gt;
{{sqltablerow|hair_color     | INTEGER     | NOT NULL         |                 | id of the hair color                                    }}&lt;br /&gt;
{{sqltablerow|level          | INTEGER     | NOT NULL         |                 | experience level of the character                       }}&lt;br /&gt;
{{sqltablerow|char_pts       | INTEGER     | NOT NULL         |                 | available points to raise attributes                    }}&lt;br /&gt;
{{sqltablerow|correct_pts    | INTEGER     | NOT NULL         |                 | available points to lower attributes and regain char_pts}}&lt;br /&gt;
{{sqltablerow|money          | INTEGER     | NOT NULL         |                 | GP of the character                                     }}&lt;br /&gt;
{{sqltablerow|x              | INTEGER     | NOT NULL         |                 | x position of the character on the map                  }}&lt;br /&gt;
{{sqltablerow|y              | INTEGER     | NOT NULL         |                 | y position of the character on the map                  }}&lt;br /&gt;
{{sqltablerow|map_id         | INTEGER     | NOT NULL         | tmw_maps.id     | id of the current map the character is located          }}&lt;br /&gt;
{{sqltablerow|str            | INTEGER     | NOT NULL         |                 | strength of the character                               }}&lt;br /&gt;
{{sqltablerow|agi            | INTEGER     | NOT NULL         |                 | agility of the character                                }}&lt;br /&gt;
{{sqltablerow|dex            | INTEGER     | NOT NULL         |                 | dexternity of the character                             }}&lt;br /&gt;
{{sqltablerow|vit            | INTEGER     | NOT NULL         |                 | vitality of the character                               }}&lt;br /&gt;
{{sqltablerow|int            | INTEGER     | NOT NULL         |                 | intelligence of the character                           }}&lt;br /&gt;
{{sqltablerow|will           | INTEGER     | NOT NULL         |                 | willpower of the character                              }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Concerns ====&lt;br /&gt;
&lt;br /&gt;
* The way experience is part of this table really won&#039;t scale and isn&#039;t flexible in any way. It&#039;s currently already way too many variables in one table row, and these are just the weapon skills. So I think we should really have a separate table for storing skill levels similar to the character inventory table below. So something that has { character_id, skill_id, experience }. The &amp;lt;code&amp;gt;skill_id&amp;lt;/code&amp;gt; should point to a &amp;lt;code&amp;gt;skills.xml&amp;lt;/code&amp;gt; file which describes (and categorizes) each skill. In that way we&#039;ll be able to easily change the set of skills and their names later. --[[User:BjÃ¸rn|BjÃ¸rn]] 18:09, 12 September 2008 (CEST)&lt;br /&gt;
** I think the same should be done with the attributes (str .. will). In theory almost every attribute in this table could be handled that way, it might look like a mess, but would be really friendly in customizing the gameplay elements. --[[User:Kess|kess]] 19:54, 12 September 2008 (CEST)&lt;br /&gt;
** I agree with that completely as this will give us more flexibility and a much more relational database design. I&#039;ve extended the &amp;quot;DAL improvements&amp;quot; task in mantis: #424 --[[User:Exceptionfault|Exceptionfault]] 15:50, 14 September 2008 (CEST)&lt;br /&gt;
*** Thanks for taking out the skills from this table. However, I disagree about generalizing stuff on the level of attributes, unless there would be any plan of putting infrastructure in place to make this possible. For now we can&#039;t even finish a server for The Mana World within years, so please don&#039;t try to build a server that supports any online RPG just yet. I only suggested we take out the skills because it would be completely unmanageable as part of this table, but the list of attribute is not expected to change for now. --[[User:BjÃ¸rn|BjÃ¸rn]] 15:55, 22 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
=== Character attributes ===&lt;br /&gt;
&lt;br /&gt;
This table is intended to store skills and experiences of each character. &lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_char_skills}}&lt;br /&gt;
{{sqltablerow|char_id         | INTEGER     | NOT NULL | tmw_characters.id | reference to the character                    }}&lt;br /&gt;
{{sqltablerow|skill_id        | INTEGER     | NOT NULL | (skills.xml)      | reference to the skill                        }}&lt;br /&gt;
{{sqltablerow|exp             | INTEGER     | NOT NULL |                   | current experience of the char in this skill  }} &lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Concerns ====&lt;br /&gt;
&lt;br /&gt;
* I&#039;m not sure, if an INTEGER does the job for column exp? --[[User:Exceptionfault|Exceptionfault]] 14:40, 19 September 2008 (CEST)&lt;br /&gt;
** What is the range? I would expect it to be enough. --[[User:BjÃ¸rn|BjÃ¸rn]] 15:56, 22 September 2008 (CEST)&lt;br /&gt;
*** Hereâ€™s some basic info:&lt;br /&gt;
***: &#039;&#039;&#039;MySQL:&#039;&#039;&#039; INTEGER (INT) may be signed or unsigned and is 4 bytes large, MySQL also have 1, 2, 3 and 8 byte integer variants (TINYINT, SMALLINT, MEDIUMINT and BIGINT) [http://dev.mysql.com/doc/refman/6.0/en/numeric-types.html]&lt;br /&gt;
***: &#039;&#039;&#039;PostgreSQL:&#039;&#039;&#039; INTEGER (INT, INT4) is signed and 4 bytes large, PostgreSQL also have 2 and 8 byte integer variants (SMALLINT and BIGINT) [http://www.postgresql.org/docs/8.3/interactive/datatype-numeric.html]&lt;br /&gt;
***: &#039;&#039;&#039;SQLite:&#039;&#039;&#039; INTEGER is signed and size is either 1, 2, 3, 4, 6 or 8 bytes depending on the size of the value [http://sqlite.org/datatype3.html]&lt;br /&gt;
***: So, the largest integer type supported should be of 8 byte size (signed): from -9,223,372,036,854,775,808 to +9,223,372,036,854,775,807, while the â€œstandardâ€ (of the SQL variants above) signed 4 byte integer ranges from -2,147,483,648 to +2,147,483,647. --[[User:Kess|kess]] 21:18, 22 September 2008 (CEST)&lt;br /&gt;
*** Although we plan to have no fixed level cap I considered a skill level of about 100 to be the highest reasonable value a player can archieve. Level 100 requires an exp sum of 10 million with the current exp formula (levelÂ³ * 10) which fits into a 4 byte integer easily. We won&#039;t get in trouble with 32bit signed integers until the players get near skill level 600 (2.16 billion). The server and the netcode also use 32 bit integers internally.&lt;br /&gt;
&lt;br /&gt;
=== Character Inventory ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_inventories}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY      |                   | unique id of the item                          }}&lt;br /&gt;
{{sqltablerow|owner_id       | INTEGER     | NOT NULL         | tmw_characters.id | id of the owning character                     }}&lt;br /&gt;
{{sqltablerow|slot           | INTEGER     | NOT NULL         |                   | inventory slot where the item is equipped      }}&lt;br /&gt;
{{sqltablerow|class_id       | INTEGER     | NOT NULL         |                   | type of the item, see items.xml file of tmwserv}}&lt;br /&gt;
{{sqltablerow|amount         | INTEGER     | NOT NULL         |                   | amount of items per slot                       }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Comments ====&lt;br /&gt;
* While I havenâ€™t looked how this table is used (my C++ knowledge is rather basic) it seems quite rigid and unflexible (as BjÃ¸rn noted above for the &#039;&#039;&#039;tmw_characters&#039;&#039;&#039; table). I think it would be nicer to have something like {&#039;&#039;owner_id&#039;&#039; FK, &#039;&#039;slot&#039;&#039;, &#039;&#039;item_id&#039;&#039; FK, &#039;&#039;amount&#039;&#039;, PK owner_id + slot}, where class_id shouldnâ€™t directly be needed in this table. --[[User:Kess|kess]] 19:49, 12 September 2008 (CEST)&lt;br /&gt;
* Concerning new features like houses, bank accounts, chests or similar, i think the design of this table needs some more roundtrips. You will need a column which indicates if the item is carried by the character or stored in a chest or in a house; as it makes no sense to have a table for every possible storage type or location. Another point is, that items should be more individualizable (is this a real word? :)). Think about custom colored shirts. So we will need at least one additional table to store individual attributes of items. --[[User:Exceptionfault|Exceptionfault]] 16:02, 14 September 2008 (CEST)&lt;br /&gt;
** We want all equipment to be completely individual with completely unique stats. --[[User:Crush2|Crush2]] 16:13, 14 September 2008 (CEST)&lt;br /&gt;
*** Good to know, so I will extend the DAL improvement task in mantis. --[[User:Exceptionfault|Exceptionfault]] 16:20, 14 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
=== Guilds ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_guilds}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY     |  | unique id of the guid   }}&lt;br /&gt;
{{sqltablerow|name           | TEXT        | NOT NULL UNIQUE |  | unique name of the guild}}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Guild memberships ===&lt;br /&gt;
&lt;br /&gt;
The table &#039;&#039;tmw_guild_members&#039;&#039; stores informations which character is member in which guild and which rights does he has.&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_guild_members}}&lt;br /&gt;
{{sqltablerow|guild_id        | INTEGER     | NOT NULL | tmw_guilds.id     | reference to the guild                                                }}&lt;br /&gt;
{{sqltablerow|member_id       | INTEGER     | NOT NULL | tmw_characters.id | reference to the characters                                           }}&lt;br /&gt;
{{sqltablerow|rights          | INTEGER     | NOT NULL |                   | id showing the rights a character has in this guild (member, admin...)}}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== World state ===&lt;br /&gt;
&lt;br /&gt;
The table &#039;&#039;tmw_world_state&#039;&#039; is used to store persistent informations about the world or individual maps.&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_world_state}}&lt;br /&gt;
{{sqltablerow| state_name      | TEXT     | PRIMARY KEY |             | unique name of a state variable        }} &lt;br /&gt;
{{sqltablerow| map_id          | INTEGER  | NULL        | tmw_maps.id | reference to a map, see details        }}&lt;br /&gt;
{{sqltablerow| value           | TEXT     | NULL        |             | string value of the state              }}&lt;br /&gt;
{{sqltablerow| moddate         | INTEGER  | NOT NULL    |             | date and time of the last modification }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Details ====&lt;br /&gt;
&lt;br /&gt;
* The column &#039;&#039;state_name&#039;&#039; forms the primary key of the table. If &#039;&#039;map_id&#039;&#039; is null, the variable is used globally in the world, otherwise the variable is specific for a map.&lt;br /&gt;
* &#039;&#039;moddate&#039;&#039; is for informational use only as it contains the unixtimestamp of the last modification.&lt;br /&gt;
&lt;br /&gt;
==== Comments ====&lt;br /&gt;
&lt;br /&gt;
* It seems that SQLite doesn&#039;t support composite primary keys (span PK over multiple columns). Therefore it is not possible to allow multiple &#039;&#039;state_name&#039;&#039;s with different &#039;&#039;map_id&#039;&#039;s. So we set a &#039;&#039;state_name&#039;&#039; to unique and use &#039;&#039;map_id&#039;&#039; as notifier if this variable is globally used or just locally for a specific map. --[[User:Exceptionfault|Exceptionfault]] 11:05, 15 September 2008 (CEST)&lt;br /&gt;
** This table is ready for usage, commited as rev. 4629 --[[User:Exceptionfault|Exceptionfault]] 13:51, 15 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Quest states ===&lt;br /&gt;
&lt;br /&gt;
This table is used to store states of quests per character, e.g. if a character has just finished a quest or is currently at the second part of the long journey...&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_quests}}&lt;br /&gt;
{{sqltablerow|owner_id        | INTEGER     | NOT NULL | tmw_characters.id | reference to the character         }}&lt;br /&gt;
{{sqltablerow|name            | TEXT        | NOT NULL |                   | name of the quest variable         }}&lt;br /&gt;
{{sqltablerow|value           | TEXT        | NOT NULL |                   | current value of the quest variable}} &lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Comments ====&lt;br /&gt;
&lt;br /&gt;
* Unless this table is adapted so that it stores the state of a particular quest, this one should have a name which makes it move obvious that it&#039;s storing custom values for &#039;&#039;characters&#039;&#039;. I consider that different from quests variables, which I would expect to be scoped to a certain quest (global quest variables) or quest instance (local quest variables). --[[User:BjÃ¸rn|BjÃ¸rn]] 18:16, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* We might want to have a similar table to this to store custom values for item instances, and also one for custom world-state variables. --[[User:BjÃ¸rn|BjÃ¸rn]] 18:16, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* I always wondered why Silene used the terminology &amp;quot;Quest&amp;quot; for what is basically a system to store/querry persistent character-bound integer variables which can be used for countless purposes, not just quests. I think we should rename this whole system to &amp;quot;character variable&amp;quot; in the database, server source and script bindings. --[[User:Crush2|Crush2]] 23:28, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* I agree with BjÃ¸rn concerning the additional tables for custom item values and custom world-state values. Although the name &amp;quot;tmw_quests&amp;quot; is a little bit confusing and should be renamed, I suggest keeping a table as such to store only quest states of characters and not to mix up with other persistent states. Instead we should provide a much cleaner documentation about the available quests and their persistent states that are possible. I envision something like a questbook in game, where each player can have a look at his finished quests and currently open quests, maybe with hints on the minimap, a todo list .... Besides that, we should be aware of dividing quests into &amp;quot;per-character&amp;quot;, &amp;quot;per-party&amp;quot; or global world quests.  --[[User:Exceptionfault|Exceptionfault]] 16:20, 14 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
=== Auctions ===&lt;br /&gt;
&lt;br /&gt;
Inspired by the ManaBay auction system developed by Qoal, it is planned to build a trading platform for the whole community of players using item auctions.&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_auctions}}&lt;br /&gt;
{{sqltablerow| auction_id    | INTEGER     | PRIMARY KEY      |                     | unique id of an auction                    }}&lt;br /&gt;
{{sqltablerow| auction_state | INTEGER     | NOT NULL         |                     | current state of the auction               }}&lt;br /&gt;
{{sqltablerow| char_id       | INTEGER     | NOT NULL         | tmw_characters (id) | owner of the auction                       }}&lt;br /&gt;
{{sqltablerow| itemclass_id  | INTEGER     | NOT NULL         | items.xml           | id of the item                             }}&lt;br /&gt;
{{sqltablerow| amount        | INTEGER     | NOT NULL         |                     | amount of items to trade                   }}&lt;br /&gt;
{{sqltablerow| start_time    | INTEGER     | NOT NULL         |                     | date of creation or start of auction       }}&lt;br /&gt;
{{sqltablerow| end_time      | INTEGER     | NOT NULL         |                     | end of auction (unixtimestamp)             }}&lt;br /&gt;
{{sqltablerow| start_price   | INTEGER     | NOT NULL         |                     | minimum price for the first bid            }}&lt;br /&gt;
{{sqltablerow| min_price     | INTEGER     | NULL             |                     | minimum price for the final bid to succeed }}&lt;br /&gt;
{{sqltablerow| buyout_price  | INTEGER     | NULL             |                     | price for direct buy of bidded item        }}&lt;br /&gt;
{{sqltablerow| description   | TEXT        | NULL             |                     | optional description of an auction         }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Annotations ====&lt;br /&gt;
&lt;br /&gt;
* auction_state can have the following values:&lt;br /&gt;
** 0 = The auction is published and ready for bidders&lt;br /&gt;
** 1 = The auction has finished and closed&lt;br /&gt;
* start_time contains the creation date of the auction. Format: Unixtimestamp&lt;br /&gt;
&lt;br /&gt;
==== Bids on Auctions ====&lt;br /&gt;
&lt;br /&gt;
This table stores bids made by characters to a specific auction.&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_auctions}}&lt;br /&gt;
{{sqltablerow| bid_id        | INTEGER     | PRIMARY KEY      |                     | unique id of a bid                         }}&lt;br /&gt;
{{sqltablerow| auction_id    | INTEGER     | NOT NULL         | tmw_auctions        | unique id of an auction                    }}&lt;br /&gt;
{{sqltablerow| char_id       | INTEGER     | NOT NULL         | tmw_characters      | owner of the bid                           }}&lt;br /&gt;
{{sqltablerow| bid_time      | INTEGER     | NOT NULL         |                     | time of the bid, used for sorting bids     }}&lt;br /&gt;
{{sqltablerow| bid_price     | INTEGER     | NOT NULL         |                     | price bidded by the character              }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
===== Annotations =====&lt;br /&gt;
&lt;br /&gt;
* bid_time holds the date and time of the bid as Unixtimestamp. Regarding 2 bids can be placed at the same second, the higher bid_price is relevant. If the bid_price is also equal, the smallest bid_id counts, as this is the record first inserted into the database.&lt;br /&gt;
&lt;br /&gt;
=== Postal system ===&lt;br /&gt;
&lt;br /&gt;
==== Letters ====&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_post}}&lt;br /&gt;
{{sqltablerow| letter_id        | INTEGER | PRIMARY KEY |                | unique id of the letter }} &lt;br /&gt;
{{sqltablerow| sender_id        | INTEGER | NOT NULL    | tmw_characters | sending character of the letter }}&lt;br /&gt;
{{sqltablerow| receiver_id      | INTEGER | NOT NULL    | tmw_characters | receiving character of the letter }}&lt;br /&gt;
{{sqltablerow| letter_type      | INTEGER | NOT NULL    |                | type of the letter (unused atm) }}&lt;br /&gt;
{{sqltablerow| expiration_date  | INTEGER | NOT NULL    |                | date and time of expiration }}&lt;br /&gt;
{{sqltablerow| sending_date     | INTEGER | NOT NULL    |                | date and time of sending }}&lt;br /&gt;
{{sqltablerow| letter_text      | TEXT    |     NULL    |                | text }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Item attachments ====&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_post_attachments}}&lt;br /&gt;
{{sqltablerow| attachment_id | INTEGER | PRIMARY KEY |                    | unique id of the attachment }} &lt;br /&gt;
{{sqltablerow| letter_id     | INTEGER | NOT NULL    | tmw_post           | reference to the letter }}&lt;br /&gt;
{{sqltablerow| item_id       | INTEGER | NOT NULL    | tmw_item_instances | attached itema }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Miscellaneous ===&lt;br /&gt;
&lt;br /&gt;
==== List of online users ====&lt;br /&gt;
&lt;br /&gt;
TMWSERV maintains a list of online users. You can select this table directly to find out who is online, or use the services provided by TMWWEB.&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_online_list}}&lt;br /&gt;
{{sqltablerow| char_id          | INTEGER | PRIMARY KEY | tmw_characters | unique id of the character }} &lt;br /&gt;
{{sqltablerow| login_date       | INTEGER | NOT NULL    | tmw_characters | unixtimestamp of login }}&lt;br /&gt;
{{endsqltable}}&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Upgrade_Database&amp;diff=10863</id>
		<title>Archive:Upgrade Database</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Upgrade_Database&amp;diff=10863"/>
		<updated>2008-12-01T08:11:41Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: /* Determine the database version */ added sqlite&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;From time to time, the database model used by tmwserv will be extended or modified. To prevent inconsistencies between the database model and the account server, the database model has its own version number which has to match the known version of the account server. That means, if you upgrade you database model, you also have to update tmwserv and vice versa.&lt;br /&gt;
&lt;br /&gt;
==== Determine the database version ====&lt;br /&gt;
&lt;br /&gt;
To find out which version your current database is of, try the following SELECT statement, which should work well independent of your database backend.&lt;br /&gt;
&lt;br /&gt;
   SELECT value FROM tmw_world_states WHERE state_name = &#039;database_version&#039;;&lt;br /&gt;
&lt;br /&gt;
This should give you a numeric value which represents your current database version. When using SQLite try the following statement:&lt;br /&gt;
&lt;br /&gt;
   sqlite3 tmw.db &amp;quot;SELECT value FROM tmw_world_states WHERE state_name = &#039;database_version&#039;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
==== How to upgrade my database ====&lt;br /&gt;
&lt;br /&gt;
According to your chosen database backend, you will find a subdirectory called &amp;quot;updates&amp;quot; under &amp;quot;tmwserv/src/sql/&amp;lt;db_backend&amp;gt;&amp;quot;. The update scripts follow a naming scheme like &amp;quot;update_&amp;lt;old_version&amp;gt;_to_&amp;lt;new_version&amp;gt;.sql&amp;quot;. So if your current version is &amp;quot;1&amp;quot; and you want to upgrade to &amp;quot;2&amp;quot;, find the script called &amp;quot;update_1_to_2.sql&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Steps to execute the script depends on your backend. For SQLite just move to the folder where your current database file &amp;quot;tmw.db&amp;quot; lies and type:&lt;br /&gt;
&lt;br /&gt;
  sqlite3 tmw.db &amp;lt; src/sql/sqlite/updates/update_1_to_2.sql&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention: The scripts don&#039;t matter what version you are running, so check it before running a script!&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Upgrade_Database&amp;diff=10850</id>
		<title>Archive:Upgrade Database</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Upgrade_Database&amp;diff=10850"/>
		<updated>2008-11-30T12:25:20Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: describe process of upgrade before next change in the database model&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;From time to time, the database model used by tmwserv will be extended or modified. To prevent inconsistencies between the database model and the account server, the database model has its own version number which has to match the known version of the account server. That means, if you upgrade you database model, you also have to update tmwserv and vice versa.&lt;br /&gt;
&lt;br /&gt;
==== Determine the database version ====&lt;br /&gt;
&lt;br /&gt;
To find out which version your current database is of, try the following SELECT statement, which should work well independent of your database backend.&lt;br /&gt;
&lt;br /&gt;
   SELECT value FROM tmw_world_states WHERE state_name = &#039;database_version&#039;;&lt;br /&gt;
&lt;br /&gt;
This should give you a numeric value which represents your current database version.&lt;br /&gt;
&lt;br /&gt;
==== How to upgrade my database ====&lt;br /&gt;
&lt;br /&gt;
According to your chosen database backend, you will find a subdirectory called &amp;quot;updates&amp;quot; under &amp;quot;tmwserv/src/sql/&amp;lt;db_backend&amp;gt;&amp;quot;. The update scripts follow a naming scheme like &amp;quot;update_&amp;lt;old_version&amp;gt;_to_&amp;lt;new_version&amp;gt;.sql&amp;quot;. So if your current version is &amp;quot;1&amp;quot; and you want to upgrade to &amp;quot;2&amp;quot;, find the script called &amp;quot;update_1_to_2.sql&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Steps to execute the script depends on your backend. For SQLite just move to the folder where your current database file &amp;quot;tmw.db&amp;quot; lies and type:&lt;br /&gt;
&lt;br /&gt;
  sqlite3 tmw.db &amp;lt; src/sql/sqlite/updates/update_1_to_2.sql&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention: The scripts don&#039;t matter what version you are running, so check it before running a script!&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=Development:Developers&amp;diff=10848</id>
		<title>Development:Developers</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=Development:Developers&amp;diff=10848"/>
		<updated>2008-11-30T11:20:18Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: /* Active */ added myself&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Active ==&lt;br /&gt;
{| border=&amp;quot;0&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot; width=&amp;quot;100%&amp;quot; style=&amp;quot;border-bottom: 2px solid #efdead&amp;quot;&lt;br /&gt;
! style=&amp;quot;background:#efdead;&amp;quot; width=&amp;quot;150px&amp;quot; align=&amp;quot;left&amp;quot; | Name&lt;br /&gt;
! style=&amp;quot;background:#efdead;&amp;quot; width=&amp;quot;200px&amp;quot; align=&amp;quot;left&amp;quot; | Occupation&lt;br /&gt;
! style=&amp;quot;background:#efdead;&amp;quot; width=&amp;quot;150px&amp;quot; align=&amp;quot;left&amp;quot; | Location&lt;br /&gt;
&lt;br /&gt;
{{dev2| [[User:Exceptionfault|Andreas Habel (Exceptionfault)]] | Programmer | Germany}}&lt;br /&gt;
{{dev1| [[User:Av3nger|Av3nger]]                 | Pixel art, map creation, translations | Brazil}}&lt;br /&gt;
{{dev2| [[User:Bertram|Bertram]]                 | Programmer | France}}&lt;br /&gt;
{{dev1| [[User:BjÃ¸rn|BjÃ¸rn Lindeijer]]           | Lead Programmer | The Netherlands}}&lt;br /&gt;
{{dev2| [[User:Crush|Philipp Sehmisch (Crush)]]  | Pixel artist, mapper, programmer | Germany}}&lt;br /&gt;
{{dev1| [[User:Dabe|David Del Re (Dabe)]]        | Story and Geography writer | USA}}&lt;br /&gt;
{{dev2| [[User:Doener|Doener]]                   | Programmer | Germany}}&lt;br /&gt;
{{dev1| [[User:ElvenProgrammer|Eugenio Favalli (ElvenProgrammer)]] | Project leader, programmer | Italy}}&lt;br /&gt;
{{dev2| [[User:Silene|Guillaume Melquiond (Silene)]] | Programmer | France}}&lt;br /&gt;
{{dev1| [[User:Jaxad0127|Jared Adams (Jaxad0127)]] | Content Manager Task Force member, mapper, minor programming | USA}}&lt;br /&gt;
{{dev2| [[User:Len|L Pabin (len)]]                         | Pixel artist, concept artist, mapper, and Head of Pixellation| USA}}&lt;br /&gt;
{{dev1| [[User:maci|maci]]                       | User support | Germany}}&lt;br /&gt;
{{dev2| [[User:hackgrid|Matt]]                   | Blabbering idiot | Germany}}&lt;br /&gt;
{{dev1| [[User:Modanung|Modanung]]               | Pixel artist, concept artist | The Netherlands}}&lt;br /&gt;
{{dev2| [[User:Pajarico|Pajarico]]               | Art, writer | Spain}}&lt;br /&gt;
{{dev1| [[User:the-me|Patrick MatthÃ¤i]]          | Debian package maintainer | Germany}}&lt;br /&gt;
{{dev2| [[User:Pauan|Pauan]]                     | Graphics artist (painting, pixel art, interface design, etc.) | USA}}&lt;br /&gt;
{{dev1| [[User:Peavey|Dennis Friis (peavey)]]    | Programmer | Denmark}}&lt;br /&gt;
{{dev2| [[User:Platyna|Platyna]]                 | Slackware package maintainer | Poland}}&lt;br /&gt;
{{dev1| [[User:Avaniel|Rogier Polak (Avaniel)]]  | Programmer | The Netherlands}}&lt;br /&gt;
{{dev2| [[User:Rotonen|Joni Orponen (Rotonen)]]  | Head of art, story and music | Finland}}&lt;br /&gt;
{{dev1| [[User:Trapdoor|trapdoor]]               | Programmer | England}}&lt;br /&gt;
{{dev2| [[User:Tuxtgz|Tuxtgz]]                   | Web-interface Programmer | Germany}}&lt;br /&gt;
{{dev1| [[User:VictorSan|VictorSan]]             | Programmer | Spain}}&lt;br /&gt;
{{dev2| [[User:Yosuhara|Yosuhara]]               | Pixel artist | Slovakia}}&lt;br /&gt;
{{dev1| [[User:Zipon|Zipon]]                     | Mapper | Denmark}}&lt;br /&gt;
{{dev2| [[User:Irukard|Krzysztof Daszuta (Irukard)]]                 | Pixel artist | Poland}}&lt;br /&gt;
{{dev1| [[User:Kage|Chuck Miller (Kage)]]        | Programmer | USA}}&lt;br /&gt;
{{dev2| [[User:Fate|Fate]]                       | Programmer (client, eAthena), Pixel artist | USA }}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Retired ==&lt;br /&gt;
{| border=&amp;quot;0&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot; width=&amp;quot;100%&amp;quot; style=&amp;quot;border-bottom: 2px solid #efdead&amp;quot;&lt;br /&gt;
! style=&amp;quot;background:#efdead;&amp;quot; width=&amp;quot;150px&amp;quot; align=&amp;quot;left&amp;quot; | Name&lt;br /&gt;
! style=&amp;quot;background:#efdead;&amp;quot; width=&amp;quot;200px&amp;quot; align=&amp;quot;left&amp;quot; | Occupation&lt;br /&gt;
! style=&amp;quot;background:#efdead;&amp;quot; width=&amp;quot;150px&amp;quot; align=&amp;quot;left&amp;quot; | Location&lt;br /&gt;
&lt;br /&gt;
{{dev1| [[User:Gagaofdeath|Andrej Sinicyn]]      | Programmer | Germany}}&lt;br /&gt;
{{dev2| [[User:Bear|Bear]]                       | Scripter | USA}}&lt;br /&gt;
{{dev1| [[User:Catfish_Man|Catfish_Man]]         | Mac port | USA}}&lt;br /&gt;
{{dev2| Chetic                                   | Mapper | }}&lt;br /&gt;
{{dev1| [[User:Clef|Clef]]                       | Pixel artist | }}&lt;br /&gt;
{{dev2| [[User:Demon|Demon]]                     | Pixel artist | }}&lt;br /&gt;
{{dev1| [[User:deviexx|deviexx]]                 | Content manager | }}&lt;br /&gt;
{{dev2| [[User:Golgo|Golgo]]                     | Pixel artist | }}&lt;br /&gt;
{{dev1| Gnulia                                   | Concept artist | }}&lt;br /&gt;
{{dev2| Igor Morgado (imorgado)                  | Tester | }}&lt;br /&gt;
{{dev1| [[User:Javila|Javila]]                   | Programmer | Brazil}}&lt;br /&gt;
{{dev2| [[User:JoshLangley|JoshLangley]]         | Client Programmer | Australia}}&lt;br /&gt;
{{dev1| [[User:kindjal|kindjal]]                 | Programmer | France, currently Italy}}&lt;br /&gt;
{{dev2| [[User:Kinetic|Kinetic]]                 | Pixel artist | USA}}&lt;br /&gt;
{{dev1| Alexander Baldeck (kth5/Shura)           | Programmer | }}&lt;br /&gt;
{{dev2| [[User:Kyokai|Kyokai]]                   | Game systems designer | }}&lt;br /&gt;
{{dev1| [[User:Maester Pixel|Maester Pixel]]     | Pixel artist | USA}}&lt;br /&gt;
{{dev2| [[User:Magick|Magick]]                   | Musician | }}&lt;br /&gt;
{{dev1| [[User:Mkael|Mkael]]                     | Concept artist | Finland}}&lt;br /&gt;
{{dev2| [[User:Mra|Mra]]                         | Programmer | Germany}}&lt;br /&gt;
{{dev1| [[User:Neko-mon|Neko-mon]]               | Pixel artist | Brazil}}&lt;br /&gt;
{{dev2| Neorice                                  | Pixel artist | }}&lt;br /&gt;
{{dev1| [[User:Nym|nym]]                         | Programmer | Australia}}&lt;br /&gt;
{{dev2| Rodney Dawes (dobey)                     | Packager (install process) | }}&lt;br /&gt;
{{dev1| Romulo Fernandes (razor85)               | Artist | }}&lt;br /&gt;
{{dev2| Simon Edwardsson (simonedw/simedw)       | Packager (Mac) | }}&lt;br /&gt;
{{dev1| [[User:Sora|Sora]]                       | Pixel artist | Poland}}&lt;br /&gt;
{{dev2| [[User:Sull|Sull]]                       | Pixel artist and hosting | Canada}}&lt;br /&gt;
{{dev1| [[User:Talaroc|Talaroc]]                 | Pixel artist | }}&lt;br /&gt;
{{dev2| Ti Sing Hao                              | Musician | }}&lt;br /&gt;
{{dev1| Ultramichy                               | Hosting | }}&lt;br /&gt;
{{dev2| [[User:Usiu|Mateusz Kaduk (Usiu)]]       | Programmer | Poland}}&lt;br /&gt;
{{dev1| Vlady                                    | Artist | }}&lt;br /&gt;
{{dev2| zenogais (bitshift2002)                  | Programmer | }}&lt;br /&gt;
{{dev1| [[User:Axltrozz|Alex Argumedo (Axltrozz)]]               | Pixel artist | USA, born in El Salvador}}&lt;br /&gt;
{{dev2| Quiche_On_A_leash | Content Management |}}&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=Development:Git_repository&amp;diff=10753</id>
		<title>Development:Git repository</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=Development:Git_repository&amp;diff=10753"/>
		<updated>2008-11-17T08:59:15Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: /* git on Windows */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page provides some information about our switch to git (which, as of Nov 14th, has been completed). As an initial comforting note, git really isn&#039;t so complicated as some people would have you believe. A few months ago I became familiar with distributed version control by using Mercurial, and since a few weeks we&#039;re using git at work. I think we&#039;ll benefit a lot from switching to it on the long run.&lt;br /&gt;
&lt;br /&gt;
== The primary repository ==&lt;br /&gt;
&lt;br /&gt;
=== Initial setup ===&lt;br /&gt;
&lt;br /&gt;
With Git, we&#039;ll have one repository for each project. The central repositories through which we cooperate are hosted on [http://gitorious.org/ gitorious.org]. Gitorious is a friendly website that is also open source. On Gitorious the main repository for each project is called &#039;&#039;mainline&#039;&#039;. Once you click to the mainline repository, you can see several ways to clone it (the new &amp;lt;code&amp;gt;svn checkout&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
We&#039;ve categorized all projects related to The Mana World, so you can easily see the complete [http://gitorious.org/search?q=category%3Athe-mana-world list of The Mana World projects] on Gitorious. The projects have different clone URLs for read-only or developer access. The URL for developer access is called the &amp;quot;push URL&amp;quot;, since it allows you to push commits into the repository via ssh. The list below is for your convenience.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{|border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
! Project&lt;br /&gt;
! Read-only URL&lt;br /&gt;
! Push URL&lt;br /&gt;
! Atom feed&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;[http://gitorious.org/projects/tmw TMW client]&#039;&#039;&#039;&lt;br /&gt;
| git://gitorious.org/tmw/mainline.git&lt;br /&gt;
| git@gitorious.org:tmw/mainline.git&lt;br /&gt;
| [http://gitorious.org/projects/tmw/repos/mainline/logs/master/feed.atom Atom]&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;[http://gitorious.org/projects/tmwdata TMW client data]&#039;&#039;&#039;&lt;br /&gt;
| git://gitorious.org/tmwdata/mainline.git&lt;br /&gt;
| git@gitorious.org:tmwdata/mainline.git&lt;br /&gt;
| [http://gitorious.org/projects/tmwdata/repos/mainline/logs/master/feed.atom Atom]&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;[http://gitorious.org/projects/tmwserv TMW server]&#039;&#039;&#039;&lt;br /&gt;
| git://gitorious.org/tmwserv/mainline.git&lt;br /&gt;
| git@gitorious.org:tmwserv/mainline.git&lt;br /&gt;
| [http://gitorious.org/projects/tmwserv/repos/mainline/logs/master/feed.atom Atom]&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;[http://gitorious.org/projects/tmwweb TMW web frontend]&#039;&#039;&#039;&lt;br /&gt;
| git://gitorious.org/tmwweb/mainline.git&lt;br /&gt;
| git@gitorious.org:tmwweb/mainline.git&lt;br /&gt;
| [http://gitorious.org/projects/tmwweb/repos/mainline/logs/master/feed.atom Atom]&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;[http://gitorious.org/projects/tmw-website TMW website]&#039;&#039;&#039;&lt;br /&gt;
| git://gitorious.org/tmw-website/mainline.git&lt;br /&gt;
| git@gitorious.org:tmw-website/mainline.git&lt;br /&gt;
| [http://gitorious.org/projects/tmw-website/repos/mainline/logs/master/feed.atom Atom]&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;[http://gitorious.org/projects/tmw-eathena eAthena server]&#039;&#039;&#039;&lt;br /&gt;
| git://gitorious.org/tmw-eathena/mainline.git&lt;br /&gt;
| git@gitorious.org:tmw-eathena/mainline.git&lt;br /&gt;
| [http://gitorious.org/projects/tmw-eathena/repos/mainline/logs/master/feed.atom Atom]&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;[http://gitorious.org/projects/tmw-eathena-data eAthena data]&#039;&#039;&#039;&lt;br /&gt;
| git://gitorious.org/tmw-eathena-data/mainline.git&lt;br /&gt;
| git@gitorious.org:tmw-eathena-data/mainline.git&lt;br /&gt;
| [http://gitorious.org/projects/tmw-eathena-data/repos/mainline/logs/master/feed.atom Atom]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Git uses ssh&#039;s private/public key authentication for identifying committers. For development purposes you should clone the &amp;quot;push url&amp;quot;, but this requires that you have:&lt;br /&gt;
&lt;br /&gt;
# Signed up to gitorious.org&lt;br /&gt;
# Generated a private/public ssh keypair (if you haven&#039;t got this already)&lt;br /&gt;
# Filled in your public key in your account details on Gitorious&lt;br /&gt;
&lt;br /&gt;
=== Cloning ===&lt;br /&gt;
&lt;br /&gt;
If you simply &amp;lt;code&amp;gt;git clone&amp;lt;/code&amp;gt; the URL without any additional arguments, it will create the repository in a directory called &amp;quot;mainline&amp;quot;. This is generally not what you want. Hence, after the clone url, you should pass the name of the directory you want to have created (just like with Subversion):&lt;br /&gt;
&lt;br /&gt;
 $ git clone &amp;lt;clone_url&amp;gt; project&lt;br /&gt;
&lt;br /&gt;
If you want to have all projects in one place, you probably want to do something like this:&lt;br /&gt;
&lt;br /&gt;
 $ mkdir tmw&lt;br /&gt;
 $ cd tmw&lt;br /&gt;
 $ git clone git@gitorious.org:tmwserv/mainline.git tmwserv&lt;br /&gt;
 $ git clone git@gitorious.org:tmw-eathena-data/mainline.git eathena-data&lt;br /&gt;
 etc.&lt;br /&gt;
 or for all of them in one go (after the cd tmw step):&lt;br /&gt;
 $ for repo in  tmw tmwdata tmwserv tmwweb tmw-website tmw-eathena tmw-eathena-data ; do git clone git://gitorious.org/${repo}/mainline.git $repo  ; done&lt;br /&gt;
&lt;br /&gt;
The way Gitorious works, we can&#039;t have one top-level &amp;quot;tmw&amp;quot; project under which we put all these repositories, since they&#039;re really separate projects. Gitorious allows multiple repositories for each project, but they are clones of each other (you can only create new ones by cloning existing ones). This allows anybody (not just the development team) to make clones and start hacking on them. Changes can easily be merged from one one repository to another. So instead of all the inconvenience with TMW forks we had in the past, now comes the time to encourage people to clone!&lt;br /&gt;
&lt;br /&gt;
=== The TMW 0.0.x client ===&lt;br /&gt;
&lt;br /&gt;
The 0.0 client may seem a bit hidden, but it exists as a branch just like with Subversion. To continue working on this client you need to checkout the branch and create your own local branch to work on it. This goes as follows:&lt;br /&gt;
&lt;br /&gt;
 $ git clone git@gitorious.org:tmw/mainline.git tmw&lt;br /&gt;
 $ cd tmw&lt;br /&gt;
 $ git checkout -b 0.0 origin/0.0&lt;br /&gt;
&lt;br /&gt;
With the last command, a new local branch called 0.0 is created. Since it was based on the 0.0 branch in origin (the repository on Gitorious), it will automatically track this remote branch. This means that when you do &amp;lt;code&amp;gt;git pull&amp;lt;/code&amp;gt;, git will attempt to automatically merge the latest changes available from this branch with your local 0.0 branch.&lt;br /&gt;
&lt;br /&gt;
== Working with git ==&lt;br /&gt;
&lt;br /&gt;
=== Commit ===&lt;br /&gt;
&lt;br /&gt;
From now on, a commit is something you do locally. Others won&#039;t see your change on Gitorious unless you push it there. You&#039;ll notice committing is very fast, and you can commit multiple times before you decide to push. You can also make corrections to your last commit.&lt;br /&gt;
&lt;br /&gt;
Before you start committing, it is important to identify yourself to git, so that it can include the correct authorship information with your commit. You are no longer identified with a username, as was the case with Subversion. You can read exactly how to do this, as well as other useful information geared towards people switching from Subversion, on this page:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Git - SVN Crash Course:&#039;&#039;&#039; http://git.or.cz/course/svn.html&lt;br /&gt;
&lt;br /&gt;
=== Pushing ===&lt;br /&gt;
&lt;br /&gt;
Once you have committed some stuff, you can push these to the repository on Gitorious using &amp;lt;code&amp;gt;git push&amp;lt;/code&amp;gt;. This works since by default the push command pushes to a &#039;&#039;remote&#039;&#039; called &#039;&#039;origin&#039;&#039;, and this remote is automatically set up when you clone. However, the push will fail if there have been new commits on the remote repository. In that case, you&#039;ll first have to pull in these changes (just like with Subversion, however Subversion allowed this as long as the same files weren&#039;t touched, git doesn&#039;t).&lt;br /&gt;
&lt;br /&gt;
=== Pulling ===&lt;br /&gt;
&lt;br /&gt;
When you want to get the latest changes from the repository on Gitorious, you generally use &amp;lt;code&amp;gt;git pull&amp;lt;/code&amp;gt;. However, note that this command does not work when you have local changes. Also, when you have local commits, the pull command will generate a merge commit (and before that you may have to resolve some conflicts).&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t want to create merge commits, but would rather stack your local commits on top of any incoming commits, you should use &amp;lt;code&amp;gt;git pull --rebase&amp;lt;/code&amp;gt;. This &#039;&#039;rebases&#039;&#039; your local commits on top of the incoming ones. You should never do this when you have pushed these commits elsewhere, so only do it when you are sure the commits are only on your machine.&lt;br /&gt;
&lt;br /&gt;
If you have local changes and want to update your checkout, then there are several options:&lt;br /&gt;
&lt;br /&gt;
* You commit your local changes, and do a pull, optionally with --rebase.&lt;br /&gt;
* Or you use &amp;lt;code&amp;gt;git stash&amp;lt;/code&amp;gt; to place your local changes on a &amp;quot;hidden&amp;quot; stash. Then, after pulling, you apply your changes again with &amp;lt;code&amp;gt;git stash apply&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Or you create a patch of your local changes that you apply again after the pull. This approach sometimes makes sense, but I would say in general it&#039;s the more clumsy way to go. There are git commands that help you with this though.&lt;br /&gt;
&lt;br /&gt;
=== Resolving conflicts ===&lt;br /&gt;
&lt;br /&gt;
Rather similar to Subversion. When there are conflicts, a merge or a rebase will add conflict markers into files. Use &amp;lt;code&amp;gt;git status&amp;lt;/code&amp;gt; to see which files remain in conflict and use &amp;lt;code&amp;gt;git add&amp;lt;/code&amp;gt; on files to mark them as resolved. When you did a merge and you have resolved all conflicts, you commit. When you were doing a rebase of several commits, you do &amp;lt;code&amp;gt;git rebase --continue&amp;lt;/code&amp;gt; instead.&lt;br /&gt;
&lt;br /&gt;
=== Good to know ===&lt;br /&gt;
&lt;br /&gt;
Git has several useful commands to figure out the current state of your repository, your files and what recently changed. Below is a non-exhaustive list of commands that are useful to know:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;git branch&#039;&#039;&#039;: Without any parameters, this command should you your local branches, and indicates which branch you&#039;re currently on.&lt;br /&gt;
* &#039;&#039;&#039;git whatchanged&#039;&#039;&#039;: This shows something similar to the ChangeLog file. Recent commits on your current branch with a list of the files the touched.&lt;br /&gt;
* &#039;&#039;&#039;git status&#039;&#039;&#039;: This shows all kind of things about your current checkout: which files changed, untracked (unknown) files, added or removed files, files that have conflicts (during merge), etc. It also shows the status of your index, which is what git will commit once you do &amp;lt;code&amp;gt;git commit&amp;lt;/code&amp;gt;. If you&#039;re new to git I would recommend to wait a bit with learning how to use the index, but not to avoid it forever.&lt;br /&gt;
&lt;br /&gt;
There are also additional applications that help you with using git:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;gitk&#039;&#039;&#039;: A simple but effective tool that visualizes the history and some of your current state. Run with &amp;lt;code&amp;gt;--all&amp;lt;/code&amp;gt; to have it show all branches, otherwise it will just show stuff relevant to your current branch.&lt;br /&gt;
* &#039;&#039;&#039;tig&#039;&#039;&#039;: A textual interface, rather similar to an email reader.&lt;br /&gt;
* &#039;&#039;&#039;git gui&#039;&#039;&#039;: A gui tool like gitk which helps you prepare and perform your commits. Also makes it easier to understand the index concept.&lt;br /&gt;
&lt;br /&gt;
=== git on Windows ===&lt;br /&gt;
&lt;br /&gt;
When using git on Windows you might use [http://code.google.com/p/msysgit/ msysgit]. If you notice, that all files seem to have changed after doing a fresh clone, this discussion should help you: [http://code.google.com/p/msysgit/issues/detail?id=83]. Find your global git configuration file, normally somewhere under c:\programs\git\etc\gitconfig, and set the parameter &#039;&#039;autocrlf&#039;&#039; in the &#039;&#039;core&#039;&#039; section to &#039;&#039;false&#039;&#039;. Then remove you last clone and do a nwe fresh clone.&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=Development:Git_repository&amp;diff=10752</id>
		<title>Development:Git repository</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=Development:Git_repository&amp;diff=10752"/>
		<updated>2008-11-17T08:56:58Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: added lineending issue under msysgit&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page provides some information about our switch to git (which, as of Nov 14th, has been completed). As an initial comforting note, git really isn&#039;t so complicated as some people would have you believe. A few months ago I became familiar with distributed version control by using Mercurial, and since a few weeks we&#039;re using git at work. I think we&#039;ll benefit a lot from switching to it on the long run.&lt;br /&gt;
&lt;br /&gt;
== The primary repository ==&lt;br /&gt;
&lt;br /&gt;
=== Initial setup ===&lt;br /&gt;
&lt;br /&gt;
With Git, we&#039;ll have one repository for each project. The central repositories through which we cooperate are hosted on [http://gitorious.org/ gitorious.org]. Gitorious is a friendly website that is also open source. On Gitorious the main repository for each project is called &#039;&#039;mainline&#039;&#039;. Once you click to the mainline repository, you can see several ways to clone it (the new &amp;lt;code&amp;gt;svn checkout&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
We&#039;ve categorized all projects related to The Mana World, so you can easily see the complete [http://gitorious.org/search?q=category%3Athe-mana-world list of The Mana World projects] on Gitorious. The projects have different clone URLs for read-only or developer access. The URL for developer access is called the &amp;quot;push URL&amp;quot;, since it allows you to push commits into the repository via ssh. The list below is for your convenience.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{|border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
! Project&lt;br /&gt;
! Read-only URL&lt;br /&gt;
! Push URL&lt;br /&gt;
! Atom feed&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;[http://gitorious.org/projects/tmw TMW client]&#039;&#039;&#039;&lt;br /&gt;
| git://gitorious.org/tmw/mainline.git&lt;br /&gt;
| git@gitorious.org:tmw/mainline.git&lt;br /&gt;
| [http://gitorious.org/projects/tmw/repos/mainline/logs/master/feed.atom Atom]&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;[http://gitorious.org/projects/tmwdata TMW client data]&#039;&#039;&#039;&lt;br /&gt;
| git://gitorious.org/tmwdata/mainline.git&lt;br /&gt;
| git@gitorious.org:tmwdata/mainline.git&lt;br /&gt;
| [http://gitorious.org/projects/tmwdata/repos/mainline/logs/master/feed.atom Atom]&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;[http://gitorious.org/projects/tmwserv TMW server]&#039;&#039;&#039;&lt;br /&gt;
| git://gitorious.org/tmwserv/mainline.git&lt;br /&gt;
| git@gitorious.org:tmwserv/mainline.git&lt;br /&gt;
| [http://gitorious.org/projects/tmwserv/repos/mainline/logs/master/feed.atom Atom]&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;[http://gitorious.org/projects/tmwweb TMW web frontend]&#039;&#039;&#039;&lt;br /&gt;
| git://gitorious.org/tmwweb/mainline.git&lt;br /&gt;
| git@gitorious.org:tmwweb/mainline.git&lt;br /&gt;
| [http://gitorious.org/projects/tmwweb/repos/mainline/logs/master/feed.atom Atom]&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;[http://gitorious.org/projects/tmw-website TMW website]&#039;&#039;&#039;&lt;br /&gt;
| git://gitorious.org/tmw-website/mainline.git&lt;br /&gt;
| git@gitorious.org:tmw-website/mainline.git&lt;br /&gt;
| [http://gitorious.org/projects/tmw-website/repos/mainline/logs/master/feed.atom Atom]&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;[http://gitorious.org/projects/tmw-eathena eAthena server]&#039;&#039;&#039;&lt;br /&gt;
| git://gitorious.org/tmw-eathena/mainline.git&lt;br /&gt;
| git@gitorious.org:tmw-eathena/mainline.git&lt;br /&gt;
| [http://gitorious.org/projects/tmw-eathena/repos/mainline/logs/master/feed.atom Atom]&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;[http://gitorious.org/projects/tmw-eathena-data eAthena data]&#039;&#039;&#039;&lt;br /&gt;
| git://gitorious.org/tmw-eathena-data/mainline.git&lt;br /&gt;
| git@gitorious.org:tmw-eathena-data/mainline.git&lt;br /&gt;
| [http://gitorious.org/projects/tmw-eathena-data/repos/mainline/logs/master/feed.atom Atom]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Git uses ssh&#039;s private/public key authentication for identifying committers. For development purposes you should clone the &amp;quot;push url&amp;quot;, but this requires that you have:&lt;br /&gt;
&lt;br /&gt;
# Signed up to gitorious.org&lt;br /&gt;
# Generated a private/public ssh keypair (if you haven&#039;t got this already)&lt;br /&gt;
# Filled in your public key in your account details on Gitorious&lt;br /&gt;
&lt;br /&gt;
=== Cloning ===&lt;br /&gt;
&lt;br /&gt;
If you simply &amp;lt;code&amp;gt;git clone&amp;lt;/code&amp;gt; the URL without any additional arguments, it will create the repository in a directory called &amp;quot;mainline&amp;quot;. This is generally not what you want. Hence, after the clone url, you should pass the name of the directory you want to have created (just like with Subversion):&lt;br /&gt;
&lt;br /&gt;
 $ git clone &amp;lt;clone_url&amp;gt; project&lt;br /&gt;
&lt;br /&gt;
If you want to have all projects in one place, you probably want to do something like this:&lt;br /&gt;
&lt;br /&gt;
 $ mkdir tmw&lt;br /&gt;
 $ cd tmw&lt;br /&gt;
 $ git clone git@gitorious.org:tmwserv/mainline.git tmwserv&lt;br /&gt;
 $ git clone git@gitorious.org:tmw-eathena-data/mainline.git eathena-data&lt;br /&gt;
 etc.&lt;br /&gt;
 or for all of them in one go (after the cd tmw step):&lt;br /&gt;
 $ for repo in  tmw tmwdata tmwserv tmwweb tmw-website tmw-eathena tmw-eathena-data ; do git clone git://gitorious.org/${repo}/mainline.git $repo  ; done&lt;br /&gt;
&lt;br /&gt;
The way Gitorious works, we can&#039;t have one top-level &amp;quot;tmw&amp;quot; project under which we put all these repositories, since they&#039;re really separate projects. Gitorious allows multiple repositories for each project, but they are clones of each other (you can only create new ones by cloning existing ones). This allows anybody (not just the development team) to make clones and start hacking on them. Changes can easily be merged from one one repository to another. So instead of all the inconvenience with TMW forks we had in the past, now comes the time to encourage people to clone!&lt;br /&gt;
&lt;br /&gt;
=== The TMW 0.0.x client ===&lt;br /&gt;
&lt;br /&gt;
The 0.0 client may seem a bit hidden, but it exists as a branch just like with Subversion. To continue working on this client you need to checkout the branch and create your own local branch to work on it. This goes as follows:&lt;br /&gt;
&lt;br /&gt;
 $ git clone git@gitorious.org:tmw/mainline.git tmw&lt;br /&gt;
 $ cd tmw&lt;br /&gt;
 $ git checkout -b 0.0 origin/0.0&lt;br /&gt;
&lt;br /&gt;
With the last command, a new local branch called 0.0 is created. Since it was based on the 0.0 branch in origin (the repository on Gitorious), it will automatically track this remote branch. This means that when you do &amp;lt;code&amp;gt;git pull&amp;lt;/code&amp;gt;, git will attempt to automatically merge the latest changes available from this branch with your local 0.0 branch.&lt;br /&gt;
&lt;br /&gt;
== Working with git ==&lt;br /&gt;
&lt;br /&gt;
=== Commit ===&lt;br /&gt;
&lt;br /&gt;
From now on, a commit is something you do locally. Others won&#039;t see your change on Gitorious unless you push it there. You&#039;ll notice committing is very fast, and you can commit multiple times before you decide to push. You can also make corrections to your last commit.&lt;br /&gt;
&lt;br /&gt;
Before you start committing, it is important to identify yourself to git, so that it can include the correct authorship information with your commit. You are no longer identified with a username, as was the case with Subversion. You can read exactly how to do this, as well as other useful information geared towards people switching from Subversion, on this page:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Git - SVN Crash Course:&#039;&#039;&#039; http://git.or.cz/course/svn.html&lt;br /&gt;
&lt;br /&gt;
=== Pushing ===&lt;br /&gt;
&lt;br /&gt;
Once you have committed some stuff, you can push these to the repository on Gitorious using &amp;lt;code&amp;gt;git push&amp;lt;/code&amp;gt;. This works since by default the push command pushes to a &#039;&#039;remote&#039;&#039; called &#039;&#039;origin&#039;&#039;, and this remote is automatically set up when you clone. However, the push will fail if there have been new commits on the remote repository. In that case, you&#039;ll first have to pull in these changes (just like with Subversion, however Subversion allowed this as long as the same files weren&#039;t touched, git doesn&#039;t).&lt;br /&gt;
&lt;br /&gt;
=== Pulling ===&lt;br /&gt;
&lt;br /&gt;
When you want to get the latest changes from the repository on Gitorious, you generally use &amp;lt;code&amp;gt;git pull&amp;lt;/code&amp;gt;. However, note that this command does not work when you have local changes. Also, when you have local commits, the pull command will generate a merge commit (and before that you may have to resolve some conflicts).&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t want to create merge commits, but would rather stack your local commits on top of any incoming commits, you should use &amp;lt;code&amp;gt;git pull --rebase&amp;lt;/code&amp;gt;. This &#039;&#039;rebases&#039;&#039; your local commits on top of the incoming ones. You should never do this when you have pushed these commits elsewhere, so only do it when you are sure the commits are only on your machine.&lt;br /&gt;
&lt;br /&gt;
If you have local changes and want to update your checkout, then there are several options:&lt;br /&gt;
&lt;br /&gt;
* You commit your local changes, and do a pull, optionally with --rebase.&lt;br /&gt;
* Or you use &amp;lt;code&amp;gt;git stash&amp;lt;/code&amp;gt; to place your local changes on a &amp;quot;hidden&amp;quot; stash. Then, after pulling, you apply your changes again with &amp;lt;code&amp;gt;git stash apply&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Or you create a patch of your local changes that you apply again after the pull. This approach sometimes makes sense, but I would say in general it&#039;s the more clumsy way to go. There are git commands that help you with this though.&lt;br /&gt;
&lt;br /&gt;
=== Resolving conflicts ===&lt;br /&gt;
&lt;br /&gt;
Rather similar to Subversion. When there are conflicts, a merge or a rebase will add conflict markers into files. Use &amp;lt;code&amp;gt;git status&amp;lt;/code&amp;gt; to see which files remain in conflict and use &amp;lt;code&amp;gt;git add&amp;lt;/code&amp;gt; on files to mark them as resolved. When you did a merge and you have resolved all conflicts, you commit. When you were doing a rebase of several commits, you do &amp;lt;code&amp;gt;git rebase --continue&amp;lt;/code&amp;gt; instead.&lt;br /&gt;
&lt;br /&gt;
=== Good to know ===&lt;br /&gt;
&lt;br /&gt;
Git has several useful commands to figure out the current state of your repository, your files and what recently changed. Below is a non-exhaustive list of commands that are useful to know:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;git branch&#039;&#039;&#039;: Without any parameters, this command should you your local branches, and indicates which branch you&#039;re currently on.&lt;br /&gt;
* &#039;&#039;&#039;git whatchanged&#039;&#039;&#039;: This shows something similar to the ChangeLog file. Recent commits on your current branch with a list of the files the touched.&lt;br /&gt;
* &#039;&#039;&#039;git status&#039;&#039;&#039;: This shows all kind of things about your current checkout: which files changed, untracked (unknown) files, added or removed files, files that have conflicts (during merge), etc. It also shows the status of your index, which is what git will commit once you do &amp;lt;code&amp;gt;git commit&amp;lt;/code&amp;gt;. If you&#039;re new to git I would recommend to wait a bit with learning how to use the index, but not to avoid it forever.&lt;br /&gt;
&lt;br /&gt;
There are also additional applications that help you with using git:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;gitk&#039;&#039;&#039;: A simple but effective tool that visualizes the history and some of your current state. Run with &amp;lt;code&amp;gt;--all&amp;lt;/code&amp;gt; to have it show all branches, otherwise it will just show stuff relevant to your current branch.&lt;br /&gt;
* &#039;&#039;&#039;tig&#039;&#039;&#039;: A textual interface, rather similar to an email reader.&lt;br /&gt;
* &#039;&#039;&#039;git gui&#039;&#039;&#039;: A gui tool like gitk which helps you prepare and perform your commits. Also makes it easier to understand the index concept.&lt;br /&gt;
&lt;br /&gt;
=== git on Windows ===&lt;br /&gt;
&lt;br /&gt;
When using git on Windows you might use [http://code.google.com/p/msysgit/ msysgit]. If you notice, that all files seem to have changed after doing a fresh clone, this discussion should help you: [http://code.google.com/p/msysgit/issues/detail?id=83]. Find your global git configuration file, normally somewhere under c:\programs\git\etc\gitconfig, and set the parameter &#039;&#039;autocrlf&#039;&#039; in the &#039;&#039;core&#039;&#039; section to &#039;&#039;false&#039;&#039;.&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Database_specifications&amp;diff=10611</id>
		<title>Archive:Database specifications</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Database_specifications&amp;diff=10611"/>
		<updated>2008-11-07T07:07:16Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: Updated graphical model, added postal system tables&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Category_programming}}&lt;br /&gt;
&lt;br /&gt;
== SQL table specifications ==&lt;br /&gt;
&lt;br /&gt;
[[Image:Database specification proposal.png|thumb|200px|The current database model.]]&lt;br /&gt;
&lt;br /&gt;
=== User accounts ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_accounts}}&lt;br /&gt;
{{sqltablerow| id            | INTEGER     | PRIMARY KEY      | | unique id of an account}}                      }}&lt;br /&gt;
{{sqltablerow|username       | TEXT        | NOT NULL UNIQUE  | | username / loginname of an user                }}&lt;br /&gt;
{{sqltablerow|password       | TEXT        | NOT NULL         | | password of an user (sha256 encoded)           }}&lt;br /&gt;
{{sqltablerow|email          | TEXT        | NOT NULL         | | email (sha256 encoded, only for pwd recovery)  }}&lt;br /&gt;
{{sqltablerow|level          | INTEGER     | NOT NULL         | | numeric level of the user account              }}&lt;br /&gt;
{{sqltablerow|banned         | INTEGER     | NOT NULL         | | unixtimestamp until when the account is banned }}&lt;br /&gt;
{{sqltablerow|registration   | INTEGER     | NOT NULL         | | unixtimestamp of account registration          }}&lt;br /&gt;
{{sqltablerow|lastlogin      | INTEGER     | NOT NULL         | | unixtimestamp of last login with client        }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Details ====&lt;br /&gt;
* email&lt;br /&gt;
** The email is stored as a one-way sha256 hash value. This ensures, that the email address a user enters cannot be used to send spam mails. It is only used to validate the mailaddress during password recovery procedure.&lt;br /&gt;
* level&lt;br /&gt;
** describes the user rights in the game (10 = normal user, 50 = gm, 99 = administrator)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Characters ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_characters}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY      |                 | unique id of the character                              }}&lt;br /&gt;
{{sqltablerow|user_id        | INTEGER     | NOT NULL         | tmw_accounts.id | id of the owner                                         }}&lt;br /&gt;
{{sqltablerow|name           | TEXT        | NOT NULL UNIQUE  |                 | name of the character                                   }}&lt;br /&gt;
{{sqltablerow|gender         | INTEGER     | NOT NULL         |                 | gender of the character (0/1)                           }}&lt;br /&gt;
{{sqltablerow|hair_style     | INTEGER     | NOT NULL         |                 | id of the hair sprite                                   }}&lt;br /&gt;
{{sqltablerow|hair_color     | INTEGER     | NOT NULL         |                 | id of the hair color                                    }}&lt;br /&gt;
{{sqltablerow|level          | INTEGER     | NOT NULL         |                 | experience level of the character                       }}&lt;br /&gt;
{{sqltablerow|char_pts       | INTEGER     | NOT NULL         |                 | available points to raise attributes                    }}&lt;br /&gt;
{{sqltablerow|correct_pts    | INTEGER     | NOT NULL         |                 | available points to lower attributes and regain char_pts}}&lt;br /&gt;
{{sqltablerow|money          | INTEGER     | NOT NULL         |                 | GP of the character                                     }}&lt;br /&gt;
{{sqltablerow|x              | INTEGER     | NOT NULL         |                 | x position of the character on the map                  }}&lt;br /&gt;
{{sqltablerow|y              | INTEGER     | NOT NULL         |                 | y position of the character on the map                  }}&lt;br /&gt;
{{sqltablerow|map_id         | INTEGER     | NOT NULL         | tmw_maps.id     | id of the current map the character is located          }}&lt;br /&gt;
{{sqltablerow|str            | INTEGER     | NOT NULL         |                 | strength of the character                               }}&lt;br /&gt;
{{sqltablerow|agi            | INTEGER     | NOT NULL         |                 | agility of the character                                }}&lt;br /&gt;
{{sqltablerow|dex            | INTEGER     | NOT NULL         |                 | dexternity of the character                             }}&lt;br /&gt;
{{sqltablerow|vit            | INTEGER     | NOT NULL         |                 | vitality of the character                               }}&lt;br /&gt;
{{sqltablerow|int            | INTEGER     | NOT NULL         |                 | intelligence of the character                           }}&lt;br /&gt;
{{sqltablerow|will           | INTEGER     | NOT NULL         |                 | willpower of the character                              }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Concerns ====&lt;br /&gt;
&lt;br /&gt;
* The way experience is part of this table really won&#039;t scale and isn&#039;t flexible in any way. It&#039;s currently already way too many variables in one table row, and these are just the weapon skills. So I think we should really have a separate table for storing skill levels similar to the character inventory table below. So something that has { character_id, skill_id, experience }. The &amp;lt;code&amp;gt;skill_id&amp;lt;/code&amp;gt; should point to a &amp;lt;code&amp;gt;skills.xml&amp;lt;/code&amp;gt; file which describes (and categorizes) each skill. In that way we&#039;ll be able to easily change the set of skills and their names later. --[[User:BjÃ¸rn|BjÃ¸rn]] 18:09, 12 September 2008 (CEST)&lt;br /&gt;
** I think the same should be done with the attributes (str .. will). In theory almost every attribute in this table could be handled that way, it might look like a mess, but would be really friendly in customizing the gameplay elements. --[[User:Kess|kess]] 19:54, 12 September 2008 (CEST)&lt;br /&gt;
** I agree with that completely as this will give us more flexibility and a much more relational database design. I&#039;ve extended the &amp;quot;DAL improvements&amp;quot; task in mantis: #424 --[[User:Exceptionfault|Exceptionfault]] 15:50, 14 September 2008 (CEST)&lt;br /&gt;
*** Thanks for taking out the skills from this table. However, I disagree about generalizing stuff on the level of attributes, unless there would be any plan of putting infrastructure in place to make this possible. For now we can&#039;t even finish a server for The Mana World within years, so please don&#039;t try to build a server that supports any online RPG just yet. I only suggested we take out the skills because it would be completely unmanageable as part of this table, but the list of attribute is not expected to change for now. --[[User:BjÃ¸rn|BjÃ¸rn]] 15:55, 22 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
=== Character attributes ===&lt;br /&gt;
&lt;br /&gt;
This table is intended to store skills and experiences of each character. &lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_char_skills}}&lt;br /&gt;
{{sqltablerow|char_id         | INTEGER     | NOT NULL | tmw_characters.id | reference to the character                    }}&lt;br /&gt;
{{sqltablerow|skill_id        | INTEGER     | NOT NULL | (skills.xml)      | reference to the skill                        }}&lt;br /&gt;
{{sqltablerow|exp             | INTEGER     | NOT NULL |                   | current experience of the char in this skill  }} &lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Concerns ====&lt;br /&gt;
&lt;br /&gt;
* I&#039;m not sure, if an INTEGER does the job for column exp? --[[User:Exceptionfault|Exceptionfault]] 14:40, 19 September 2008 (CEST)&lt;br /&gt;
** What is the range? I would expect it to be enough. --[[User:BjÃ¸rn|BjÃ¸rn]] 15:56, 22 September 2008 (CEST)&lt;br /&gt;
*** Hereâ€™s some basic info:&lt;br /&gt;
***: &#039;&#039;&#039;MySQL:&#039;&#039;&#039; INTEGER (INT) may be signed or unsigned and is 4 bytes large, MySQL also have 1, 2, 3 and 8 byte integer variants (TINYINT, SMALLINT, MEDIUMINT and BIGINT) [http://dev.mysql.com/doc/refman/6.0/en/numeric-types.html]&lt;br /&gt;
***: &#039;&#039;&#039;PostgreSQL:&#039;&#039;&#039; INTEGER (INT, INT4) is signed and 4 bytes large, PostgreSQL also have 2 and 8 byte integer variants (SMALLINT and BIGINT) [http://www.postgresql.org/docs/8.3/interactive/datatype-numeric.html]&lt;br /&gt;
***: &#039;&#039;&#039;SQLite:&#039;&#039;&#039; INTEGER is signed and size is either 1, 2, 3, 4, 6 or 8 bytes depending on the size of the value [http://sqlite.org/datatype3.html]&lt;br /&gt;
***: So, the largest integer type supported should be of 8 byte size (signed): from -9,223,372,036,854,775,808 to +9,223,372,036,854,775,807, while the â€œstandardâ€ (of the SQL variants above) signed 4 byte integer ranges from -2,147,483,648 to +2,147,483,647. --[[User:Kess|kess]] 21:18, 22 September 2008 (CEST)&lt;br /&gt;
*** Although we plan to have no fixed level cap I considered a skill level of about 100 to be the highest reasonable value a player can archieve. Level 100 requires an exp sum of 10 million with the current exp formula (levelÂ³ * 10) which fits into a 4 byte integer easily. We won&#039;t get in trouble with 32bit signed integers until the players get near skill level 600 (2.16 billion). The server and the netcode also use 32 bit integers internally.&lt;br /&gt;
&lt;br /&gt;
=== Character Inventory ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_inventories}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY      |                   | unique id of the item                          }}&lt;br /&gt;
{{sqltablerow|owner_id       | INTEGER     | NOT NULL         | tmw_characters.id | id of the owning character                     }}&lt;br /&gt;
{{sqltablerow|slot           | INTEGER     | NOT NULL         |                   | inventory slot where the item is equipped      }}&lt;br /&gt;
{{sqltablerow|class_id       | INTEGER     | NOT NULL         |                   | type of the item, see items.xml file of tmwserv}}&lt;br /&gt;
{{sqltablerow|amount         | INTEGER     | NOT NULL         |                   | amount of items per slot                       }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Comments ====&lt;br /&gt;
* While I havenâ€™t looked how this table is used (my C++ knowledge is rather basic) it seems quite rigid and unflexible (as BjÃ¸rn noted above for the &#039;&#039;&#039;tmw_characters&#039;&#039;&#039; table). I think it would be nicer to have something like {&#039;&#039;owner_id&#039;&#039; FK, &#039;&#039;slot&#039;&#039;, &#039;&#039;item_id&#039;&#039; FK, &#039;&#039;amount&#039;&#039;, PK owner_id + slot}, where class_id shouldnâ€™t directly be needed in this table. --[[User:Kess|kess]] 19:49, 12 September 2008 (CEST)&lt;br /&gt;
* Concerning new features like houses, bank accounts, chests or similar, i think the design of this table needs some more roundtrips. You will need a column which indicates if the item is carried by the character or stored in a chest or in a house; as it makes no sense to have a table for every possible storage type or location. Another point is, that items should be more individualizable (is this a real word? :)). Think about custom colored shirts. So we will need at least one additional table to store individual attributes of items. --[[User:Exceptionfault|Exceptionfault]] 16:02, 14 September 2008 (CEST)&lt;br /&gt;
** We want all equipment to be completely individual with completely unique stats. --[[User:Crush2|Crush2]] 16:13, 14 September 2008 (CEST)&lt;br /&gt;
*** Good to know, so I will extend the DAL improvement task in mantis. --[[User:Exceptionfault|Exceptionfault]] 16:20, 14 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
=== Guilds ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_guilds}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY     |  | unique id of the guid   }}&lt;br /&gt;
{{sqltablerow|name           | TEXT        | NOT NULL UNIQUE |  | unique name of the guild}}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Guild memberships ===&lt;br /&gt;
&lt;br /&gt;
The table &#039;&#039;tmw_guild_members&#039;&#039; stores informations which character is member in which guild and which rights does he has.&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_guild_members}}&lt;br /&gt;
{{sqltablerow|guild_id        | INTEGER     | NOT NULL | tmw_guilds.id     | reference to the guild                                                }}&lt;br /&gt;
{{sqltablerow|member_id       | INTEGER     | NOT NULL | tmw_characters.id | reference to the characters                                           }}&lt;br /&gt;
{{sqltablerow|rights          | INTEGER     | NOT NULL |                   | id showing the rights a character has in this guild (member, admin...)}}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== World state ===&lt;br /&gt;
&lt;br /&gt;
The table &#039;&#039;tmw_world_state&#039;&#039; is used to store persistent informations about the world or individual maps.&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_world_state}}&lt;br /&gt;
{{sqltablerow| state_name      | TEXT     | PRIMARY KEY |             | unique name of a state variable        }} &lt;br /&gt;
{{sqltablerow| map_id          | INTEGER  | NULL        | tmw_maps.id | reference to a map, see details        }}&lt;br /&gt;
{{sqltablerow| value           | TEXT     | NULL        |             | string value of the state              }}&lt;br /&gt;
{{sqltablerow| moddate         | INTEGER  | NOT NULL    |             | date and time of the last modification }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Details ====&lt;br /&gt;
&lt;br /&gt;
* The column &#039;&#039;state_name&#039;&#039; forms the primary key of the table. If &#039;&#039;map_id&#039;&#039; is null, the variable is used globally in the world, otherwise the variable is specific for a map.&lt;br /&gt;
* &#039;&#039;moddate&#039;&#039; is for informational use only as it contains the unixtimestamp of the last modification.&lt;br /&gt;
&lt;br /&gt;
==== Comments ====&lt;br /&gt;
&lt;br /&gt;
* It seems that SQLite doesn&#039;t support composite primary keys (span PK over multiple columns). Therefore it is not possible to allow multiple &#039;&#039;state_name&#039;&#039;s with different &#039;&#039;map_id&#039;&#039;s. So we set a &#039;&#039;state_name&#039;&#039; to unique and use &#039;&#039;map_id&#039;&#039; as notifier if this variable is globally used or just locally for a specific map. --[[User:Exceptionfault|Exceptionfault]] 11:05, 15 September 2008 (CEST)&lt;br /&gt;
** This table is ready for usage, commited as rev. 4629 --[[User:Exceptionfault|Exceptionfault]] 13:51, 15 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Quest states ===&lt;br /&gt;
&lt;br /&gt;
This table is used to store states of quests per character, e.g. if a character has just finished a quest or is currently at the second part of the long journey...&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_quests}}&lt;br /&gt;
{{sqltablerow|owner_id        | INTEGER     | NOT NULL | tmw_characters.id | reference to the character         }}&lt;br /&gt;
{{sqltablerow|name            | TEXT        | NOT NULL |                   | name of the quest variable         }}&lt;br /&gt;
{{sqltablerow|value           | TEXT        | NOT NULL |                   | current value of the quest variable}} &lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Comments ====&lt;br /&gt;
&lt;br /&gt;
* Unless this table is adapted so that it stores the state of a particular quest, this one should have a name which makes it move obvious that it&#039;s storing custom values for &#039;&#039;characters&#039;&#039;. I consider that different from quests variables, which I would expect to be scoped to a certain quest (global quest variables) or quest instance (local quest variables). --[[User:BjÃ¸rn|BjÃ¸rn]] 18:16, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* We might want to have a similar table to this to store custom values for item instances, and also one for custom world-state variables. --[[User:BjÃ¸rn|BjÃ¸rn]] 18:16, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* I always wondered why Silene used the terminology &amp;quot;Quest&amp;quot; for what is basically a system to store/querry persistent character-bound integer variables which can be used for countless purposes, not just quests. I think we should rename this whole system to &amp;quot;character variable&amp;quot; in the database, server source and script bindings. --[[User:Crush2|Crush2]] 23:28, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* I agree with BjÃ¸rn concerning the additional tables for custom item values and custom world-state values. Although the name &amp;quot;tmw_quests&amp;quot; is a little bit confusing and should be renamed, I suggest keeping a table as such to store only quest states of characters and not to mix up with other persistent states. Instead we should provide a much cleaner documentation about the available quests and their persistent states that are possible. I envision something like a questbook in game, where each player can have a look at his finished quests and currently open quests, maybe with hints on the minimap, a todo list .... Besides that, we should be aware of dividing quests into &amp;quot;per-character&amp;quot;, &amp;quot;per-party&amp;quot; or global world quests.  --[[User:Exceptionfault|Exceptionfault]] 16:20, 14 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
=== Auctions ===&lt;br /&gt;
&lt;br /&gt;
Inspired by the ManaBay auction system developed by Qoal, it is planned to build a trading platform for the whole community of players using item auctions.&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_auctions}}&lt;br /&gt;
{{sqltablerow| auction_id    | INTEGER     | PRIMARY KEY      |                     | unique id of an auction                    }}&lt;br /&gt;
{{sqltablerow| auction_state | INTEGER     | NOT NULL         |                     | current state of the auction               }}&lt;br /&gt;
{{sqltablerow| char_id       | INTEGER     | NOT NULL         | tmw_characters (id) | owner of the auction                       }}&lt;br /&gt;
{{sqltablerow| itemclass_id  | INTEGER     | NOT NULL         | items.xml           | id of the item                             }}&lt;br /&gt;
{{sqltablerow| amount        | INTEGER     | NOT NULL         |                     | amount of items to trade                   }}&lt;br /&gt;
{{sqltablerow| start_time    | INTEGER     | NOT NULL         |                     | date of creation or start of auction       }}&lt;br /&gt;
{{sqltablerow| end_time      | INTEGER     | NOT NULL         |                     | end of auction (unixtimestamp)             }}&lt;br /&gt;
{{sqltablerow| start_price   | INTEGER     | NOT NULL         |                     | minimum price for the first bid            }}&lt;br /&gt;
{{sqltablerow| min_price     | INTEGER     | NULL             |                     | minimum price for the final bid to succeed }}&lt;br /&gt;
{{sqltablerow| buyout_price  | INTEGER     | NULL             |                     | price for direct buy of bidded item        }}&lt;br /&gt;
{{sqltablerow| description   | TEXT        | NULL             |                     | optional description of an auction         }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Annotations ====&lt;br /&gt;
&lt;br /&gt;
* auction_state can have the following values:&lt;br /&gt;
** 0 = The auction is published and ready for bidders&lt;br /&gt;
** 1 = The auction has finished and closed&lt;br /&gt;
* start_time contains the creation date of the auction. Format: Unixtimestamp&lt;br /&gt;
&lt;br /&gt;
==== Bids on Auctions ====&lt;br /&gt;
&lt;br /&gt;
This table stores bids made by characters to a specific auction.&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_auctions}}&lt;br /&gt;
{{sqltablerow| bid_id        | INTEGER     | PRIMARY KEY      |                     | unique id of a bid                         }}&lt;br /&gt;
{{sqltablerow| auction_id    | INTEGER     | NOT NULL         | tmw_auctions        | unique id of an auction                    }}&lt;br /&gt;
{{sqltablerow| char_id       | INTEGER     | NOT NULL         | tmw_characters      | owner of the bid                           }}&lt;br /&gt;
{{sqltablerow| bid_time      | INTEGER     | NOT NULL         |                     | time of the bid, used for sorting bids     }}&lt;br /&gt;
{{sqltablerow| bid_price     | INTEGER     | NOT NULL         |                     | price bidded by the character              }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
===== Annotations =====&lt;br /&gt;
&lt;br /&gt;
* bid_time holds the date and time of the bid as Unixtimestamp. Regarding 2 bids can be placed at the same second, the higher bid_price is relevant. If the bid_price is also equal, the smallest bid_id counts, as this is the record first inserted into the database.&lt;br /&gt;
&lt;br /&gt;
=== Postal system ===&lt;br /&gt;
&lt;br /&gt;
==== Letters ====&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_post}}&lt;br /&gt;
{{sqltablerow| letter_id        | INTEGER | PRIMARY KEY |                | unique id of the letter }} &lt;br /&gt;
{{sqltablerow| sender_id        | INTEGER | NOT NULL    | tmw_characters | sending character of the letter }}&lt;br /&gt;
{{sqltablerow| receiver_id      | INTEGER | NOT NULL    | tmw_characters | receiving character of the letter }}&lt;br /&gt;
{{sqltablerow| letter_type      | INTEGER | NOT NULL    |                | type of the letter (unused atm) }}&lt;br /&gt;
{{sqltablerow| expiration_date  | INTEGER | NOT NULL    |                | date and time of expiration }}&lt;br /&gt;
{{sqltablerow| sending_date     | INTEGER | NOT NULL    |                | date and time of sending }}&lt;br /&gt;
{{sqltablerow| letter_text      | TEXT    |     NULL    |                | text }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Item attachments ====&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_post_attachments}}&lt;br /&gt;
{{sqltablerow| attachment_id | INTEGER | PRIMARY KEY |                    | unique id of the attachment }} &lt;br /&gt;
{{sqltablerow| letter_id     | INTEGER | NOT NULL    | tmw_post           | reference to the letter }}&lt;br /&gt;
{{sqltablerow| item_id       | INTEGER | NOT NULL    | tmw_item_instances | attached itema }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Reference  ==&lt;br /&gt;
&lt;br /&gt;
Since the database is changing relatively often while we&#039;re still developing 0.1.0 and nobody likes to keep this page up to date, here is the link to the source code that specifies creation of the database tables. The source code is always right!&lt;br /&gt;
&lt;br /&gt;
* [http://themanaworld.svn.sourceforge.net/viewvc/themanaworld/tmwserv/trunk/src/account-server/dalstoragesql.hpp?view=markup View dalstoragesql.hpp]&lt;br /&gt;
* [http://themanaworld.svn.sourceforge.net/viewvc/*checkout*/themanaworld/tmwserv/trunk/src/account-server/dalstoragesql.hpp?revision=4024 Download dalstoragesql.hpp (plain text)]&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=File:Database_specification_proposal.png&amp;diff=10416</id>
		<title>File:Database specification proposal.png</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=File:Database_specification_proposal.png&amp;diff=10416"/>
		<updated>2008-10-23T10:55:08Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Database_specifications&amp;diff=10401</id>
		<title>Archive:Database specifications</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Database_specifications&amp;diff=10401"/>
		<updated>2008-10-21T07:03:09Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: Added link to graphical db model&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Category_programming}}&lt;br /&gt;
&lt;br /&gt;
== SQL table specifications ==&lt;br /&gt;
&lt;br /&gt;
[[Image:Database specification.png|thumb|200px|The current database model.]]&lt;br /&gt;
&lt;br /&gt;
=== User accounts ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_accounts}}&lt;br /&gt;
{{sqltablerow| id            | INTEGER     | PRIMARY KEY      | | unique id of an account}}                      }}&lt;br /&gt;
{{sqltablerow|username       | TEXT        | NOT NULL UNIQUE  | | username / loginname of an user                }}&lt;br /&gt;
{{sqltablerow|password       | TEXT        | NOT NULL         | | password of an user (sha256 encoded)           }}&lt;br /&gt;
{{sqltablerow|email          | TEXT        | NOT NULL         | | email (sha256 encoded, only for pwd recovery)  }}&lt;br /&gt;
{{sqltablerow|level          | INTEGER     | NOT NULL         | | numeric level of the user account              }}&lt;br /&gt;
{{sqltablerow|banned         | INTEGER     | NOT NULL         | | unixtimestamp until when the account is banned }}&lt;br /&gt;
{{sqltablerow|registration   | INTEGER     | NOT NULL         | | unixtimestamp of account registration          }}&lt;br /&gt;
{{sqltablerow|lastlogin      | INTEGER     | NOT NULL         | | unixtimestamp of last login with client        }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Details ====&lt;br /&gt;
* email&lt;br /&gt;
** The email is stored as a one-way sha256 hash value. This ensures, that the email address a user enters cannot be used to send spam mails. It is only used to validate the mailaddress during password recovery procedure.&lt;br /&gt;
* level&lt;br /&gt;
** describes the user rights in the game (10 = normal user, 50 = gm, 99 = administrator)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Characters ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_characters}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY      |                 | unique id of the character                              }}&lt;br /&gt;
{{sqltablerow|user_id        | INTEGER     | NOT NULL         | tmw_accounts.id | id of the owner                                         }}&lt;br /&gt;
{{sqltablerow|name           | TEXT        | NOT NULL UNIQUE  |                 | name of the character                                   }}&lt;br /&gt;
{{sqltablerow|gender         | INTEGER     | NOT NULL         |                 | gender of the character (0/1)                           }}&lt;br /&gt;
{{sqltablerow|hair_style     | INTEGER     | NOT NULL         |                 | id of the hair sprite                                   }}&lt;br /&gt;
{{sqltablerow|hair_color     | INTEGER     | NOT NULL         |                 | id of the hair color                                    }}&lt;br /&gt;
{{sqltablerow|level          | INTEGER     | NOT NULL         |                 | experience level of the character                       }}&lt;br /&gt;
{{sqltablerow|char_pts       | INTEGER     | NOT NULL         |                 | available points to raise attributes                    }}&lt;br /&gt;
{{sqltablerow|correct_pts    | INTEGER     | NOT NULL         |                 | available points to lower attributes and regain char_pts}}&lt;br /&gt;
{{sqltablerow|money          | INTEGER     | NOT NULL         |                 | GP of the character                                     }}&lt;br /&gt;
{{sqltablerow|x              | INTEGER     | NOT NULL         |                 | x position of the character on the map                  }}&lt;br /&gt;
{{sqltablerow|y              | INTEGER     | NOT NULL         |                 | y position of the character on the map                  }}&lt;br /&gt;
{{sqltablerow|map_id         | INTEGER     | NOT NULL         | tmw_maps.id     | id of the current map the character is located          }}&lt;br /&gt;
{{sqltablerow|str            | INTEGER     | NOT NULL         |                 | strength of the character                               }}&lt;br /&gt;
{{sqltablerow|agi            | INTEGER     | NOT NULL         |                 | agility of the character                                }}&lt;br /&gt;
{{sqltablerow|dex            | INTEGER     | NOT NULL         |                 | dexternity of the character                             }}&lt;br /&gt;
{{sqltablerow|vit            | INTEGER     | NOT NULL         |                 | vitality of the character                               }}&lt;br /&gt;
{{sqltablerow|int            | INTEGER     | NOT NULL         |                 | intelligence of the character                           }}&lt;br /&gt;
{{sqltablerow|will           | INTEGER     | NOT NULL         |                 | willpower of the character                              }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Concerns ====&lt;br /&gt;
&lt;br /&gt;
* The way experience is part of this table really won&#039;t scale and isn&#039;t flexible in any way. It&#039;s currently already way too many variables in one table row, and these are just the weapon skills. So I think we should really have a separate table for storing skill levels similar to the character inventory table below. So something that has { character_id, skill_id, experience }. The &amp;lt;code&amp;gt;skill_id&amp;lt;/code&amp;gt; should point to a &amp;lt;code&amp;gt;skills.xml&amp;lt;/code&amp;gt; file which describes (and categorizes) each skill. In that way we&#039;ll be able to easily change the set of skills and their names later. --[[User:BjÃ¸rn|BjÃ¸rn]] 18:09, 12 September 2008 (CEST)&lt;br /&gt;
** I think the same should be done with the attributes (str .. will). In theory almost every attribute in this table could be handled that way, it might look like a mess, but would be really friendly in customizing the gameplay elements. --[[User:Kess|kess]] 19:54, 12 September 2008 (CEST)&lt;br /&gt;
** I agree with that completely as this will give us more flexibility and a much more relational database design. I&#039;ve extended the &amp;quot;DAL improvements&amp;quot; task in mantis: #424 --[[User:Exceptionfault|Exceptionfault]] 15:50, 14 September 2008 (CEST)&lt;br /&gt;
*** Thanks for taking out the skills from this table. However, I disagree about generalizing stuff on the level of attributes, unless there would be any plan of putting infrastructure in place to make this possible. For now we can&#039;t even finish a server for The Mana World within years, so please don&#039;t try to build a server that supports any online RPG just yet. I only suggested we take out the skills because it would be completely unmanageable as part of this table, but the list of attribute is not expected to change for now. --[[User:BjÃ¸rn|BjÃ¸rn]] 15:55, 22 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
=== Character attributes ===&lt;br /&gt;
&lt;br /&gt;
This table is intended to store skills and experiences of each character. &lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_char_skills}}&lt;br /&gt;
{{sqltablerow|char_id         | INTEGER     | NOT NULL | tmw_characters.id | reference to the character                    }}&lt;br /&gt;
{{sqltablerow|skill_id        | INTEGER     | NOT NULL | (skills.xml)      | reference to the skill                        }}&lt;br /&gt;
{{sqltablerow|exp             | INTEGER     | NOT NULL |                   | current experience of the char in this skill  }} &lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Concerns ====&lt;br /&gt;
&lt;br /&gt;
* I&#039;m not sure, if an INTEGER does the job for column exp? --[[User:Exceptionfault|Exceptionfault]] 14:40, 19 September 2008 (CEST)&lt;br /&gt;
** What is the range? I would expect it to be enough. --[[User:BjÃ¸rn|BjÃ¸rn]] 15:56, 22 September 2008 (CEST)&lt;br /&gt;
*** Hereâ€™s some basic info:&lt;br /&gt;
***: &#039;&#039;&#039;MySQL:&#039;&#039;&#039; INTEGER (INT) may be signed or unsigned and is 4 bytes large, MySQL also have 1, 2, 3 and 8 byte integer variants (TINYINT, SMALLINT, MEDIUMINT and BIGINT) [http://dev.mysql.com/doc/refman/6.0/en/numeric-types.html]&lt;br /&gt;
***: &#039;&#039;&#039;PostgreSQL:&#039;&#039;&#039; INTEGER (INT, INT4) is signed and 4 bytes large, PostgreSQL also have 2 and 8 byte integer variants (SMALLINT and BIGINT) [http://www.postgresql.org/docs/8.3/interactive/datatype-numeric.html]&lt;br /&gt;
***: &#039;&#039;&#039;SQLite:&#039;&#039;&#039; INTEGER is signed and size is either 1, 2, 3, 4, 6 or 8 bytes depending on the size of the value [http://sqlite.org/datatype3.html]&lt;br /&gt;
***: So, the largest integer type supported should be of 8 byte size (signed): from -9,223,372,036,854,775,808 to +9,223,372,036,854,775,807, while the â€œstandardâ€ (of the SQL variants above) signed 4 byte integer ranges from -2,147,483,648 to +2,147,483,647. --[[User:Kess|kess]] 21:18, 22 September 2008 (CEST)&lt;br /&gt;
*** Although we plan to have no fixed level cap I considered a skill level of about 100 to be the highest reasonable value a player can archieve. Level 100 requires an exp sum of 10 million with the current exp formula (levelÂ³ * 10) which fits into a 4 byte integer easily. We won&#039;t get in trouble with 32bit signed integers until the players get near skill level 600 (2.16 billion). The server and the netcode also use 32 bit integers internally.&lt;br /&gt;
&lt;br /&gt;
=== Character Inventory ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_inventories}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY      |                   | unique id of the item                          }}&lt;br /&gt;
{{sqltablerow|owner_id       | INTEGER     | NOT NULL         | tmw_characters.id | id of the owning character                     }}&lt;br /&gt;
{{sqltablerow|slot           | INTEGER     | NOT NULL         |                   | inventory slot where the item is equipped      }}&lt;br /&gt;
{{sqltablerow|class_id       | INTEGER     | NOT NULL         |                   | type of the item, see items.xml file of tmwserv}}&lt;br /&gt;
{{sqltablerow|amount         | INTEGER     | NOT NULL         |                   | amount of items per slot                       }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Comments ====&lt;br /&gt;
* While I havenâ€™t looked how this table is used (my C++ knowledge is rather basic) it seems quite rigid and unflexible (as BjÃ¸rn noted above for the &#039;&#039;&#039;tmw_characters&#039;&#039;&#039; table). I think it would be nicer to have something like {&#039;&#039;owner_id&#039;&#039; FK, &#039;&#039;slot&#039;&#039;, &#039;&#039;item_id&#039;&#039; FK, &#039;&#039;amount&#039;&#039;, PK owner_id + slot}, where class_id shouldnâ€™t directly be needed in this table. --[[User:Kess|kess]] 19:49, 12 September 2008 (CEST)&lt;br /&gt;
* Concerning new features like houses, bank accounts, chests or similar, i think the design of this table needs some more roundtrips. You will need a column which indicates if the item is carried by the character or stored in a chest or in a house; as it makes no sense to have a table for every possible storage type or location. Another point is, that items should be more individualizable (is this a real word? :)). Think about custom colored shirts. So we will need at least one additional table to store individual attributes of items. --[[User:Exceptionfault|Exceptionfault]] 16:02, 14 September 2008 (CEST)&lt;br /&gt;
** We want all equipment to be completely individual with completely unique stats. --[[User:Crush2|Crush2]] 16:13, 14 September 2008 (CEST)&lt;br /&gt;
*** Good to know, so I will extend the DAL improvement task in mantis. --[[User:Exceptionfault|Exceptionfault]] 16:20, 14 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
=== Guilds ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_guilds}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY     |  | unique id of the guid   }}&lt;br /&gt;
{{sqltablerow|name           | TEXT        | NOT NULL UNIQUE |  | unique name of the guild}}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Guild memberships ===&lt;br /&gt;
&lt;br /&gt;
The table &#039;&#039;tmw_guild_members&#039;&#039; stores informations which character is member in which guild and which rights does he has.&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_guild_members}}&lt;br /&gt;
{{sqltablerow|guild_id        | INTEGER     | NOT NULL | tmw_guilds.id     | reference to the guild                                                }}&lt;br /&gt;
{{sqltablerow|member_id       | INTEGER     | NOT NULL | tmw_characters.id | reference to the characters                                           }}&lt;br /&gt;
{{sqltablerow|rights          | INTEGER     | NOT NULL |                   | id showing the rights a character has in this guild (member, admin...)}}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== World state ===&lt;br /&gt;
&lt;br /&gt;
The table &#039;&#039;tmw_world_state&#039;&#039; is used to store persistent informations about the world or individual maps.&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_world_state}}&lt;br /&gt;
{{sqltablerow| state_name      | TEXT     | PRIMARY KEY |             | unique name of a state variable        }} &lt;br /&gt;
{{sqltablerow| map_id          | INTEGER  | NULL        | tmw_maps.id | reference to a map, see details        }}&lt;br /&gt;
{{sqltablerow| value           | TEXT     | NULL        |             | string value of the state              }}&lt;br /&gt;
{{sqltablerow| moddate         | INTEGER  | NOT NULL    |             | date and time of the last modification }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Details ====&lt;br /&gt;
&lt;br /&gt;
* The column &#039;&#039;state_name&#039;&#039; forms the primary key of the table. If &#039;&#039;map_id&#039;&#039; is null, the variable is used globally in the world, otherwise the variable is specific for a map.&lt;br /&gt;
* &#039;&#039;moddate&#039;&#039; is for informational use only as it contains the unixtimestamp of the last modification.&lt;br /&gt;
&lt;br /&gt;
==== Comments ====&lt;br /&gt;
&lt;br /&gt;
* It seems that SQLite doesn&#039;t support composite primary keys (span PK over multiple columns). Therefore it is not possible to allow multiple &#039;&#039;state_name&#039;&#039;s with different &#039;&#039;map_id&#039;&#039;s. So we set a &#039;&#039;state_name&#039;&#039; to unique and use &#039;&#039;map_id&#039;&#039; as notifier if this variable is globally used or just locally for a specific map. --[[User:Exceptionfault|Exceptionfault]] 11:05, 15 September 2008 (CEST)&lt;br /&gt;
** This table is ready for usage, commited as rev. 4629 --[[User:Exceptionfault|Exceptionfault]] 13:51, 15 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Quest states ===&lt;br /&gt;
&lt;br /&gt;
This table is used to store states of quests per character, e.g. if a character has just finished a quest or is currently at the second part of the long journey...&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_quests}}&lt;br /&gt;
{{sqltablerow|owner_id        | INTEGER     | NOT NULL | tmw_characters.id | reference to the character         }}&lt;br /&gt;
{{sqltablerow|name            | TEXT        | NOT NULL |                   | name of the quest variable         }}&lt;br /&gt;
{{sqltablerow|value           | TEXT        | NOT NULL |                   | current value of the quest variable}} &lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Comments ====&lt;br /&gt;
&lt;br /&gt;
* Unless this table is adapted so that it stores the state of a particular quest, this one should have a name which makes it move obvious that it&#039;s storing custom values for &#039;&#039;characters&#039;&#039;. I consider that different from quests variables, which I would expect to be scoped to a certain quest (global quest variables) or quest instance (local quest variables). --[[User:BjÃ¸rn|BjÃ¸rn]] 18:16, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* We might want to have a similar table to this to store custom values for item instances, and also one for custom world-state variables. --[[User:BjÃ¸rn|BjÃ¸rn]] 18:16, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* I always wondered why Silene used the terminology &amp;quot;Quest&amp;quot; for what is basically a system to store/querry persistent character-bound integer variables which can be used for countless purposes, not just quests. I think we should rename this whole system to &amp;quot;character variable&amp;quot; in the database, server source and script bindings. --[[User:Crush2|Crush2]] 23:28, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* I agree with BjÃ¸rn concerning the additional tables for custom item values and custom world-state values. Although the name &amp;quot;tmw_quests&amp;quot; is a little bit confusing and should be renamed, I suggest keeping a table as such to store only quest states of characters and not to mix up with other persistent states. Instead we should provide a much cleaner documentation about the available quests and their persistent states that are possible. I envision something like a questbook in game, where each player can have a look at his finished quests and currently open quests, maybe with hints on the minimap, a todo list .... Besides that, we should be aware of dividing quests into &amp;quot;per-character&amp;quot;, &amp;quot;per-party&amp;quot; or global world quests.  --[[User:Exceptionfault|Exceptionfault]] 16:20, 14 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
=== Auctions ===&lt;br /&gt;
&lt;br /&gt;
Inspired by the ManaBay auction system developed by Qoal, it is planned to build a trading platform for the whole community of players using item auctions.&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_auctions}}&lt;br /&gt;
{{sqltablerow| auction_id    | INTEGER     | PRIMARY KEY      |                     | unique id of an auction                    }}&lt;br /&gt;
{{sqltablerow| auction_state | INTEGER     | NOT NULL         |                     | current state of the auction               }}&lt;br /&gt;
{{sqltablerow| char_id       | INTEGER     | NOT NULL         | tmw_characters (id) | owner of the auction                       }}&lt;br /&gt;
{{sqltablerow| itemclass_id  | INTEGER     | NOT NULL         | items.xml           | id of the item                             }}&lt;br /&gt;
{{sqltablerow| amount        | INTEGER     | NOT NULL         |                     | amount of items to trade                   }}&lt;br /&gt;
{{sqltablerow| start_time    | INTEGER     | NOT NULL         |                     | date of creation or start of auction       }}&lt;br /&gt;
{{sqltablerow| end_time      | INTEGER     | NOT NULL         |                     | end of auction (unixtimestamp)             }}&lt;br /&gt;
{{sqltablerow| start_price   | INTEGER     | NOT NULL         |                     | minimum price for the first bid            }}&lt;br /&gt;
{{sqltablerow| min_price     | INTEGER     | NULL             |                     | minimum price for the final bid to succeed }}&lt;br /&gt;
{{sqltablerow| buyout_price  | INTEGER     | NULL             |                     | price for direct buy of bidded item        }}&lt;br /&gt;
{{sqltablerow| description   | TEXT        | NULL             |                     | optional description of an auction         }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Annotations ====&lt;br /&gt;
&lt;br /&gt;
* auction_state can have the following values:&lt;br /&gt;
** 0 = The auction is published and ready for bidders&lt;br /&gt;
** 1 = The auction has finished and closed&lt;br /&gt;
* start_time contains the creation date of the auction. Format: Unixtimestamp&lt;br /&gt;
&lt;br /&gt;
==== Bids on Auctions ====&lt;br /&gt;
&lt;br /&gt;
This table stores bids made by characters to a specific auction.&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_auctions}}&lt;br /&gt;
{{sqltablerow| bid_id        | INTEGER     | PRIMARY KEY      |                     | unique id of a bid                         }}&lt;br /&gt;
{{sqltablerow| auction_id    | INTEGER     | NOT NULL         | tmw_auctions        | unique id of an auction                    }}&lt;br /&gt;
{{sqltablerow| char_id       | INTEGER     | NOT NULL         | tmw_characters      | owner of the bid                           }}&lt;br /&gt;
{{sqltablerow| bid_time      | INTEGER     | NOT NULL         |                     | time of the bid, used for sorting bids     }}&lt;br /&gt;
{{sqltablerow| bid_price     | INTEGER     | NOT NULL         |                     | price bidded by the character              }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
===== Annotations =====&lt;br /&gt;
&lt;br /&gt;
* bid_time holds the date and time of the bid as Unixtimestamp. Regarding 2 bids can be placed at the same second, the higher bid_price is relevant. If the bid_price is also equal, the smallest bid_id counts, as this is the record first inserted into the database.&lt;br /&gt;
&lt;br /&gt;
== Reference  ==&lt;br /&gt;
&lt;br /&gt;
Since the database is changing relatively often while we&#039;re still developing 0.1.0 and nobody likes to keep this page up to date, here is the link to the source code that specifies creation of the database tables. The source code is always right!&lt;br /&gt;
&lt;br /&gt;
* [http://themanaworld.svn.sourceforge.net/viewvc/themanaworld/tmwserv/trunk/src/account-server/dalstoragesql.hpp?view=markup View dalstoragesql.hpp]&lt;br /&gt;
* [http://themanaworld.svn.sourceforge.net/viewvc/*checkout*/themanaworld/tmwserv/trunk/src/account-server/dalstoragesql.hpp?revision=4024 Download dalstoragesql.hpp (plain text)]&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=File:Database_specification.png&amp;diff=10400</id>
		<title>File:Database specification.png</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=File:Database_specification.png&amp;diff=10400"/>
		<updated>2008-10-21T06:53:08Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: Current database model used by 0.1.* tmwserv&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Current database model used by 0.1.* tmwserv&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Database_specifications&amp;diff=10359</id>
		<title>Archive:Database specifications</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Database_specifications&amp;diff=10359"/>
		<updated>2008-10-16T14:38:20Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: /* Auctions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Category_programming}}&lt;br /&gt;
&lt;br /&gt;
== SQL table specifications ==&lt;br /&gt;
&lt;br /&gt;
=== User accounts ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_accounts}}&lt;br /&gt;
{{sqltablerow| id            | INTEGER     | PRIMARY KEY      | | unique id of an account}}                      }}&lt;br /&gt;
{{sqltablerow|username       | TEXT        | NOT NULL UNIQUE  | | username / loginname of an user                }}&lt;br /&gt;
{{sqltablerow|password       | TEXT        | NOT NULL         | | password of an user (sha256 encoded)           }}&lt;br /&gt;
{{sqltablerow|email          | TEXT        | NOT NULL         | | email (sha256 encoded, only for pwd recovery)  }}&lt;br /&gt;
{{sqltablerow|level          | INTEGER     | NOT NULL         | | numeric level of the user account              }}&lt;br /&gt;
{{sqltablerow|banned         | INTEGER     | NOT NULL         | | unixtimestamp until when the account is banned }}&lt;br /&gt;
{{sqltablerow|registration   | INTEGER     | NOT NULL         | | unixtimestamp of account registration          }}&lt;br /&gt;
{{sqltablerow|lastlogin      | INTEGER     | NOT NULL         | | unixtimestamp of last login with client        }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Details ====&lt;br /&gt;
* email&lt;br /&gt;
** The email is stored as a one-way sha256 hash value. This ensures, that the email address a user enters cannot be used to send spam mails. It is only used to validate the mailaddress during password recovery procedure.&lt;br /&gt;
* level&lt;br /&gt;
** describes the user rights in the game (10 = normal user, 50 = gm, 99 = administrator)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Characters ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_characters}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY      |                 | unique id of the character                              }}&lt;br /&gt;
{{sqltablerow|user_id        | INTEGER     | NOT NULL         | tmw_accounts.id | id of the owner                                         }}&lt;br /&gt;
{{sqltablerow|name           | TEXT        | NOT NULL UNIQUE  |                 | name of the character                                   }}&lt;br /&gt;
{{sqltablerow|gender         | INTEGER     | NOT NULL         |                 | gender of the character (0/1)                           }}&lt;br /&gt;
{{sqltablerow|hair_style     | INTEGER     | NOT NULL         |                 | id of the hair sprite                                   }}&lt;br /&gt;
{{sqltablerow|hair_color     | INTEGER     | NOT NULL         |                 | id of the hair color                                    }}&lt;br /&gt;
{{sqltablerow|level          | INTEGER     | NOT NULL         |                 | experience level of the character                       }}&lt;br /&gt;
{{sqltablerow|char_pts       | INTEGER     | NOT NULL         |                 | available points to raise attributes                    }}&lt;br /&gt;
{{sqltablerow|correct_pts    | INTEGER     | NOT NULL         |                 | available points to lower attributes and regain char_pts}}&lt;br /&gt;
{{sqltablerow|money          | INTEGER     | NOT NULL         |                 | GP of the character                                     }}&lt;br /&gt;
{{sqltablerow|x              | INTEGER     | NOT NULL         |                 | x position of the character on the map                  }}&lt;br /&gt;
{{sqltablerow|y              | INTEGER     | NOT NULL         |                 | y position of the character on the map                  }}&lt;br /&gt;
{{sqltablerow|map_id         | INTEGER     | NOT NULL         | tmw_maps.id     | id of the current map the character is located          }}&lt;br /&gt;
{{sqltablerow|str            | INTEGER     | NOT NULL         |                 | strength of the character                               }}&lt;br /&gt;
{{sqltablerow|agi            | INTEGER     | NOT NULL         |                 | agility of the character                                }}&lt;br /&gt;
{{sqltablerow|dex            | INTEGER     | NOT NULL         |                 | dexternity of the character                             }}&lt;br /&gt;
{{sqltablerow|vit            | INTEGER     | NOT NULL         |                 | vitality of the character                               }}&lt;br /&gt;
{{sqltablerow|int            | INTEGER     | NOT NULL         |                 | intelligence of the character                           }}&lt;br /&gt;
{{sqltablerow|will           | INTEGER     | NOT NULL         |                 | willpower of the character                              }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Concerns ====&lt;br /&gt;
&lt;br /&gt;
* The way experience is part of this table really won&#039;t scale and isn&#039;t flexible in any way. It&#039;s currently already way too many variables in one table row, and these are just the weapon skills. So I think we should really have a separate table for storing skill levels similar to the character inventory table below. So something that has { character_id, skill_id, experience }. The &amp;lt;code&amp;gt;skill_id&amp;lt;/code&amp;gt; should point to a &amp;lt;code&amp;gt;skills.xml&amp;lt;/code&amp;gt; file which describes (and categorizes) each skill. In that way we&#039;ll be able to easily change the set of skills and their names later. --[[User:BjÃ¸rn|BjÃ¸rn]] 18:09, 12 September 2008 (CEST)&lt;br /&gt;
** I think the same should be done with the attributes (str .. will). In theory almost every attribute in this table could be handled that way, it might look like a mess, but would be really friendly in customizing the gameplay elements. --[[User:Kess|kess]] 19:54, 12 September 2008 (CEST)&lt;br /&gt;
** I agree with that completely as this will give us more flexibility and a much more relational database design. I&#039;ve extended the &amp;quot;DAL improvements&amp;quot; task in mantis: #424 --[[User:Exceptionfault|Exceptionfault]] 15:50, 14 September 2008 (CEST)&lt;br /&gt;
*** Thanks for taking out the skills from this table. However, I disagree about generalizing stuff on the level of attributes, unless there would be any plan of putting infrastructure in place to make this possible. For now we can&#039;t even finish a server for The Mana World within years, so please don&#039;t try to build a server that supports any online RPG just yet. I only suggested we take out the skills because it would be completely unmanageable as part of this table, but the list of attribute is not expected to change for now. --[[User:BjÃ¸rn|BjÃ¸rn]] 15:55, 22 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
=== Character attributes ===&lt;br /&gt;
&lt;br /&gt;
This table is intended to store skills and experiences of each character. &lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_char_skills}}&lt;br /&gt;
{{sqltablerow|char_id         | INTEGER     | NOT NULL | tmw_characters.id | reference to the character                    }}&lt;br /&gt;
{{sqltablerow|skill_id        | INTEGER     | NOT NULL | (skills.xml)      | reference to the skill                        }}&lt;br /&gt;
{{sqltablerow|exp             | INTEGER     | NOT NULL |                   | current experience of the char in this skill  }} &lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Concerns ====&lt;br /&gt;
&lt;br /&gt;
* I&#039;m not sure, if an INTEGER does the job for column exp? --[[User:Exceptionfault|Exceptionfault]] 14:40, 19 September 2008 (CEST)&lt;br /&gt;
** What is the range? I would expect it to be enough. --[[User:BjÃ¸rn|BjÃ¸rn]] 15:56, 22 September 2008 (CEST)&lt;br /&gt;
*** Hereâ€™s some basic info:&lt;br /&gt;
***: &#039;&#039;&#039;MySQL:&#039;&#039;&#039; INTEGER (INT) may be signed or unsigned and is 4 bytes large, MySQL also have 1, 2, 3 and 8 byte integer variants (TINYINT, SMALLINT, MEDIUMINT and BIGINT) [http://dev.mysql.com/doc/refman/6.0/en/numeric-types.html]&lt;br /&gt;
***: &#039;&#039;&#039;PostgreSQL:&#039;&#039;&#039; INTEGER (INT, INT4) is signed and 4 bytes large, PostgreSQL also have 2 and 8 byte integer variants (SMALLINT and BIGINT) [http://www.postgresql.org/docs/8.3/interactive/datatype-numeric.html]&lt;br /&gt;
***: &#039;&#039;&#039;SQLite:&#039;&#039;&#039; INTEGER is signed and size is either 1, 2, 3, 4, 6 or 8 bytes depending on the size of the value [http://sqlite.org/datatype3.html]&lt;br /&gt;
***: So, the largest integer type supported should be of 8 byte size (signed): from -9,223,372,036,854,775,808 to +9,223,372,036,854,775,807, while the â€œstandardâ€ (of the SQL variants above) signed 4 byte integer ranges from -2,147,483,648 to +2,147,483,647. --[[User:Kess|kess]] 21:18, 22 September 2008 (CEST)&lt;br /&gt;
*** Although we plan to have no fixed level cap I considered a skill level of about 100 to be the highest reasonable value a player can archieve. Level 100 requires an exp sum of 10 million with the current exp formula (levelÂ³ * 10) which fits into a 4 byte integer easily. We won&#039;t get in trouble with 32bit signed integers until the players get near skill level 600 (2.16 billion). The server and the netcode also use 32 bit integers internally.&lt;br /&gt;
&lt;br /&gt;
=== Character Inventory ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_inventories}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY      |                   | unique id of the item                          }}&lt;br /&gt;
{{sqltablerow|owner_id       | INTEGER     | NOT NULL         | tmw_characters.id | id of the owning character                     }}&lt;br /&gt;
{{sqltablerow|slot           | INTEGER     | NOT NULL         |                   | inventory slot where the item is equipped      }}&lt;br /&gt;
{{sqltablerow|class_id       | INTEGER     | NOT NULL         |                   | type of the item, see items.xml file of tmwserv}}&lt;br /&gt;
{{sqltablerow|amount         | INTEGER     | NOT NULL         |                   | amount of items per slot                       }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Comments ====&lt;br /&gt;
* While I havenâ€™t looked how this table is used (my C++ knowledge is rather basic) it seems quite rigid and unflexible (as BjÃ¸rn noted above for the &#039;&#039;&#039;tmw_characters&#039;&#039;&#039; table). I think it would be nicer to have something like {&#039;&#039;owner_id&#039;&#039; FK, &#039;&#039;slot&#039;&#039;, &#039;&#039;item_id&#039;&#039; FK, &#039;&#039;amount&#039;&#039;, PK owner_id + slot}, where class_id shouldnâ€™t directly be needed in this table. --[[User:Kess|kess]] 19:49, 12 September 2008 (CEST)&lt;br /&gt;
* Concerning new features like houses, bank accounts, chests or similar, i think the design of this table needs some more roundtrips. You will need a column which indicates if the item is carried by the character or stored in a chest or in a house; as it makes no sense to have a table for every possible storage type or location. Another point is, that items should be more individualizable (is this a real word? :)). Think about custom colored shirts. So we will need at least one additional table to store individual attributes of items. --[[User:Exceptionfault|Exceptionfault]] 16:02, 14 September 2008 (CEST)&lt;br /&gt;
** We want all equipment to be completely individual with completely unique stats. --[[User:Crush2|Crush2]] 16:13, 14 September 2008 (CEST)&lt;br /&gt;
*** Good to know, so I will extend the DAL improvement task in mantis. --[[User:Exceptionfault|Exceptionfault]] 16:20, 14 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
=== Guilds ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_guilds}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY     |  | unique id of the guid   }}&lt;br /&gt;
{{sqltablerow|name           | TEXT        | NOT NULL UNIQUE |  | unique name of the guild}}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Guild memberships ===&lt;br /&gt;
&lt;br /&gt;
The table &#039;&#039;tmw_guild_members&#039;&#039; stores informations which character is member in which guild and which rights does he has.&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_guild_members}}&lt;br /&gt;
{{sqltablerow|guild_id        | INTEGER     | NOT NULL | tmw_guilds.id     | reference to the guild                                                }}&lt;br /&gt;
{{sqltablerow|member_id       | INTEGER     | NOT NULL | tmw_characters.id | reference to the characters                                           }}&lt;br /&gt;
{{sqltablerow|rights          | INTEGER     | NOT NULL |                   | id showing the rights a character has in this guild (member, admin...)}}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== World state ===&lt;br /&gt;
&lt;br /&gt;
The table &#039;&#039;tmw_world_state&#039;&#039; is used to store persistent informations about the world or individual maps.&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_world_state}}&lt;br /&gt;
{{sqltablerow| state_name      | TEXT     | PRIMARY KEY |             | unique name of a state variable        }} &lt;br /&gt;
{{sqltablerow| map_id          | INTEGER  | NULL        | tmw_maps.id | reference to a map, see details        }}&lt;br /&gt;
{{sqltablerow| value           | TEXT     | NULL        |             | string value of the state              }}&lt;br /&gt;
{{sqltablerow| moddate         | INTEGER  | NOT NULL    |             | date and time of the last modification }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Details ====&lt;br /&gt;
&lt;br /&gt;
* The column &#039;&#039;state_name&#039;&#039; forms the primary key of the table. If &#039;&#039;map_id&#039;&#039; is null, the variable is used globally in the world, otherwise the variable is specific for a map.&lt;br /&gt;
* &#039;&#039;moddate&#039;&#039; is for informational use only as it contains the unixtimestamp of the last modification.&lt;br /&gt;
&lt;br /&gt;
==== Comments ====&lt;br /&gt;
&lt;br /&gt;
* It seems that SQLite doesn&#039;t support composite primary keys (span PK over multiple columns). Therefore it is not possible to allow multiple &#039;&#039;state_name&#039;&#039;s with different &#039;&#039;map_id&#039;&#039;s. So we set a &#039;&#039;state_name&#039;&#039; to unique and use &#039;&#039;map_id&#039;&#039; as notifier if this variable is globally used or just locally for a specific map. --[[User:Exceptionfault|Exceptionfault]] 11:05, 15 September 2008 (CEST)&lt;br /&gt;
** This table is ready for usage, commited as rev. 4629 --[[User:Exceptionfault|Exceptionfault]] 13:51, 15 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Quest states ===&lt;br /&gt;
&lt;br /&gt;
This table is used to store states of quests per character, e.g. if a character has just finished a quest or is currently at the second part of the long journey...&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_quests}}&lt;br /&gt;
{{sqltablerow|owner_id        | INTEGER     | NOT NULL | tmw_characters.id | reference to the character         }}&lt;br /&gt;
{{sqltablerow|name            | TEXT        | NOT NULL |                   | name of the quest variable         }}&lt;br /&gt;
{{sqltablerow|value           | TEXT        | NOT NULL |                   | current value of the quest variable}} &lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Comments ====&lt;br /&gt;
&lt;br /&gt;
* Unless this table is adapted so that it stores the state of a particular quest, this one should have a name which makes it move obvious that it&#039;s storing custom values for &#039;&#039;characters&#039;&#039;. I consider that different from quests variables, which I would expect to be scoped to a certain quest (global quest variables) or quest instance (local quest variables). --[[User:BjÃ¸rn|BjÃ¸rn]] 18:16, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* We might want to have a similar table to this to store custom values for item instances, and also one for custom world-state variables. --[[User:BjÃ¸rn|BjÃ¸rn]] 18:16, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* I always wondered why Silene used the terminology &amp;quot;Quest&amp;quot; for what is basically a system to store/querry persistent character-bound integer variables which can be used for countless purposes, not just quests. I think we should rename this whole system to &amp;quot;character variable&amp;quot; in the database, server source and script bindings. --[[User:Crush2|Crush2]] 23:28, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* I agree with BjÃ¸rn concerning the additional tables for custom item values and custom world-state values. Although the name &amp;quot;tmw_quests&amp;quot; is a little bit confusing and should be renamed, I suggest keeping a table as such to store only quest states of characters and not to mix up with other persistent states. Instead we should provide a much cleaner documentation about the available quests and their persistent states that are possible. I envision something like a questbook in game, where each player can have a look at his finished quests and currently open quests, maybe with hints on the minimap, a todo list .... Besides that, we should be aware of dividing quests into &amp;quot;per-character&amp;quot;, &amp;quot;per-party&amp;quot; or global world quests.  --[[User:Exceptionfault|Exceptionfault]] 16:20, 14 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
=== Auctions ===&lt;br /&gt;
&lt;br /&gt;
Inspired by the ManaBay auction system developed by Qoal, it is planned to build a trading plattform for the whole community of players using item auctions.&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_auctions}}&lt;br /&gt;
{{sqltablerow| auction_id    | INTEGER     | PRIMARY KEY      |                     | unique id of an auction                    }}&lt;br /&gt;
{{sqltablerow| auction_state | INTEGER     | NOT NULL         |                     | current state of the auction               }}&lt;br /&gt;
{{sqltablerow| char_id       | INTEGER     | NOT NULL         | tmw_characters (id) | owner of the auction                       }}&lt;br /&gt;
{{sqltablerow| itemclass_id  | INTEGER     | NOT NULL         | items.xml           | id of the item                             }}&lt;br /&gt;
{{sqltablerow| amount        | INTEGER     | NOT NULL         |                     | amount of items to trade                   }}&lt;br /&gt;
{{sqltablerow| start_time    | INTEGER     | NOT NULL         |                     | date of creation or start of auction       }}&lt;br /&gt;
{{sqltablerow| end_time      | INTEGER     | NOT NULL         |                     | end of auction (unixtimestamp)             }}&lt;br /&gt;
{{sqltablerow| start_price   | INTEGER     | NOT NULL         |                     | minimum price for the first bid            }}&lt;br /&gt;
{{sqltablerow| min_price     | INTEGER     | NULL             |                     | minimum price for the final bid to succeed }}&lt;br /&gt;
{{sqltablerow| buyout_price  | INTEGER     | NULL             |                     | price for direct buy of bidded item        }}&lt;br /&gt;
{{sqltablerow| description   | TEXT        | NULL             |                     | optional description of an auction         }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Annotations ====&lt;br /&gt;
&lt;br /&gt;
* auction_state can have the following values:&lt;br /&gt;
** 0 = The auction is published and ready for bidders&lt;br /&gt;
** 1 = The auction has finished and closed&lt;br /&gt;
* start_time contains the creation date of the auction. Format: Unixtimestamp&lt;br /&gt;
&lt;br /&gt;
==== Bids on Auctions ====&lt;br /&gt;
&lt;br /&gt;
This table stores bids made by characters to a specific auction.&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_auctions}}&lt;br /&gt;
{{sqltablerow| bid_id        | INTEGER     | PRIMARY KEY      |                     | unique id of a bid                         }}&lt;br /&gt;
{{sqltablerow| auction_id    | INTEGER     | NOT NULL         | tmw_auctions        | unique id of an auction                    }}&lt;br /&gt;
{{sqltablerow| char_id       | INTEGER     | NOT NULL         | tmw_characters      | owner of the bid                           }}&lt;br /&gt;
{{sqltablerow| bid_time      | INTEGER     | NOT NULL         |                     | time of the bid, used for sorting bids     }}&lt;br /&gt;
{{sqltablerow| bid_price     | INTEGER     | NOT NULL         |                     | price bidded by the character              }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
===== Annotations =====&lt;br /&gt;
&lt;br /&gt;
* bid_time holds the date and time of the bid as Unixtimestamp. Regarding 2 bids can be placed at the same second, the higher bid_price is relevant. If the bid_price is also equal, the smallest bid_id counts, as this is the record first inserted into the database.&lt;br /&gt;
&lt;br /&gt;
== Reference  ==&lt;br /&gt;
&lt;br /&gt;
Since the database is changing relatively often while we&#039;re still developing 0.1.0 and nobody likes to keep this page up to date, here is the link to the source code that specifies creation of the database tables. The source code is always right!&lt;br /&gt;
&lt;br /&gt;
* [http://themanaworld.svn.sourceforge.net/viewvc/themanaworld/tmwserv/trunk/src/account-server/dalstoragesql.hpp?view=markup View dalstoragesql.hpp]&lt;br /&gt;
* [http://themanaworld.svn.sourceforge.net/viewvc/*checkout*/themanaworld/tmwserv/trunk/src/account-server/dalstoragesql.hpp?revision=4024 Download dalstoragesql.hpp (plain text)]&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Database_specifications&amp;diff=10358</id>
		<title>Archive:Database specifications</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Database_specifications&amp;diff=10358"/>
		<updated>2008-10-16T14:18:40Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: /* Auctions */ added bids table for auctions&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Category_programming}}&lt;br /&gt;
&lt;br /&gt;
== SQL table specifications ==&lt;br /&gt;
&lt;br /&gt;
=== User accounts ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_accounts}}&lt;br /&gt;
{{sqltablerow| id            | INTEGER     | PRIMARY KEY      | | unique id of an account}}                      }}&lt;br /&gt;
{{sqltablerow|username       | TEXT        | NOT NULL UNIQUE  | | username / loginname of an user                }}&lt;br /&gt;
{{sqltablerow|password       | TEXT        | NOT NULL         | | password of an user (sha256 encoded)           }}&lt;br /&gt;
{{sqltablerow|email          | TEXT        | NOT NULL         | | email (sha256 encoded, only for pwd recovery)  }}&lt;br /&gt;
{{sqltablerow|level          | INTEGER     | NOT NULL         | | numeric level of the user account              }}&lt;br /&gt;
{{sqltablerow|banned         | INTEGER     | NOT NULL         | | unixtimestamp until when the account is banned }}&lt;br /&gt;
{{sqltablerow|registration   | INTEGER     | NOT NULL         | | unixtimestamp of account registration          }}&lt;br /&gt;
{{sqltablerow|lastlogin      | INTEGER     | NOT NULL         | | unixtimestamp of last login with client        }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Details ====&lt;br /&gt;
* email&lt;br /&gt;
** The email is stored as a one-way sha256 hash value. This ensures, that the email address a user enters cannot be used to send spam mails. It is only used to validate the mailaddress during password recovery procedure.&lt;br /&gt;
* level&lt;br /&gt;
** describes the user rights in the game (10 = normal user, 50 = gm, 99 = administrator)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Characters ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_characters}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY      |                 | unique id of the character                              }}&lt;br /&gt;
{{sqltablerow|user_id        | INTEGER     | NOT NULL         | tmw_accounts.id | id of the owner                                         }}&lt;br /&gt;
{{sqltablerow|name           | TEXT        | NOT NULL UNIQUE  |                 | name of the character                                   }}&lt;br /&gt;
{{sqltablerow|gender         | INTEGER     | NOT NULL         |                 | gender of the character (0/1)                           }}&lt;br /&gt;
{{sqltablerow|hair_style     | INTEGER     | NOT NULL         |                 | id of the hair sprite                                   }}&lt;br /&gt;
{{sqltablerow|hair_color     | INTEGER     | NOT NULL         |                 | id of the hair color                                    }}&lt;br /&gt;
{{sqltablerow|level          | INTEGER     | NOT NULL         |                 | experience level of the character                       }}&lt;br /&gt;
{{sqltablerow|char_pts       | INTEGER     | NOT NULL         |                 | available points to raise attributes                    }}&lt;br /&gt;
{{sqltablerow|correct_pts    | INTEGER     | NOT NULL         |                 | available points to lower attributes and regain char_pts}}&lt;br /&gt;
{{sqltablerow|money          | INTEGER     | NOT NULL         |                 | GP of the character                                     }}&lt;br /&gt;
{{sqltablerow|x              | INTEGER     | NOT NULL         |                 | x position of the character on the map                  }}&lt;br /&gt;
{{sqltablerow|y              | INTEGER     | NOT NULL         |                 | y position of the character on the map                  }}&lt;br /&gt;
{{sqltablerow|map_id         | INTEGER     | NOT NULL         | tmw_maps.id     | id of the current map the character is located          }}&lt;br /&gt;
{{sqltablerow|str            | INTEGER     | NOT NULL         |                 | strength of the character                               }}&lt;br /&gt;
{{sqltablerow|agi            | INTEGER     | NOT NULL         |                 | agility of the character                                }}&lt;br /&gt;
{{sqltablerow|dex            | INTEGER     | NOT NULL         |                 | dexternity of the character                             }}&lt;br /&gt;
{{sqltablerow|vit            | INTEGER     | NOT NULL         |                 | vitality of the character                               }}&lt;br /&gt;
{{sqltablerow|int            | INTEGER     | NOT NULL         |                 | intelligence of the character                           }}&lt;br /&gt;
{{sqltablerow|will           | INTEGER     | NOT NULL         |                 | willpower of the character                              }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Concerns ====&lt;br /&gt;
&lt;br /&gt;
* The way experience is part of this table really won&#039;t scale and isn&#039;t flexible in any way. It&#039;s currently already way too many variables in one table row, and these are just the weapon skills. So I think we should really have a separate table for storing skill levels similar to the character inventory table below. So something that has { character_id, skill_id, experience }. The &amp;lt;code&amp;gt;skill_id&amp;lt;/code&amp;gt; should point to a &amp;lt;code&amp;gt;skills.xml&amp;lt;/code&amp;gt; file which describes (and categorizes) each skill. In that way we&#039;ll be able to easily change the set of skills and their names later. --[[User:BjÃ¸rn|BjÃ¸rn]] 18:09, 12 September 2008 (CEST)&lt;br /&gt;
** I think the same should be done with the attributes (str .. will). In theory almost every attribute in this table could be handled that way, it might look like a mess, but would be really friendly in customizing the gameplay elements. --[[User:Kess|kess]] 19:54, 12 September 2008 (CEST)&lt;br /&gt;
** I agree with that completely as this will give us more flexibility and a much more relational database design. I&#039;ve extended the &amp;quot;DAL improvements&amp;quot; task in mantis: #424 --[[User:Exceptionfault|Exceptionfault]] 15:50, 14 September 2008 (CEST)&lt;br /&gt;
*** Thanks for taking out the skills from this table. However, I disagree about generalizing stuff on the level of attributes, unless there would be any plan of putting infrastructure in place to make this possible. For now we can&#039;t even finish a server for The Mana World within years, so please don&#039;t try to build a server that supports any online RPG just yet. I only suggested we take out the skills because it would be completely unmanageable as part of this table, but the list of attribute is not expected to change for now. --[[User:BjÃ¸rn|BjÃ¸rn]] 15:55, 22 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
=== Character attributes ===&lt;br /&gt;
&lt;br /&gt;
This table is intended to store skills and experiences of each character. &lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_char_skills}}&lt;br /&gt;
{{sqltablerow|char_id         | INTEGER     | NOT NULL | tmw_characters.id | reference to the character                    }}&lt;br /&gt;
{{sqltablerow|skill_id        | INTEGER     | NOT NULL | (skills.xml)      | reference to the skill                        }}&lt;br /&gt;
{{sqltablerow|exp             | INTEGER     | NOT NULL |                   | current experience of the char in this skill  }} &lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Concerns ====&lt;br /&gt;
&lt;br /&gt;
* I&#039;m not sure, if an INTEGER does the job for column exp? --[[User:Exceptionfault|Exceptionfault]] 14:40, 19 September 2008 (CEST)&lt;br /&gt;
** What is the range? I would expect it to be enough. --[[User:BjÃ¸rn|BjÃ¸rn]] 15:56, 22 September 2008 (CEST)&lt;br /&gt;
*** Hereâ€™s some basic info:&lt;br /&gt;
***: &#039;&#039;&#039;MySQL:&#039;&#039;&#039; INTEGER (INT) may be signed or unsigned and is 4 bytes large, MySQL also have 1, 2, 3 and 8 byte integer variants (TINYINT, SMALLINT, MEDIUMINT and BIGINT) [http://dev.mysql.com/doc/refman/6.0/en/numeric-types.html]&lt;br /&gt;
***: &#039;&#039;&#039;PostgreSQL:&#039;&#039;&#039; INTEGER (INT, INT4) is signed and 4 bytes large, PostgreSQL also have 2 and 8 byte integer variants (SMALLINT and BIGINT) [http://www.postgresql.org/docs/8.3/interactive/datatype-numeric.html]&lt;br /&gt;
***: &#039;&#039;&#039;SQLite:&#039;&#039;&#039; INTEGER is signed and size is either 1, 2, 3, 4, 6 or 8 bytes depending on the size of the value [http://sqlite.org/datatype3.html]&lt;br /&gt;
***: So, the largest integer type supported should be of 8 byte size (signed): from -9,223,372,036,854,775,808 to +9,223,372,036,854,775,807, while the â€œstandardâ€ (of the SQL variants above) signed 4 byte integer ranges from -2,147,483,648 to +2,147,483,647. --[[User:Kess|kess]] 21:18, 22 September 2008 (CEST)&lt;br /&gt;
*** Although we plan to have no fixed level cap I considered a skill level of about 100 to be the highest reasonable value a player can archieve. Level 100 requires an exp sum of 10 million with the current exp formula (levelÂ³ * 10) which fits into a 4 byte integer easily. We won&#039;t get in trouble with 32bit signed integers until the players get near skill level 600 (2.16 billion). The server and the netcode also use 32 bit integers internally.&lt;br /&gt;
&lt;br /&gt;
=== Character Inventory ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_inventories}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY      |                   | unique id of the item                          }}&lt;br /&gt;
{{sqltablerow|owner_id       | INTEGER     | NOT NULL         | tmw_characters.id | id of the owning character                     }}&lt;br /&gt;
{{sqltablerow|slot           | INTEGER     | NOT NULL         |                   | inventory slot where the item is equipped      }}&lt;br /&gt;
{{sqltablerow|class_id       | INTEGER     | NOT NULL         |                   | type of the item, see items.xml file of tmwserv}}&lt;br /&gt;
{{sqltablerow|amount         | INTEGER     | NOT NULL         |                   | amount of items per slot                       }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Comments ====&lt;br /&gt;
* While I havenâ€™t looked how this table is used (my C++ knowledge is rather basic) it seems quite rigid and unflexible (as BjÃ¸rn noted above for the &#039;&#039;&#039;tmw_characters&#039;&#039;&#039; table). I think it would be nicer to have something like {&#039;&#039;owner_id&#039;&#039; FK, &#039;&#039;slot&#039;&#039;, &#039;&#039;item_id&#039;&#039; FK, &#039;&#039;amount&#039;&#039;, PK owner_id + slot}, where class_id shouldnâ€™t directly be needed in this table. --[[User:Kess|kess]] 19:49, 12 September 2008 (CEST)&lt;br /&gt;
* Concerning new features like houses, bank accounts, chests or similar, i think the design of this table needs some more roundtrips. You will need a column which indicates if the item is carried by the character or stored in a chest or in a house; as it makes no sense to have a table for every possible storage type or location. Another point is, that items should be more individualizable (is this a real word? :)). Think about custom colored shirts. So we will need at least one additional table to store individual attributes of items. --[[User:Exceptionfault|Exceptionfault]] 16:02, 14 September 2008 (CEST)&lt;br /&gt;
** We want all equipment to be completely individual with completely unique stats. --[[User:Crush2|Crush2]] 16:13, 14 September 2008 (CEST)&lt;br /&gt;
*** Good to know, so I will extend the DAL improvement task in mantis. --[[User:Exceptionfault|Exceptionfault]] 16:20, 14 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
=== Guilds ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_guilds}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY     |  | unique id of the guid   }}&lt;br /&gt;
{{sqltablerow|name           | TEXT        | NOT NULL UNIQUE |  | unique name of the guild}}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Guild memberships ===&lt;br /&gt;
&lt;br /&gt;
The table &#039;&#039;tmw_guild_members&#039;&#039; stores informations which character is member in which guild and which rights does he has.&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_guild_members}}&lt;br /&gt;
{{sqltablerow|guild_id        | INTEGER     | NOT NULL | tmw_guilds.id     | reference to the guild                                                }}&lt;br /&gt;
{{sqltablerow|member_id       | INTEGER     | NOT NULL | tmw_characters.id | reference to the characters                                           }}&lt;br /&gt;
{{sqltablerow|rights          | INTEGER     | NOT NULL |                   | id showing the rights a character has in this guild (member, admin...)}}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== World state ===&lt;br /&gt;
&lt;br /&gt;
The table &#039;&#039;tmw_world_state&#039;&#039; is used to store persistent informations about the world or individual maps.&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_world_state}}&lt;br /&gt;
{{sqltablerow| state_name      | TEXT     | PRIMARY KEY |             | unique name of a state variable        }} &lt;br /&gt;
{{sqltablerow| map_id          | INTEGER  | NULL        | tmw_maps.id | reference to a map, see details        }}&lt;br /&gt;
{{sqltablerow| value           | TEXT     | NULL        |             | string value of the state              }}&lt;br /&gt;
{{sqltablerow| moddate         | INTEGER  | NOT NULL    |             | date and time of the last modification }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Details ====&lt;br /&gt;
&lt;br /&gt;
* The column &#039;&#039;state_name&#039;&#039; forms the primary key of the table. If &#039;&#039;map_id&#039;&#039; is null, the variable is used globally in the world, otherwise the variable is specific for a map.&lt;br /&gt;
* &#039;&#039;moddate&#039;&#039; is for informational use only as it contains the unixtimestamp of the last modification.&lt;br /&gt;
&lt;br /&gt;
==== Comments ====&lt;br /&gt;
&lt;br /&gt;
* It seems that SQLite doesn&#039;t support composite primary keys (span PK over multiple columns). Therefore it is not possible to allow multiple &#039;&#039;state_name&#039;&#039;s with different &#039;&#039;map_id&#039;&#039;s. So we set a &#039;&#039;state_name&#039;&#039; to unique and use &#039;&#039;map_id&#039;&#039; as notifier if this variable is globally used or just locally for a specific map. --[[User:Exceptionfault|Exceptionfault]] 11:05, 15 September 2008 (CEST)&lt;br /&gt;
** This table is ready for usage, commited as rev. 4629 --[[User:Exceptionfault|Exceptionfault]] 13:51, 15 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Quest states ===&lt;br /&gt;
&lt;br /&gt;
This table is used to store states of quests per character, e.g. if a character has just finished a quest or is currently at the second part of the long journey...&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_quests}}&lt;br /&gt;
{{sqltablerow|owner_id        | INTEGER     | NOT NULL | tmw_characters.id | reference to the character         }}&lt;br /&gt;
{{sqltablerow|name            | TEXT        | NOT NULL |                   | name of the quest variable         }}&lt;br /&gt;
{{sqltablerow|value           | TEXT        | NOT NULL |                   | current value of the quest variable}} &lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Comments ====&lt;br /&gt;
&lt;br /&gt;
* Unless this table is adapted so that it stores the state of a particular quest, this one should have a name which makes it move obvious that it&#039;s storing custom values for &#039;&#039;characters&#039;&#039;. I consider that different from quests variables, which I would expect to be scoped to a certain quest (global quest variables) or quest instance (local quest variables). --[[User:BjÃ¸rn|BjÃ¸rn]] 18:16, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* We might want to have a similar table to this to store custom values for item instances, and also one for custom world-state variables. --[[User:BjÃ¸rn|BjÃ¸rn]] 18:16, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* I always wondered why Silene used the terminology &amp;quot;Quest&amp;quot; for what is basically a system to store/querry persistent character-bound integer variables which can be used for countless purposes, not just quests. I think we should rename this whole system to &amp;quot;character variable&amp;quot; in the database, server source and script bindings. --[[User:Crush2|Crush2]] 23:28, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* I agree with BjÃ¸rn concerning the additional tables for custom item values and custom world-state values. Although the name &amp;quot;tmw_quests&amp;quot; is a little bit confusing and should be renamed, I suggest keeping a table as such to store only quest states of characters and not to mix up with other persistent states. Instead we should provide a much cleaner documentation about the available quests and their persistent states that are possible. I envision something like a questbook in game, where each player can have a look at his finished quests and currently open quests, maybe with hints on the minimap, a todo list .... Besides that, we should be aware of dividing quests into &amp;quot;per-character&amp;quot;, &amp;quot;per-party&amp;quot; or global world quests.  --[[User:Exceptionfault|Exceptionfault]] 16:20, 14 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
=== Auctions ===&lt;br /&gt;
&lt;br /&gt;
Inspired by the ManaBay auction system developed by Qoal, it is planned to build a trading plattform for the whole community of players using item auctions.&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_auctions}}&lt;br /&gt;
{{sqltablerow| auction_id    | INTEGER     | PRIMARY KEY      |                     | unique id of an auction                    }}&lt;br /&gt;
{{sqltablerow| auction_state | INTEGER     | NOT NULL         |                     | current state of the auction               }}&lt;br /&gt;
{{sqltablerow| char_id       | INTEGER     | NOT NULL         | tmw_characters (id) | owner of the auction                       }}&lt;br /&gt;
{{sqltablerow| itemclass_id  | INTEGER     | NOT NULL         | items.xml           | id of the item                             }}&lt;br /&gt;
{{sqltablerow| amount        | INTEGER     | NOT NULL         |                     | amount of items to trade                   }}&lt;br /&gt;
{{sqltablerow| start_time    | INTEGER     | NOT NULL         |                     | date of creation or start of auction       }}&lt;br /&gt;
{{sqltablerow| start_price   | INTEGER     | NOT NULL         |                     | minimum price for the first bid            }}&lt;br /&gt;
{{sqltablerow| end_time      | INTEGER     | NULL             |                     | end of auction (unixtimestamp)             }}&lt;br /&gt;
{{sqltablerow| min_price     | INTEGER     | NULL             |                     | minimum price for the final bid to succeed }}&lt;br /&gt;
{{sqltablerow| buyout_price  | INTEGER     | NULL             |                     | price for direct buy of bidded item        }}&lt;br /&gt;
{{sqltablerow| description   | TEXT        | NULL             |                     | optional description of an auction         }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Annotations ====&lt;br /&gt;
&lt;br /&gt;
* auction_state can have the following values:&lt;br /&gt;
** 0 = The auction is created by the owner but not yet published&lt;br /&gt;
** 1 = The auction is published and ready for bitters&lt;br /&gt;
** 2 = The auction has finished and closed&lt;br /&gt;
* start_time depends on the current state of the auction. If the auction is in state 0, the column contains the creation date of the auction. If it switches to &amp;quot;open&amp;quot; the date has to be refresehd to contain the start date of the auction. Format: Unixtimestamp&lt;br /&gt;
* end_time is empty unless the auction has started. The owner has to define the duration of an auction when he changes the state to &amp;quot;open&amp;quot;. Format: Unixtimestamp&lt;br /&gt;
&lt;br /&gt;
==== Bids on Auctions ====&lt;br /&gt;
&lt;br /&gt;
This table stores bids made by characters to a specific auction.&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_auctions}}&lt;br /&gt;
{{sqltablerow| bid_id        | INTEGER     | PRIMARY KEY      |                     | unique id of a bid                         }}&lt;br /&gt;
{{sqltablerow| auction_id    | INTEGER     | NOT NULL         | tmw_auctions        | unique id of an auction                    }}&lt;br /&gt;
{{sqltablerow| char_id       | INTEGER     | NOT NULL         | tmw_characters      | owner of the bid                           }}&lt;br /&gt;
{{sqltablerow| bid_time      | INTEGER     | NOT NULL         |                     | time of the bid, used for sorting bids     }}&lt;br /&gt;
{{sqltablerow| bid_price     | INTEGER     | NOT NULL         |                     | price bidded by the character              }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
===== Annotations =====&lt;br /&gt;
&lt;br /&gt;
* bid_time holds the date and time of the bid as Unixtimestamp. Regarding 2 bids can be placed at the same second, the higher bid_price is relevant. If the bid_price is also equal, the smallest bid_id counts, as this is the record first inserted into the database.&lt;br /&gt;
&lt;br /&gt;
== Reference  ==&lt;br /&gt;
&lt;br /&gt;
Since the database is changing relatively often while we&#039;re still developing 0.1.0 and nobody likes to keep this page up to date, here is the link to the source code that specifies creation of the database tables. The source code is always right!&lt;br /&gt;
&lt;br /&gt;
* [http://themanaworld.svn.sourceforge.net/viewvc/themanaworld/tmwserv/trunk/src/account-server/dalstoragesql.hpp?view=markup View dalstoragesql.hpp]&lt;br /&gt;
* [http://themanaworld.svn.sourceforge.net/viewvc/*checkout*/themanaworld/tmwserv/trunk/src/account-server/dalstoragesql.hpp?revision=4024 Download dalstoragesql.hpp (plain text)]&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Database_specifications&amp;diff=10357</id>
		<title>Archive:Database specifications</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Database_specifications&amp;diff=10357"/>
		<updated>2008-10-16T13:55:58Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Category_programming}}&lt;br /&gt;
&lt;br /&gt;
== SQL table specifications ==&lt;br /&gt;
&lt;br /&gt;
=== User accounts ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_accounts}}&lt;br /&gt;
{{sqltablerow| id            | INTEGER     | PRIMARY KEY      | | unique id of an account}}                      }}&lt;br /&gt;
{{sqltablerow|username       | TEXT        | NOT NULL UNIQUE  | | username / loginname of an user                }}&lt;br /&gt;
{{sqltablerow|password       | TEXT        | NOT NULL         | | password of an user (sha256 encoded)           }}&lt;br /&gt;
{{sqltablerow|email          | TEXT        | NOT NULL         | | email (sha256 encoded, only for pwd recovery)  }}&lt;br /&gt;
{{sqltablerow|level          | INTEGER     | NOT NULL         | | numeric level of the user account              }}&lt;br /&gt;
{{sqltablerow|banned         | INTEGER     | NOT NULL         | | unixtimestamp until when the account is banned }}&lt;br /&gt;
{{sqltablerow|registration   | INTEGER     | NOT NULL         | | unixtimestamp of account registration          }}&lt;br /&gt;
{{sqltablerow|lastlogin      | INTEGER     | NOT NULL         | | unixtimestamp of last login with client        }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Details ====&lt;br /&gt;
* email&lt;br /&gt;
** The email is stored as a one-way sha256 hash value. This ensures, that the email address a user enters cannot be used to send spam mails. It is only used to validate the mailaddress during password recovery procedure.&lt;br /&gt;
* level&lt;br /&gt;
** describes the user rights in the game (10 = normal user, 50 = gm, 99 = administrator)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Characters ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_characters}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY      |                 | unique id of the character                              }}&lt;br /&gt;
{{sqltablerow|user_id        | INTEGER     | NOT NULL         | tmw_accounts.id | id of the owner                                         }}&lt;br /&gt;
{{sqltablerow|name           | TEXT        | NOT NULL UNIQUE  |                 | name of the character                                   }}&lt;br /&gt;
{{sqltablerow|gender         | INTEGER     | NOT NULL         |                 | gender of the character (0/1)                           }}&lt;br /&gt;
{{sqltablerow|hair_style     | INTEGER     | NOT NULL         |                 | id of the hair sprite                                   }}&lt;br /&gt;
{{sqltablerow|hair_color     | INTEGER     | NOT NULL         |                 | id of the hair color                                    }}&lt;br /&gt;
{{sqltablerow|level          | INTEGER     | NOT NULL         |                 | experience level of the character                       }}&lt;br /&gt;
{{sqltablerow|char_pts       | INTEGER     | NOT NULL         |                 | available points to raise attributes                    }}&lt;br /&gt;
{{sqltablerow|correct_pts    | INTEGER     | NOT NULL         |                 | available points to lower attributes and regain char_pts}}&lt;br /&gt;
{{sqltablerow|money          | INTEGER     | NOT NULL         |                 | GP of the character                                     }}&lt;br /&gt;
{{sqltablerow|x              | INTEGER     | NOT NULL         |                 | x position of the character on the map                  }}&lt;br /&gt;
{{sqltablerow|y              | INTEGER     | NOT NULL         |                 | y position of the character on the map                  }}&lt;br /&gt;
{{sqltablerow|map_id         | INTEGER     | NOT NULL         | tmw_maps.id     | id of the current map the character is located          }}&lt;br /&gt;
{{sqltablerow|str            | INTEGER     | NOT NULL         |                 | strength of the character                               }}&lt;br /&gt;
{{sqltablerow|agi            | INTEGER     | NOT NULL         |                 | agility of the character                                }}&lt;br /&gt;
{{sqltablerow|dex            | INTEGER     | NOT NULL         |                 | dexternity of the character                             }}&lt;br /&gt;
{{sqltablerow|vit            | INTEGER     | NOT NULL         |                 | vitality of the character                               }}&lt;br /&gt;
{{sqltablerow|int            | INTEGER     | NOT NULL         |                 | intelligence of the character                           }}&lt;br /&gt;
{{sqltablerow|will           | INTEGER     | NOT NULL         |                 | willpower of the character                              }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Concerns ====&lt;br /&gt;
&lt;br /&gt;
* The way experience is part of this table really won&#039;t scale and isn&#039;t flexible in any way. It&#039;s currently already way too many variables in one table row, and these are just the weapon skills. So I think we should really have a separate table for storing skill levels similar to the character inventory table below. So something that has { character_id, skill_id, experience }. The &amp;lt;code&amp;gt;skill_id&amp;lt;/code&amp;gt; should point to a &amp;lt;code&amp;gt;skills.xml&amp;lt;/code&amp;gt; file which describes (and categorizes) each skill. In that way we&#039;ll be able to easily change the set of skills and their names later. --[[User:BjÃ¸rn|BjÃ¸rn]] 18:09, 12 September 2008 (CEST)&lt;br /&gt;
** I think the same should be done with the attributes (str .. will). In theory almost every attribute in this table could be handled that way, it might look like a mess, but would be really friendly in customizing the gameplay elements. --[[User:Kess|kess]] 19:54, 12 September 2008 (CEST)&lt;br /&gt;
** I agree with that completely as this will give us more flexibility and a much more relational database design. I&#039;ve extended the &amp;quot;DAL improvements&amp;quot; task in mantis: #424 --[[User:Exceptionfault|Exceptionfault]] 15:50, 14 September 2008 (CEST)&lt;br /&gt;
*** Thanks for taking out the skills from this table. However, I disagree about generalizing stuff on the level of attributes, unless there would be any plan of putting infrastructure in place to make this possible. For now we can&#039;t even finish a server for The Mana World within years, so please don&#039;t try to build a server that supports any online RPG just yet. I only suggested we take out the skills because it would be completely unmanageable as part of this table, but the list of attribute is not expected to change for now. --[[User:BjÃ¸rn|BjÃ¸rn]] 15:55, 22 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
=== Character attributes ===&lt;br /&gt;
&lt;br /&gt;
This table is intended to store skills and experiences of each character. &lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_char_skills}}&lt;br /&gt;
{{sqltablerow|char_id         | INTEGER     | NOT NULL | tmw_characters.id | reference to the character                    }}&lt;br /&gt;
{{sqltablerow|skill_id        | INTEGER     | NOT NULL | (skills.xml)      | reference to the skill                        }}&lt;br /&gt;
{{sqltablerow|exp             | INTEGER     | NOT NULL |                   | current experience of the char in this skill  }} &lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Concerns ====&lt;br /&gt;
&lt;br /&gt;
* I&#039;m not sure, if an INTEGER does the job for column exp? --[[User:Exceptionfault|Exceptionfault]] 14:40, 19 September 2008 (CEST)&lt;br /&gt;
** What is the range? I would expect it to be enough. --[[User:BjÃ¸rn|BjÃ¸rn]] 15:56, 22 September 2008 (CEST)&lt;br /&gt;
*** Hereâ€™s some basic info:&lt;br /&gt;
***: &#039;&#039;&#039;MySQL:&#039;&#039;&#039; INTEGER (INT) may be signed or unsigned and is 4 bytes large, MySQL also have 1, 2, 3 and 8 byte integer variants (TINYINT, SMALLINT, MEDIUMINT and BIGINT) [http://dev.mysql.com/doc/refman/6.0/en/numeric-types.html]&lt;br /&gt;
***: &#039;&#039;&#039;PostgreSQL:&#039;&#039;&#039; INTEGER (INT, INT4) is signed and 4 bytes large, PostgreSQL also have 2 and 8 byte integer variants (SMALLINT and BIGINT) [http://www.postgresql.org/docs/8.3/interactive/datatype-numeric.html]&lt;br /&gt;
***: &#039;&#039;&#039;SQLite:&#039;&#039;&#039; INTEGER is signed and size is either 1, 2, 3, 4, 6 or 8 bytes depending on the size of the value [http://sqlite.org/datatype3.html]&lt;br /&gt;
***: So, the largest integer type supported should be of 8 byte size (signed): from -9,223,372,036,854,775,808 to +9,223,372,036,854,775,807, while the â€œstandardâ€ (of the SQL variants above) signed 4 byte integer ranges from -2,147,483,648 to +2,147,483,647. --[[User:Kess|kess]] 21:18, 22 September 2008 (CEST)&lt;br /&gt;
*** Although we plan to have no fixed level cap I considered a skill level of about 100 to be the highest reasonable value a player can archieve. Level 100 requires an exp sum of 10 million with the current exp formula (levelÂ³ * 10) which fits into a 4 byte integer easily. We won&#039;t get in trouble with 32bit signed integers until the players get near skill level 600 (2.16 billion). The server and the netcode also use 32 bit integers internally.&lt;br /&gt;
&lt;br /&gt;
=== Character Inventory ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_inventories}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY      |                   | unique id of the item                          }}&lt;br /&gt;
{{sqltablerow|owner_id       | INTEGER     | NOT NULL         | tmw_characters.id | id of the owning character                     }}&lt;br /&gt;
{{sqltablerow|slot           | INTEGER     | NOT NULL         |                   | inventory slot where the item is equipped      }}&lt;br /&gt;
{{sqltablerow|class_id       | INTEGER     | NOT NULL         |                   | type of the item, see items.xml file of tmwserv}}&lt;br /&gt;
{{sqltablerow|amount         | INTEGER     | NOT NULL         |                   | amount of items per slot                       }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Comments ====&lt;br /&gt;
* While I havenâ€™t looked how this table is used (my C++ knowledge is rather basic) it seems quite rigid and unflexible (as BjÃ¸rn noted above for the &#039;&#039;&#039;tmw_characters&#039;&#039;&#039; table). I think it would be nicer to have something like {&#039;&#039;owner_id&#039;&#039; FK, &#039;&#039;slot&#039;&#039;, &#039;&#039;item_id&#039;&#039; FK, &#039;&#039;amount&#039;&#039;, PK owner_id + slot}, where class_id shouldnâ€™t directly be needed in this table. --[[User:Kess|kess]] 19:49, 12 September 2008 (CEST)&lt;br /&gt;
* Concerning new features like houses, bank accounts, chests or similar, i think the design of this table needs some more roundtrips. You will need a column which indicates if the item is carried by the character or stored in a chest or in a house; as it makes no sense to have a table for every possible storage type or location. Another point is, that items should be more individualizable (is this a real word? :)). Think about custom colored shirts. So we will need at least one additional table to store individual attributes of items. --[[User:Exceptionfault|Exceptionfault]] 16:02, 14 September 2008 (CEST)&lt;br /&gt;
** We want all equipment to be completely individual with completely unique stats. --[[User:Crush2|Crush2]] 16:13, 14 September 2008 (CEST)&lt;br /&gt;
*** Good to know, so I will extend the DAL improvement task in mantis. --[[User:Exceptionfault|Exceptionfault]] 16:20, 14 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
=== Guilds ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_guilds}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY     |  | unique id of the guid   }}&lt;br /&gt;
{{sqltablerow|name           | TEXT        | NOT NULL UNIQUE |  | unique name of the guild}}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Guild memberships ===&lt;br /&gt;
&lt;br /&gt;
The table &#039;&#039;tmw_guild_members&#039;&#039; stores informations which character is member in which guild and which rights does he has.&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_guild_members}}&lt;br /&gt;
{{sqltablerow|guild_id        | INTEGER     | NOT NULL | tmw_guilds.id     | reference to the guild                                                }}&lt;br /&gt;
{{sqltablerow|member_id       | INTEGER     | NOT NULL | tmw_characters.id | reference to the characters                                           }}&lt;br /&gt;
{{sqltablerow|rights          | INTEGER     | NOT NULL |                   | id showing the rights a character has in this guild (member, admin...)}}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== World state ===&lt;br /&gt;
&lt;br /&gt;
The table &#039;&#039;tmw_world_state&#039;&#039; is used to store persistent informations about the world or individual maps.&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_world_state}}&lt;br /&gt;
{{sqltablerow| state_name      | TEXT     | PRIMARY KEY |             | unique name of a state variable        }} &lt;br /&gt;
{{sqltablerow| map_id          | INTEGER  | NULL        | tmw_maps.id | reference to a map, see details        }}&lt;br /&gt;
{{sqltablerow| value           | TEXT     | NULL        |             | string value of the state              }}&lt;br /&gt;
{{sqltablerow| moddate         | INTEGER  | NOT NULL    |             | date and time of the last modification }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Details ====&lt;br /&gt;
&lt;br /&gt;
* The column &#039;&#039;state_name&#039;&#039; forms the primary key of the table. If &#039;&#039;map_id&#039;&#039; is null, the variable is used globally in the world, otherwise the variable is specific for a map.&lt;br /&gt;
* &#039;&#039;moddate&#039;&#039; is for informational use only as it contains the unixtimestamp of the last modification.&lt;br /&gt;
&lt;br /&gt;
==== Comments ====&lt;br /&gt;
&lt;br /&gt;
* It seems that SQLite doesn&#039;t support composite primary keys (span PK over multiple columns). Therefore it is not possible to allow multiple &#039;&#039;state_name&#039;&#039;s with different &#039;&#039;map_id&#039;&#039;s. So we set a &#039;&#039;state_name&#039;&#039; to unique and use &#039;&#039;map_id&#039;&#039; as notifier if this variable is globally used or just locally for a specific map. --[[User:Exceptionfault|Exceptionfault]] 11:05, 15 September 2008 (CEST)&lt;br /&gt;
** This table is ready for usage, commited as rev. 4629 --[[User:Exceptionfault|Exceptionfault]] 13:51, 15 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Quest states ===&lt;br /&gt;
&lt;br /&gt;
This table is used to store states of quests per character, e.g. if a character has just finished a quest or is currently at the second part of the long journey...&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_quests}}&lt;br /&gt;
{{sqltablerow|owner_id        | INTEGER     | NOT NULL | tmw_characters.id | reference to the character         }}&lt;br /&gt;
{{sqltablerow|name            | TEXT        | NOT NULL |                   | name of the quest variable         }}&lt;br /&gt;
{{sqltablerow|value           | TEXT        | NOT NULL |                   | current value of the quest variable}} &lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Comments ====&lt;br /&gt;
&lt;br /&gt;
* Unless this table is adapted so that it stores the state of a particular quest, this one should have a name which makes it move obvious that it&#039;s storing custom values for &#039;&#039;characters&#039;&#039;. I consider that different from quests variables, which I would expect to be scoped to a certain quest (global quest variables) or quest instance (local quest variables). --[[User:BjÃ¸rn|BjÃ¸rn]] 18:16, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* We might want to have a similar table to this to store custom values for item instances, and also one for custom world-state variables. --[[User:BjÃ¸rn|BjÃ¸rn]] 18:16, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* I always wondered why Silene used the terminology &amp;quot;Quest&amp;quot; for what is basically a system to store/querry persistent character-bound integer variables which can be used for countless purposes, not just quests. I think we should rename this whole system to &amp;quot;character variable&amp;quot; in the database, server source and script bindings. --[[User:Crush2|Crush2]] 23:28, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* I agree with BjÃ¸rn concerning the additional tables for custom item values and custom world-state values. Although the name &amp;quot;tmw_quests&amp;quot; is a little bit confusing and should be renamed, I suggest keeping a table as such to store only quest states of characters and not to mix up with other persistent states. Instead we should provide a much cleaner documentation about the available quests and their persistent states that are possible. I envision something like a questbook in game, where each player can have a look at his finished quests and currently open quests, maybe with hints on the minimap, a todo list .... Besides that, we should be aware of dividing quests into &amp;quot;per-character&amp;quot;, &amp;quot;per-party&amp;quot; or global world quests.  --[[User:Exceptionfault|Exceptionfault]] 16:20, 14 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
=== Auctions ===&lt;br /&gt;
&lt;br /&gt;
Inspired by the ManaBay auction system developed by Qoal, it is planned to build a trading plattform for the whole community of players using item auctions.&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_auctions}}&lt;br /&gt;
{{sqltablerow| auction_id    | INTEGER     | PRIMARY KEY      |                     | unique id of an auction                    }}&lt;br /&gt;
{{sqltablerow| auction_state | INTEGER     | NOT NULL         |                     | current state of the auction               }}&lt;br /&gt;
{{sqltablerow| char_id       | INTEGER     | NOT NULL         | tmw_characters (id) | owner of the auction                       }}&lt;br /&gt;
{{sqltablerow| itemclass_id  | INTEGER     | NOT NULL         | items.xml           | id of the item                             }}&lt;br /&gt;
{{sqltablerow| amount        | INTEGER     | NOT NULL         |                     | amount of items to trade                   }}&lt;br /&gt;
{{sqltablerow| start_time    | INTEGER     | NOT NULL         |                     | date of creation or start of auction       }}&lt;br /&gt;
{{sqltablerow| start_price   | INTEGER     | NOT NULL         |                     | minimum price for the first bid            }}&lt;br /&gt;
{{sqltablerow| end_time      | INTEGER     | NULL             |                     | end of auction (unixtimestamp)             }}&lt;br /&gt;
{{sqltablerow| min_price     | INTEGER     | NULL             |                     | minimum price for the final bid to succeed }}&lt;br /&gt;
{{sqltablerow| buyout_price  | INTEGER     | NULL             |                     | price for direct buy of bidded item        }}&lt;br /&gt;
{{sqltablerow| description   | TEXT        | NULL             |                     | optional description of an auction         }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Annotations ====&lt;br /&gt;
&lt;br /&gt;
* auction_state can have the following values:&lt;br /&gt;
** 0 = The auction is created by the owner but not yet published&lt;br /&gt;
** 1 = The auction is published and ready for bitters&lt;br /&gt;
** 2 = The auction has finished and closed&lt;br /&gt;
* start_time depends on the current state of the auction. If the auction is in state 0, the column contains the creation date of the auction. If it switches to &amp;quot;open&amp;quot; the date has to be refresehd to contain the start date of the auction. Format: Unixtimestamp&lt;br /&gt;
* end_time is empty unless the auction has started. The owner has to define the duration of an auction when he changes the state to &amp;quot;open&amp;quot;. Format: Unixtimestamp&lt;br /&gt;
&lt;br /&gt;
== Reference  ==&lt;br /&gt;
&lt;br /&gt;
Since the database is changing relatively often while we&#039;re still developing 0.1.0 and nobody likes to keep this page up to date, here is the link to the source code that specifies creation of the database tables. The source code is always right!&lt;br /&gt;
&lt;br /&gt;
* [http://themanaworld.svn.sourceforge.net/viewvc/themanaworld/tmwserv/trunk/src/account-server/dalstoragesql.hpp?view=markup View dalstoragesql.hpp]&lt;br /&gt;
* [http://themanaworld.svn.sourceforge.net/viewvc/*checkout*/themanaworld/tmwserv/trunk/src/account-server/dalstoragesql.hpp?revision=4024 Download dalstoragesql.hpp (plain text)]&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Database_specifications&amp;diff=10173</id>
		<title>Archive:Database specifications</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Database_specifications&amp;diff=10173"/>
		<updated>2008-09-19T12:40:53Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: refreshed tmw_char_skills table and modified tmw_characters&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Category_programming}}&lt;br /&gt;
&lt;br /&gt;
== SQL table specifications ==&lt;br /&gt;
&lt;br /&gt;
=== User accounts ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_accounts}}&lt;br /&gt;
{{sqltablerow| id            | INTEGER     | PRIMARY KEY      | | unique id of an account}}                      }}&lt;br /&gt;
{{sqltablerow|username       | TEXT        | NOT NULL UNIQUE  | | username / loginname of an user                }}&lt;br /&gt;
{{sqltablerow|password       | TEXT        | NOT NULL         | | password of an user (sha256 encoded)           }}&lt;br /&gt;
{{sqltablerow|email          | TEXT        | NOT NULL         | | email (sha256 encoded, only for pwd recovery)  }}&lt;br /&gt;
{{sqltablerow|level          | INTEGER     | NOT NULL         | | numeric level of the user account              }}&lt;br /&gt;
{{sqltablerow|banned         | INTEGER     | NOT NULL         | | unixtimestamp until when the account is banned }}&lt;br /&gt;
{{sqltablerow|registration   | INTEGER     | NOT NULL         | | unixtimestamp of account registration          }}&lt;br /&gt;
{{sqltablerow|lastlogin      | INTEGER     | NOT NULL         | | unixtimestamp of last login with client        }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Details ====&lt;br /&gt;
* email&lt;br /&gt;
** The email is stored as a one-way sha256 hash value. This ensures, that the email address a user enters cannot be used to send spam mails. It is only used to validate the mailaddress during password recovery procedure.&lt;br /&gt;
* level&lt;br /&gt;
** describes the user rights in the game (10 = normal user, 50 = gm, 99 = administrator)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Characters ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_characters}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY      |                 | unique id of the character                              }}&lt;br /&gt;
{{sqltablerow|user_id        | INTEGER     | NOT NULL         | tmw_accounts.id | id of the owner                                         }}&lt;br /&gt;
{{sqltablerow|name           | TEXT        | NOT NULL UNIQUE  |                 | name of the character                                   }}&lt;br /&gt;
{{sqltablerow|gender         | INTEGER     | NOT NULL         |                 | gender of the character (0/1)                           }}&lt;br /&gt;
{{sqltablerow|hair_style     | INTEGER     | NOT NULL         |                 | id of the hair sprite                                   }}&lt;br /&gt;
{{sqltablerow|hair_color     | INTEGER     | NOT NULL         |                 | id of the hair color                                    }}&lt;br /&gt;
{{sqltablerow|level          | INTEGER     | NOT NULL         |                 | experience level of the character                       }}&lt;br /&gt;
{{sqltablerow|char_pts       | INTEGER     | NOT NULL         |                 | available points to raise attributes                    }}&lt;br /&gt;
{{sqltablerow|correct_pts    | INTEGER     | NOT NULL         |                 | available points to lower attributes and regain char_pts}}&lt;br /&gt;
{{sqltablerow|money          | INTEGER     | NOT NULL         |                 | GP of the character                                     }}&lt;br /&gt;
{{sqltablerow|x              | INTEGER     | NOT NULL         |                 | x position of the character on the map                  }}&lt;br /&gt;
{{sqltablerow|y              | INTEGER     | NOT NULL         |                 | y position of the character on the map                  }}&lt;br /&gt;
{{sqltablerow|map_id         | INTEGER     | NOT NULL         | tmw_maps.id     | id of the current map the character is located          }}&lt;br /&gt;
{{sqltablerow|str            | INTEGER     | NOT NULL         |                 | strength of the character                               }}&lt;br /&gt;
{{sqltablerow|agi            | INTEGER     | NOT NULL         |                 | agility of the character                                }}&lt;br /&gt;
{{sqltablerow|dex            | INTEGER     | NOT NULL         |                 | dexternity of the character                             }}&lt;br /&gt;
{{sqltablerow|vit            | INTEGER     | NOT NULL         |                 | vitality of the character                               }}&lt;br /&gt;
{{sqltablerow|int            | INTEGER     | NOT NULL         |                 | intelligence of the character                           }}&lt;br /&gt;
{{sqltablerow|will           | INTEGER     | NOT NULL         |                 | willpower of the character                              }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Concerns ====&lt;br /&gt;
&lt;br /&gt;
* The way experience is part of this table really won&#039;t scale and isn&#039;t flexible in any way. It&#039;s currently already way too many variables in one table row, and these are just the weapon skills. So I think we should really have a separate table for storing skill levels similar to the character inventory table below. So something that has { character_id, skill_id, experience }. The &amp;lt;code&amp;gt;skill_id&amp;lt;/code&amp;gt; should point to a &amp;lt;code&amp;gt;skills.xml&amp;lt;/code&amp;gt; file which describes (and categorizes) each skill. In that way we&#039;ll be able to easily change the set of skills and their names later. --[[User:BjÃ¸rn|BjÃ¸rn]] 18:09, 12 September 2008 (CEST)&lt;br /&gt;
** I think the same should be done with the attributes (str .. will). In theory almost every attribute in this table could be handled that way, it might look like a mess, but would be really friendly in customizing the gameplay elements. --[[User:Kess|kess]] 19:54, 12 September 2008 (CEST)&lt;br /&gt;
** I agree with that completely as this will give us more flexibility and a much more relational database design. I&#039;ve extended the &amp;quot;DAL improvements&amp;quot; task in mantis: #424 --[[User:Exceptionfault|Exceptionfault]] 15:50, 14 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
=== Character attributes ===&lt;br /&gt;
&lt;br /&gt;
This table is intended to store skills and experiences of each character. &lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_char_skills}}&lt;br /&gt;
{{sqltablerow|char_id         | INTEGER     | NOT NULL | tmw_characters.id | reference to the character                    }}&lt;br /&gt;
{{sqltablerow|skill_id        | INTEGER     | NOT NULL | (skills.xml)      | reference to the skill                        }}&lt;br /&gt;
{{sqltablerow|exp             | INTEGER     | NOT NULL |                   | current experience of the char in this skill  }} &lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Concerns ====&lt;br /&gt;
&lt;br /&gt;
* I&#039;am not sure, if an INTEGER does the job for column exp? --[[User:Exceptionfault|Exceptionfault]] 14:40, 19 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Character Inventory ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_inventories}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY      |                   | unique id of the item                          }}&lt;br /&gt;
{{sqltablerow|owner_id       | INTEGER     | NOT NULL         | tmw_characters.id | id of the owning character                     }}&lt;br /&gt;
{{sqltablerow|slot           | INTEGER     | NOT NULL         |                   | inventory slot where the item is equipped      }}&lt;br /&gt;
{{sqltablerow|class_id       | INTEGER     | NOT NULL         |                   | type of the item, see items.xml file of tmwserv}}&lt;br /&gt;
{{sqltablerow|amount         | INTEGER     | NOT NULL         |                   | amount of items per slot                       }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Comments ====&lt;br /&gt;
* While I havenâ€™t looked how this table is used (my C++ knowledge is rather basic) it seems quite rigid and unflexible (as BjÃ¸rn noted above for the &#039;&#039;&#039;tmw_characters&#039;&#039;&#039; table). I think it would be nicer to have something like {&#039;&#039;owner_id&#039;&#039; FK, &#039;&#039;slot&#039;&#039;, &#039;&#039;item_id&#039;&#039; FK, &#039;&#039;amount&#039;&#039;, PK owner_id + slot}, where class_id shouldnâ€™t directly be needed in this table. --[[User:Kess|kess]] 19:49, 12 September 2008 (CEST)&lt;br /&gt;
* Concerning new features like houses, bank accounts, chests or similar, i think the design of this table needs some more roundtrips. You will need a column which indicates if the item is carried by the character or stored in a chest or in a house; as it makes no sense to have a table for every possible storage type or location. Another point is, that items should be more individualizable (is this a real word? :)). Think about custom colored shirts. So we will need at least one additional table to store individual attributes of items. --[[User:Exceptionfault|Exceptionfault]] 16:02, 14 September 2008 (CEST)&lt;br /&gt;
** We want all equipment to be completely individual with completely unique stats. --[[User:Crush2|Crush2]] 16:13, 14 September 2008 (CEST)&lt;br /&gt;
*** Good to know, so I will extend the DAL improvement task in mantis. --[[User:Exceptionfault|Exceptionfault]] 16:20, 14 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
=== Guilds ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_guilds}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY     |  | unique id of the guid   }}&lt;br /&gt;
{{sqltablerow|name           | TEXT        | NOT NULL UNIQUE |  | unique name of the guild}}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Guild memberships ===&lt;br /&gt;
&lt;br /&gt;
The table &#039;&#039;tmw_guild_members&#039;&#039; stores informations which character is member in which guild and which rights does he has.&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_guild_members}}&lt;br /&gt;
{{sqltablerow|guild_id        | INTEGER     | NOT NULL | tmw_guilds.id     | reference to the guild                                                }}&lt;br /&gt;
{{sqltablerow|member_id       | INTEGER     | NOT NULL | tmw_characters.id | reference to the characters                                           }}&lt;br /&gt;
{{sqltablerow|rights          | INTEGER     | NOT NULL |                   | id showing the rights a character has in this guild (member, admin...)}}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== World state ===&lt;br /&gt;
&lt;br /&gt;
The table &#039;&#039;tmw_world_state&#039;&#039; is used to store persistent informations about the world or individual maps.&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_world_state}}&lt;br /&gt;
{{sqltablerow| state_name      | TEXT     | PRIMARY KEY |             | unique name of a state variable        }} &lt;br /&gt;
{{sqltablerow| map_id          | INTEGER  | NULL        | tmw_maps.id | reference to a map, see details        }}&lt;br /&gt;
{{sqltablerow| value           | TEXT     | NULL        |             | string value of the state              }}&lt;br /&gt;
{{sqltablerow| moddate         | INTEGER  | NOT NULL    |             | date and time of the last modification }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Details ====&lt;br /&gt;
&lt;br /&gt;
* The column &#039;&#039;state_name&#039;&#039; forms the primary key of the table. If &#039;&#039;map_id&#039;&#039; is null, the variable is used globally in the world, otherwise the variable is specific for a map.&lt;br /&gt;
* &#039;&#039;moddate&#039;&#039; is for informational use only as it contains the unixtimestamp of the last modification.&lt;br /&gt;
&lt;br /&gt;
==== Comments ====&lt;br /&gt;
&lt;br /&gt;
* It seems that SQLite doesn&#039;t support composite primary keys (span PK over multiple columns). Therefore it is not possible to allow multiple &#039;&#039;state_name&#039;&#039;s with different &#039;&#039;map_id&#039;&#039;s. So we set a &#039;&#039;state_name&#039;&#039; to unique and use &#039;&#039;map_id&#039;&#039; as notifier if this variable is globally used or just locally for a specific map. --[[User:Exceptionfault|Exceptionfault]] 11:05, 15 September 2008 (CEST)&lt;br /&gt;
** This table is ready for usage, commited as rev. 4629 --[[User:Exceptionfault|Exceptionfault]] 13:51, 15 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Quest states ===&lt;br /&gt;
&lt;br /&gt;
This table is used to store states of quests per character, e.g. if a character has just finished a quest or is currently at the second part of the long journey...&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_quests}}&lt;br /&gt;
{{sqltablerow|owner_id        | INTEGER     | NOT NULL | tmw_characters.id | reference to the character         }}&lt;br /&gt;
{{sqltablerow|name            | TEXT        | NOT NULL |                   | name of the quest variable         }}&lt;br /&gt;
{{sqltablerow|value           | TEXT        | NOT NULL |                   | current value of the quest variable}} &lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Comments ====&lt;br /&gt;
&lt;br /&gt;
* Unless this table is adapted so that it stores the state of a particular quest, this one should have a name which makes it move obvious that it&#039;s storing custom values for &#039;&#039;characters&#039;&#039;. I consider that different from quests variables, which I would expect to be scoped to a certain quest (global quest variables) or quest instance (local quest variables). --[[User:BjÃ¸rn|BjÃ¸rn]] 18:16, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* We might want to have a similar table to this to store custom values for item instances, and also one for custom world-state variables. --[[User:BjÃ¸rn|BjÃ¸rn]] 18:16, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* I always wondered why Silene used the terminology &amp;quot;Quest&amp;quot; for what is basically a system to store/querry persistent character-bound integer variables which can be used for countless purposes, not just quests. I think we should rename this whole system to &amp;quot;character variable&amp;quot; in the database, server source and script bindings. --[[User:Crush2|Crush2]] 23:28, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* I agree with BjÃ¸rn concerning the additional tables for custom item values and custom world-state values. Although the name &amp;quot;tmw_quests&amp;quot; is a little bit confusing and should be renamed, I suggest keeping a table as such to store only quest states of characters and not to mix up with other persistent states. Instead we should provide a much cleaner documentation about the available quests and their persistent states that are possible. I envision something like a questbook in game, where each player can have a look at his finished quests and currently open quests, maybe with hints on the minimap, a todo list .... Besides that, we should be aware of dividing quests into &amp;quot;per-character&amp;quot;, &amp;quot;per-party&amp;quot; or global world quests.  --[[User:Exceptionfault|Exceptionfault]] 16:20, 14 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Reference  ==&lt;br /&gt;
&lt;br /&gt;
Since the database is changing relatively often while we&#039;re still developing 0.1.0 and nobody likes to keep this page up to date, here is the link to the source code that specifies creation of the database tables. The source code is always right!&lt;br /&gt;
&lt;br /&gt;
* [http://themanaworld.svn.sourceforge.net/viewvc/themanaworld/tmwserv/trunk/src/account-server/dalstoragesql.hpp?view=markup View dalstoragesql.hpp]&lt;br /&gt;
* [http://themanaworld.svn.sourceforge.net/viewvc/*checkout*/themanaworld/tmwserv/trunk/src/account-server/dalstoragesql.hpp?revision=4024 Download dalstoragesql.hpp (plain text)]&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=Template:Paramtablerow&amp;diff=10169</id>
		<title>Template:Paramtablerow</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=Template:Paramtablerow&amp;diff=10169"/>
		<updated>2008-09-19T07:02:59Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;|- style=&amp;quot;background-color: white;&amp;quot;&lt;br /&gt;
|style=&amp;quot;border-right: 1px solid lightgrey; padding-right: 10px;&amp;quot;|&amp;lt;tt&amp;gt;{{{1}}}&amp;lt;/tt&amp;gt;&lt;br /&gt;
|style=&amp;quot;border-right: 1px solid lightgrey; padding-right: 10px;&amp;quot;|{{{2}}}&lt;br /&gt;
|style=&amp;quot;border-right: 1px solid lightgrey; padding-right: 10px;&amp;quot;|{{{3}}}&lt;br /&gt;
|style=&amp;quot;padding-right: 10px;&amp;quot;|{{{4}}}&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=Template:Paramtablerow&amp;diff=10168</id>
		<title>Template:Paramtablerow</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=Template:Paramtablerow&amp;diff=10168"/>
		<updated>2008-09-19T07:02:09Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;|- style=&amp;quot;background-color: white;&amp;quot;&lt;br /&gt;
|style=&amp;quot;border-right: 1px solid lightgrey;&amp;quot;|&amp;lt;tt&amp;gt;{{{1}}}&amp;lt;/tt&amp;gt;&lt;br /&gt;
|style=&amp;quot;border-right: 1px solid lightgrey;&amp;quot;|{{{2}}}&lt;br /&gt;
|style=&amp;quot;border-right: 1px solid lightgrey;&amp;quot;|{{{3}}}&lt;br /&gt;
||{{{4}}}&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=Template:Paramtablerow&amp;diff=10167</id>
		<title>Template:Paramtablerow</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=Template:Paramtablerow&amp;diff=10167"/>
		<updated>2008-09-19T07:00:29Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;|-&lt;br /&gt;
|style=&amp;quot;border-right: 1px solid lightgrey;&amp;quot;|&amp;lt;tt&amp;gt;{{{1}}}&amp;lt;/tt&amp;gt;&lt;br /&gt;
|style=&amp;quot;border-right: 1px solid lightgrey;&amp;quot;|{{{2}}}&lt;br /&gt;
|style=&amp;quot;border-right: 1px solid lightgrey;&amp;quot;|{{{3}}}&lt;br /&gt;
||{{{4}}}&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=Template:Endparamtable&amp;diff=10166</id>
		<title>Template:Endparamtable</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=Template:Endparamtable&amp;diff=10166"/>
		<updated>2008-09-19T06:52:31Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;|}&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=Template:Paramtablerow&amp;diff=10165</id>
		<title>Template:Paramtablerow</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=Template:Paramtablerow&amp;diff=10165"/>
		<updated>2008-09-19T06:52:07Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;|-&lt;br /&gt;
|style=&amp;quot;border-right: 1px solid lightgrey;&amp;quot;|{{{1}}}&lt;br /&gt;
|style=&amp;quot;border-right: 1px solid lightgrey;&amp;quot;|{{{2}}}&lt;br /&gt;
|style=&amp;quot;border-right: 1px solid lightgrey;&amp;quot;|{{{3}}}&lt;br /&gt;
|{{{4}}}&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=Template:Beginparamtable&amp;diff=10164</id>
		<title>Template:Beginparamtable</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=Template:Beginparamtable&amp;diff=10164"/>
		<updated>2008-09-19T06:51:06Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{|cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;1&amp;quot; style=&amp;quot;border: 1px solid lightgray;&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
{|- cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;3&amp;quot; style=&amp;quot;background-color: #eeeeee;&amp;quot; &lt;br /&gt;
! Parameter name !! Required !! Default value !! Description&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Database_Installation&amp;diff=10161</id>
		<title>Archive:Database Installation</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Database_Installation&amp;diff=10161"/>
		<updated>2008-09-19T06:39:36Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: User:Exceptionfault/Database Installation moved to Database Installation: the state is acceptable now&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;This page is currently WIP and should describe how to set up the database for a new installation of tmwserv. This page should be moved to [[Setting up a server]] when finished.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Before you can set up your own server you have to decide wich database backend you want to use. Currently, the server supports three different types of database backends:&lt;br /&gt;
* mySQL&lt;br /&gt;
* SQLite&lt;br /&gt;
* PostgreSQL&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Settings up mySQL ==&lt;br /&gt;
&lt;br /&gt;
=== Requirements === &lt;br /&gt;
&lt;br /&gt;
To run tmwserv with mySQL you should use a mySQL version &amp;gt;= 5.0.*. It was tested sucessfully with 5.0.51a.&lt;br /&gt;
Also you have to enable the [http://dev.mysql.com/doc/refman/5.0/en/innodb.html InnoDB] storage engine as tmwserv makes use of the relational and transactional features. &lt;br /&gt;
&lt;br /&gt;
=== Creating a database and a user ===&lt;br /&gt;
&lt;br /&gt;
This chapter assumes, that you still have little experience working with mysql, so it does not describe how to install mysql itself. The first step to get tmwserv running under mySQL would be the creation of a database and a user. As you can easily do this with graphical frontends like [http://www.phpmyadmin.net phpMyAdmin], we will give you a handy script for doing that from command line. Don&#039;t forget to replace the placeholders with appropriate values for your environment. &lt;br /&gt;
&lt;br /&gt;
For the following commands you have to be logged in as a database administrator, preferable &#039;&#039;root&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
 -- create a user called tmw (modify this as you whish)&lt;br /&gt;
 -- the &#039;localhost&#039; says, that our new user is only allowed from our local machine&lt;br /&gt;
 CREATE USER &#039;tmw&#039;@&#039;localhost&#039; IDENTIFIED BY &#039;&amp;lt;insert your password preferred here&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
 -- allow the user to connect to the server without any resource limitations&lt;br /&gt;
 GRANT USAGE ON * . * TO &#039;tmw&#039;@&#039;localhost&#039; IDENTIFIED BY &#039;&amp;lt;again your pwd&amp;gt;&#039; &lt;br /&gt;
    WITH MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0 ;&lt;br /&gt;
&lt;br /&gt;
 -- create a new database called &#039;tmw&#039; but you can name it just as you like&lt;br /&gt;
 CREATE DATABASE IF NOT EXISTS `tmw` ;&lt;br /&gt;
&lt;br /&gt;
 -- give our new user full privileges on our new created database&lt;br /&gt;
 GRANT ALL PRIVILEGES ON `tmw` . * TO &#039;tmw&#039;@&#039;localhost&#039;;&lt;br /&gt;
    &lt;br /&gt;
Summarized, now we have a new database called &#039;&#039;tmw&#039;&#039;, a new database user &#039;&#039;tmw&#039;&#039; that has full rights in his database, and a restriction, that he is only able to connect from localhost.&lt;br /&gt;
&lt;br /&gt;
=== Create database tables ===&lt;br /&gt;
&lt;br /&gt;
If our new database user is ready for use, we have to create all necessary tables. The installation of tmwserv provides you with a ready to use database script. You can find this script under &#039;&#039;./src/sql/mysql/createTables.sql&#039;&#039; To run this script connect as user tmw with your database.&lt;br /&gt;
&lt;br /&gt;
 mysql --host localhost --user tmw --password --database tmw --no-beep&lt;br /&gt;
&lt;br /&gt;
After typing your password you should be connected to the database. The command &#039;&#039;\.&#039;&#039; runs a database script.&lt;br /&gt;
&lt;br /&gt;
 \. &amp;lt;path to the script&amp;gt;/createTables.sql&lt;br /&gt;
 -- e.g.&lt;br /&gt;
 \. ~/tmwserv/src/sql/mysql/createTables.sql&lt;br /&gt;
&lt;br /&gt;
=== Configuring tmwserv to use the database ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TODO&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Settings up SQLite ==&lt;br /&gt;
&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
&lt;br /&gt;
Tmwserv has been tested with SQLite version 3.5.8&lt;br /&gt;
&lt;br /&gt;
=== Preparation of database file ===&lt;br /&gt;
&lt;br /&gt;
The creation of a new database file is very easy. Just go to the directory where you want to create it and type:&lt;br /&gt;
&lt;br /&gt;
 sqlite3 &amp;lt;name of the file&amp;gt;&lt;br /&gt;
 sqlite3 tmw.db&lt;br /&gt;
&lt;br /&gt;
After this you should be &amp;quot;connected&amp;quot; to the database file and ready to create the necessary tables. We provide you with a ready to use installation script that could be found under &#039;&#039;./src/sql/sqlite/createTables.sql&#039;&#039;. To execute the script type the following while connected with sqlite:&lt;br /&gt;
&lt;br /&gt;
 .read &amp;lt;path and filename of the script&amp;gt;&lt;br /&gt;
 .read ~/tmwserv/src/sql/sqlite/createTables.sql&lt;br /&gt;
&lt;br /&gt;
To verify if the installation was sucessfull just type&lt;br /&gt;
 .tables&lt;br /&gt;
which should give you a list of tmw_* tables.&lt;br /&gt;
&lt;br /&gt;
=== Configuring tmwserv to use the database ===&lt;br /&gt;
&lt;br /&gt;
Before starting tmwserv you have to configure the account server where your database file is located. Tmwserv uses a XML file called &#039;&#039;tmwserv.xml&#039;&#039; with an easy to read &#039;&#039;key = value&#039;&#039; structure. Locate the option &#039;&#039;sqlite_database&#039;&#039; and modify the value attribute according to your environment. You can use a relative path starting at the location of your tmwserv executeable. &lt;br /&gt;
 &amp;lt;option name=&amp;quot;sqlite_database&amp;quot; value=&amp;quot;./tmw.db&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Settings up PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TODO&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Executing_SQL_Statements&amp;diff=10160</id>
		<title>Archive:Executing SQL Statements</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Executing_SQL_Statements&amp;diff=10160"/>
		<updated>2008-09-19T06:36:38Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: /* Comments */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Category_programming}}&lt;br /&gt;
&lt;br /&gt;
== Executing SQL Statements from C++ ==&lt;br /&gt;
&lt;br /&gt;
The current Data access layer (DAL) of tmwserv provides an abstract interface to execute SQL statements against several types of database engines. SQL statement can be executed using 2 different methods whereas the second one is the preferred way.&lt;br /&gt;
&lt;br /&gt;
=== using execSQL method ===&lt;br /&gt;
&lt;br /&gt;
The easiest way to execute SQL statement is to call the &#039;&#039;execSql&#039;&#039; method, providing the statement as complete string. As this looks very simple and comes as a one-liner, you have to be aware of [http://en.wikipedia.org/wiki/SQL_Injection SQL injection attacks].&lt;br /&gt;
&lt;br /&gt;
 const RecordSet&amp;amp; execSql(const std::string&amp;amp; sql, const bool refresh = false)&lt;br /&gt;
 const RecordSet&amp;amp; info = mDb-&amp;gt;execSql(&amp;quot;SELECT x FROM y WHERE z = &#039;a&#039;&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
=== Using prepared Statements ===&lt;br /&gt;
&lt;br /&gt;
The secure way in executing sql, without having to worry about sql injection attacks, is to use prepared statements and bind variables. Many database systems are even faster when using them, because the internal memory can be used much more efficiently.&lt;br /&gt;
To execute a statement using bind variables, you have to do the following steps:&lt;br /&gt;
# Write your SQL statement containing placeholdes instead of final values&lt;br /&gt;
# Let the dataprovider parse and prepare your statement&lt;br /&gt;
# Bind the final values to your prepared statement&lt;br /&gt;
# Execute the prepared statement with your bound values&lt;br /&gt;
#* Return to 3, if you have to execute the statement more than once, but with different values&lt;br /&gt;
#* Finalize the prepared statement and free memory&lt;br /&gt;
Ported to our DAL this means the following:&lt;br /&gt;
&lt;br /&gt;
 std::string sql = &amp;quot;SELECT x FROM y WHERE z = ?&amp;quot;;   // ? is used as placeholder for out final value&lt;br /&gt;
                                                    // column or table names can never be expressed as placeholders!&lt;br /&gt;
 mDb-&amp;gt;prepareStatement(sql, 1);                     // prepare the statement, define that we need 1 bind variable&lt;br /&gt;
 mDb-&amp;gt;bindParameter(&amp;quot;a&amp;quot;, 1);                        // bind value &amp;quot;a&amp;quot; as first parameter&lt;br /&gt;
 const RecordSet&amp;amp; info = mDb-&amp;gt;execStatement();      // execute statement&lt;br /&gt;
&lt;br /&gt;
As you can see, it takes a little more effort to execute a SQL statement using bind variables, but that should not frighten you doing it that way! The &#039;&#039;execStatement()&#039;&#039; methods frees up memory for you and finalizes the prepared statement. If you want to reexecute it with different bind variables have a look at the following example:&lt;br /&gt;
&lt;br /&gt;
 std::string sql = &amp;quot;INSERT INTO x (z) VALUES (?);&amp;quot;;&lt;br /&gt;
 mDb-&amp;gt;prepareStatement(sql, 1);&lt;br /&gt;
 &lt;br /&gt;
 for (int i = 1; i &amp;lt;= 10; i++)&lt;br /&gt;
 {&lt;br /&gt;
     mDb-&amp;gt;bindParameter(i, 1);&lt;br /&gt;
     mDb-&amp;gt;execStatement((i==10));&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Calling &#039;&#039;execStatement(bool)&#039;&#039; with &#039;&#039;false&#039;&#039;, resets the bound variables in the prepared statement to &#039;&#039;NULL&#039;&#039; but keeps the statement in prepared state. Only if we come to the last execution, we want to finalize and clean up everything.&lt;br /&gt;
&lt;br /&gt;
==Comments==&lt;br /&gt;
How about using a syntax similar to the printf function from the standard library instead? This would make the code more readable and less cumbersome to code than having a bindParameter call for every variable in the querry, in my opinion.&lt;br /&gt;
 std::string value1=&amp;quot;foo&amp;quot;;&lt;br /&gt;
 int value2 = 42;&lt;br /&gt;
 execSql(&amp;quot;SELECT field1 FROM table WHERE field2=%s AND field3=%i&amp;quot;, value1, value2);&lt;br /&gt;
The runQuerry function should then automatically take care of escaping any quotes in string arguments and then add quotes around them.&lt;br /&gt;
&lt;br /&gt;
:Or just bind the variables itself. &amp;amp;mdash; [[User:Jaxad0127|&amp;lt;span style=&amp;quot;color: #160196&amp;quot;&amp;gt;Jaxad&amp;lt;/span&amp;gt;]][[User Talk:Jaxad0127|&amp;lt;span style=&amp;quot;color: #5B038F&amp;quot;&amp;gt;0127&amp;lt;/span&amp;gt;]] 22:52, 18 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
:: Using bind variables in SQL is a common practice and besides the little more effort in coding it has a lot of advantages from the database point of view, not only sql injection. Assume the statement above: &lt;br /&gt;
 execSql(&amp;quot;SELECT field1 FROM table WHERE field2=%s AND field3=%i&amp;quot;, value1, value2);&lt;br /&gt;
:: The function will evaluate it with &amp;quot;SELECT field1 FROM table WHERE field2=&#039;abc&#039; AND field3=&#039;efg&#039;&amp;quot;. The next time you run the query maybe it will be &amp;quot;SELECT field1 FROM table WHERE field2=&#039;abc&#039; AND field3=&#039;xyz&#039;&amp;quot;. For the databse, this is a totally new statement. It has to parse it and create an execution plan and check for permission (in case of mysql and pgsql). The costs especially for finding an apropriate execution plan should not be underrated. Using bind variables, the database always gets the statement &amp;quot;SELECT field1 FROM table WHERE field2=? AND field3=?&amp;quot; as the &amp;quot;?&amp;quot; is a known placeholder in SQLite and MySQL. It has to parse the statement only once and can cache the execution plan. I&#039;ll present an example from oracle, but it woould be the same for MySQL:&lt;br /&gt;
&lt;br /&gt;
 declare &lt;br /&gt;
 	v_sql VARCHAR2(100);&lt;br /&gt;
 begin&lt;br /&gt;
 	for i in 0 .. 10000 loop&lt;br /&gt;
 		-- concatination i as string into sql statement&lt;br /&gt;
 		v_sql := &#039;SELECT * FROM T WHERE id = &#039; || to_char(i);&lt;br /&gt;
 		execute immediate v_sql;&lt;br /&gt;
 	end loop;&lt;br /&gt;
 end;&lt;br /&gt;
 /&lt;br /&gt;
 Elapsed: 00:00:00.59&lt;br /&gt;
 &lt;br /&gt;
 declare &lt;br /&gt;
 	v_sql VARCHAR2(100);&lt;br /&gt;
 begin&lt;br /&gt;
 	for i in 0 .. 10000 loop&lt;br /&gt;
 		-- using i as bind variable and binding during execution&lt;br /&gt;
 		v_sql := &#039;SELECT * FROM T WHERE id = :i&#039;;&lt;br /&gt;
 		execute immediate v_sql using i;&lt;br /&gt;
 	end loop;&lt;br /&gt;
 end;&lt;br /&gt;
 /&lt;br /&gt;
 Elapsed: 00:00:00.32&lt;br /&gt;
&lt;br /&gt;
:: The measurable difference: The second statements just takes 54% of the time. IMO we should not surrender using binding techniques. But I agree with Crush, maybe we can simplify the execution using paramarrays and do the magic stuff inside the dataprovider. --[[User:Exceptionfault|Exceptionfault]] 08:36, 19 September 2008 (CEST)&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Executing_SQL_Statements&amp;diff=10155</id>
		<title>Archive:Executing SQL Statements</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Executing_SQL_Statements&amp;diff=10155"/>
		<updated>2008-09-18T11:03:56Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Category_programming}}&lt;br /&gt;
&lt;br /&gt;
== Executing SQL Statements from C++ ==&lt;br /&gt;
&lt;br /&gt;
The current Data access layer (DAL) of tmwserv provides an abstract interface to execute SQL statements against several types of database engines. SQL statement can be executed using 2 different methods whereas the second one is the preferred way.&lt;br /&gt;
&lt;br /&gt;
=== using execSQL method ===&lt;br /&gt;
&lt;br /&gt;
The easiest way to execute SQL statement is to call the &#039;&#039;execSql&#039;&#039; method, providing the statement as complete string. As this looks very simple and comes as a one-liner, you have to be aware of [http://en.wikipedia.org/wiki/SQL_Injection SQL injection attacks].&lt;br /&gt;
&lt;br /&gt;
 const RecordSet&amp;amp; execSql(const std::string&amp;amp; sql, const bool refresh = false)&lt;br /&gt;
 const RecordSet&amp;amp; info = mDb-&amp;gt;execSql(&amp;quot;SELECT x FROM y WHERE z = &#039;a&#039;&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
=== Using prepared Statements ===&lt;br /&gt;
&lt;br /&gt;
The secure way in executing sql, without having to worry about sql injection attacks, is to use prepared statements and bind variables. Many database systems are even faster when using them, because the internal memory can be used much more efficiently.&lt;br /&gt;
To execute a statement using bind variables, you have to do the following steps:&lt;br /&gt;
# Write your SQL statement containing placeholdes instead of final values&lt;br /&gt;
# Let the dataprovider parse and prepare your statement&lt;br /&gt;
# Bind the final values to your prepared statement&lt;br /&gt;
# Execute the prepared statement with your bound values&lt;br /&gt;
#* Return to 3, if you have to execute the statement more than once, but with different values&lt;br /&gt;
#* Finalize the prepared statement and free memory&lt;br /&gt;
Ported to our DAL this means the following:&lt;br /&gt;
&lt;br /&gt;
 std::string sql = &amp;quot;SELECT x FROM y WHERE z = ?&amp;quot;;   // ? is used as placeholder for out final value&lt;br /&gt;
                                                    // column or table names can never be expressed as placeholders!&lt;br /&gt;
 mDb-&amp;gt;prepareStatement(sql, 1);                     // prepare the statement, define that we need 1 bind variable&lt;br /&gt;
 mDb-&amp;gt;bindParameter(&amp;quot;a&amp;quot;, 1);                        // bind value &amp;quot;a&amp;quot; as first parameter&lt;br /&gt;
 const RecordSet&amp;amp; info = mDb-&amp;gt;execStatement();      // execute statement&lt;br /&gt;
&lt;br /&gt;
As you can see, it takes a little more effort to execute a SQL statement using bind variables, but that should not frighten you doing it that way! The &#039;&#039;execStatement()&#039;&#039; methods frees up memory for you and finalizes the prepared statement. If you want to reexecute it with different bind variables have a look at the following example:&lt;br /&gt;
&lt;br /&gt;
 std::string sql = &amp;quot;INSERT INTO x (z) VALUES (?);&amp;quot;;&lt;br /&gt;
 mDb-&amp;gt;prepareStatement(sql, 1);&lt;br /&gt;
 &lt;br /&gt;
 for (int i = 1; i &amp;lt;= 10; i++)&lt;br /&gt;
 {&lt;br /&gt;
     mDb-&amp;gt;bindParameter(i, 1);&lt;br /&gt;
     mDb-&amp;gt;execStatement((i==10));&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Calling &#039;&#039;execStatement(bool)&#039;&#039; with &#039;&#039;false&#039;&#039;, resets the bound variables in the prepared statement to &#039;&#039;NULL&#039;&#039; but keeps the statement in prepared state. Only if we come to the last execution, we want to finalize and clean up everything.&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Database_Installation&amp;diff=10149</id>
		<title>Archive:Database Installation</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Database_Installation&amp;diff=10149"/>
		<updated>2008-09-17T09:35:22Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: /* Settings up SQLite */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;This page is currently WIP and should describe how to set up the database for a new installation of tmwserv. This page should be moved to [[Setting up a server]] when finished.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Before you can set up your own server you have to decide wich database backend you want to use. Currently, the server supports three different types of database backends:&lt;br /&gt;
* mySQL&lt;br /&gt;
* SQLite&lt;br /&gt;
* PostgreSQL&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Settings up mySQL ==&lt;br /&gt;
&lt;br /&gt;
=== Requirements === &lt;br /&gt;
&lt;br /&gt;
To run tmwserv with mySQL you should use a mySQL version &amp;gt;= 5.0.*. It was tested sucessfully with 5.0.51a.&lt;br /&gt;
Also you have to enable the [http://dev.mysql.com/doc/refman/5.0/en/innodb.html InnoDB] storage engine as tmwserv makes use of the relational and transactional features. &lt;br /&gt;
&lt;br /&gt;
=== Creating a database and a user ===&lt;br /&gt;
&lt;br /&gt;
This chapter assumes, that you still have little experience working with mysql, so it does not describe how to install mysql itself. The first step to get tmwserv running under mySQL would be the creation of a database and a user. As you can easily do this with graphical frontends like [http://www.phpmyadmin.net phpMyAdmin], we will give you a handy script for doing that from command line. Don&#039;t forget to replace the placeholders with appropriate values for your environment. &lt;br /&gt;
&lt;br /&gt;
For the following commands you have to be logged in as a database administrator, preferable &#039;&#039;root&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
 -- create a user called tmw (modify this as you whish)&lt;br /&gt;
 -- the &#039;localhost&#039; says, that our new user is only allowed from our local machine&lt;br /&gt;
 CREATE USER &#039;tmw&#039;@&#039;localhost&#039; IDENTIFIED BY &#039;&amp;lt;insert your password preferred here&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
 -- allow the user to connect to the server without any resource limitations&lt;br /&gt;
 GRANT USAGE ON * . * TO &#039;tmw&#039;@&#039;localhost&#039; IDENTIFIED BY &#039;&amp;lt;again your pwd&amp;gt;&#039; &lt;br /&gt;
    WITH MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0 ;&lt;br /&gt;
&lt;br /&gt;
 -- create a new database called &#039;tmw&#039; but you can name it just as you like&lt;br /&gt;
 CREATE DATABASE IF NOT EXISTS `tmw` ;&lt;br /&gt;
&lt;br /&gt;
 -- give our new user full privileges on our new created database&lt;br /&gt;
 GRANT ALL PRIVILEGES ON `tmw` . * TO &#039;tmw&#039;@&#039;localhost&#039;;&lt;br /&gt;
    &lt;br /&gt;
Summarized, now we have a new database called &#039;&#039;tmw&#039;&#039;, a new database user &#039;&#039;tmw&#039;&#039; that has full rights in his database, and a restriction, that he is only able to connect from localhost.&lt;br /&gt;
&lt;br /&gt;
=== Create database tables ===&lt;br /&gt;
&lt;br /&gt;
If our new database user is ready for use, we have to create all necessary tables. The installation of tmwserv provides you with a ready to use database script. You can find this script under &#039;&#039;./src/sql/mysql/createTables.sql&#039;&#039; To run this script connect as user tmw with your database.&lt;br /&gt;
&lt;br /&gt;
 mysql --host localhost --user tmw --password --database tmw --no-beep&lt;br /&gt;
&lt;br /&gt;
After typing your password you should be connected to the database. The command &#039;&#039;\.&#039;&#039; runs a database script.&lt;br /&gt;
&lt;br /&gt;
 \. &amp;lt;path to the script&amp;gt;/createTables.sql&lt;br /&gt;
 -- e.g.&lt;br /&gt;
 \. ~/tmwserv/src/sql/mysql/createTables.sql&lt;br /&gt;
&lt;br /&gt;
=== Configuring tmwserv to use the database ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TODO&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Settings up SQLite ==&lt;br /&gt;
&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
&lt;br /&gt;
Tmwserv has been tested with SQLite version 3.5.8&lt;br /&gt;
&lt;br /&gt;
=== Preparation of database file ===&lt;br /&gt;
&lt;br /&gt;
The creation of a new database file is very easy. Just go to the directory where you want to create it and type:&lt;br /&gt;
&lt;br /&gt;
 sqlite3 &amp;lt;name of the file&amp;gt;&lt;br /&gt;
 sqlite3 tmw.db&lt;br /&gt;
&lt;br /&gt;
After this you should be &amp;quot;connected&amp;quot; to the database file and ready to create the necessary tables. We provide you with a ready to use installation script that could be found under &#039;&#039;./src/sql/sqlite/createTables.sql&#039;&#039;. To execute the script type the following while connected with sqlite:&lt;br /&gt;
&lt;br /&gt;
 .read &amp;lt;path and filename of the script&amp;gt;&lt;br /&gt;
 .read ~/tmwserv/src/sql/sqlite/createTables.sql&lt;br /&gt;
&lt;br /&gt;
To verify if the installation was sucessfull just type&lt;br /&gt;
 .tables&lt;br /&gt;
which should give you a list of tmw_* tables.&lt;br /&gt;
&lt;br /&gt;
=== Configuring tmwserv to use the database ===&lt;br /&gt;
&lt;br /&gt;
Before starting tmwserv you have to configure the account server where your database file is located. Tmwserv uses a XML file called &#039;&#039;tmwserv.xml&#039;&#039; with an easy to read &#039;&#039;key = value&#039;&#039; structure. Locate the option &#039;&#039;sqlite_database&#039;&#039; and modify the value attribute according to your environment. You can use a relative path starting at the location of your tmwserv executeable. &lt;br /&gt;
 &amp;lt;option name=&amp;quot;sqlite_database&amp;quot; value=&amp;quot;./tmw.db&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Settings up PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TODO&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Database_Installation&amp;diff=10148</id>
		<title>Archive:Database Installation</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Database_Installation&amp;diff=10148"/>
		<updated>2008-09-17T09:04:22Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;This page is currently WIP and should describe how to set up the database for a new installation of tmwserv. This page should be moved to [[Setting up a server]] when finished.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Before you can set up your own server you have to decide wich database backend you want to use. Currently, the server supports three different types of database backends:&lt;br /&gt;
* mySQL&lt;br /&gt;
* SQLite&lt;br /&gt;
* PostgreSQL&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Settings up mySQL ==&lt;br /&gt;
&lt;br /&gt;
=== Requirements === &lt;br /&gt;
&lt;br /&gt;
To run tmwserv with mySQL you should use a mySQL version &amp;gt;= 5.0.*. It was tested sucessfully with 5.0.51a.&lt;br /&gt;
Also you have to enable the [http://dev.mysql.com/doc/refman/5.0/en/innodb.html InnoDB] storage engine as tmwserv makes use of the relational and transactional features. &lt;br /&gt;
&lt;br /&gt;
=== Creating a database and a user ===&lt;br /&gt;
&lt;br /&gt;
This chapter assumes, that you still have little experience working with mysql, so it does not describe how to install mysql itself. The first step to get tmwserv running under mySQL would be the creation of a database and a user. As you can easily do this with graphical frontends like [http://www.phpmyadmin.net phpMyAdmin], we will give you a handy script for doing that from command line. Don&#039;t forget to replace the placeholders with appropriate values for your environment. &lt;br /&gt;
&lt;br /&gt;
For the following commands you have to be logged in as a database administrator, preferable &#039;&#039;root&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
 -- create a user called tmw (modify this as you whish)&lt;br /&gt;
 -- the &#039;localhost&#039; says, that our new user is only allowed from our local machine&lt;br /&gt;
 CREATE USER &#039;tmw&#039;@&#039;localhost&#039; IDENTIFIED BY &#039;&amp;lt;insert your password preferred here&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
 -- allow the user to connect to the server without any resource limitations&lt;br /&gt;
 GRANT USAGE ON * . * TO &#039;tmw&#039;@&#039;localhost&#039; IDENTIFIED BY &#039;&amp;lt;again your pwd&amp;gt;&#039; &lt;br /&gt;
    WITH MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0 ;&lt;br /&gt;
&lt;br /&gt;
 -- create a new database called &#039;tmw&#039; but you can name it just as you like&lt;br /&gt;
 CREATE DATABASE IF NOT EXISTS `tmw` ;&lt;br /&gt;
&lt;br /&gt;
 -- give our new user full privileges on our new created database&lt;br /&gt;
 GRANT ALL PRIVILEGES ON `tmw` . * TO &#039;tmw&#039;@&#039;localhost&#039;;&lt;br /&gt;
    &lt;br /&gt;
Summarized, now we have a new database called &#039;&#039;tmw&#039;&#039;, a new database user &#039;&#039;tmw&#039;&#039; that has full rights in his database, and a restriction, that he is only able to connect from localhost.&lt;br /&gt;
&lt;br /&gt;
=== Create database tables ===&lt;br /&gt;
&lt;br /&gt;
If our new database user is ready for use, we have to create all necessary tables. The installation of tmwserv provides you with a ready to use database script. You can find this script under &#039;&#039;./src/sql/mysql/createTables.sql&#039;&#039; To run this script connect as user tmw with your database.&lt;br /&gt;
&lt;br /&gt;
 mysql --host localhost --user tmw --password --database tmw --no-beep&lt;br /&gt;
&lt;br /&gt;
After typing your password you should be connected to the database. The command &#039;&#039;\.&#039;&#039; runs a database script.&lt;br /&gt;
&lt;br /&gt;
 \. &amp;lt;path to the script&amp;gt;/createTables.sql&lt;br /&gt;
 -- e.g.&lt;br /&gt;
 \. ~/tmwserv/src/sql/mysql/createTables.sql&lt;br /&gt;
&lt;br /&gt;
=== Configuring tmwserv to use the database ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TODO&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Settings up SQLite ==&lt;br /&gt;
&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
&lt;br /&gt;
Tmwserv has been tested with SQLite version 3.5.8&lt;br /&gt;
&lt;br /&gt;
=== Preparation of database file ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TODO&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Configuring tmwserv to use the database ===&lt;br /&gt;
&lt;br /&gt;
== Settings up PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TODO&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Database_Installation&amp;diff=10147</id>
		<title>Archive:Database Installation</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Database_Installation&amp;diff=10147"/>
		<updated>2008-09-16T21:29:47Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;This page is currently WIP and should describe how to set up the database for a new installation of tmwserv. This page should be moved to [[Setting up a server]] when finished.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Before you can set up your own server you have to decide wich database backend you want to use. Currently, the server supports three different types of database backends:&lt;br /&gt;
* mySQL&lt;br /&gt;
* SQLite&lt;br /&gt;
* PostgreSQL&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Settings up mySQL ==&lt;br /&gt;
&lt;br /&gt;
=== Creating a database and a user ===&lt;br /&gt;
&lt;br /&gt;
This chapter assumes, that you still have little experience working with mysql, so it does not describe how to install mysql itself. The first step to get tmwserv running under mySQL would be the creation of a database and a user. As you can easily do this with graphical frontends like [http://www.phpmyadmin.net phpMyAdmin], we will give you a handy script. Don&#039;t forget to replace the placeholders with appropriate values. For the following commands you have to be logged in as a database administrator, preferable &#039;&#039;root&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
 -- create a user called tmw (modify this as you whish)&lt;br /&gt;
 -- the &#039;localhost&#039; says, that our new user is only allowed from our local machine&lt;br /&gt;
 CREATE USER &#039;tmw&#039;@&#039;localhost&#039; IDENTIFIED BY &#039;&amp;lt;insert your password preferred here&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
 -- allow the user to connect to the server without any resource limitations&lt;br /&gt;
 GRANT USAGE ON * . * TO &#039;tmw&#039;@&#039;localhost&#039; IDENTIFIED BY &#039;&amp;lt;again your pwd&amp;gt;&#039; &lt;br /&gt;
    WITH MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0 ;&lt;br /&gt;
&lt;br /&gt;
 -- create a new database called &#039;tmw&#039; but you can name it just as you like&lt;br /&gt;
 CREATE DATABASE IF NOT EXISTS `tmw` ;&lt;br /&gt;
&lt;br /&gt;
 -- give our new user full privileges on our new created database&lt;br /&gt;
 GRANT ALL PRIVILEGES ON `tmw` . * TO &#039;tmw&#039;@&#039;localhost&#039;;&lt;br /&gt;
    &lt;br /&gt;
Summarized: now we have a new database called &#039;&#039;tmw&#039;&#039;, a new database user &#039;&#039;tmw&#039;&#039; that has full rights in this database, and a restriction, that he is only able to connect from localhost.&lt;br /&gt;
&lt;br /&gt;
=== Create database tables ===&lt;br /&gt;
&lt;br /&gt;
If our new database user is ready for use, we have to create all necessary tables. The installation of tmwserv provides you with a ready to use database script. You can find this script under &#039;&#039;./src/sql/mysql/createTables.sql&#039;&#039; To run this script connect as user tmw with your database.&lt;br /&gt;
&lt;br /&gt;
 mysql --host localhost --user tmw --password --database tmw --no-beep&lt;br /&gt;
&lt;br /&gt;
After typing your password you should be connected to the database. The command &#039;&#039;\.&#039;&#039; runs a database script.&lt;br /&gt;
&lt;br /&gt;
 \. &amp;lt;path to the script&amp;gt;/createTables.sql&lt;br /&gt;
 -- e.g.&lt;br /&gt;
 \. ~/tmwserv/src/sql/mysql/createTables.sql&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Settings up SQLite ==&lt;br /&gt;
&lt;br /&gt;
== Settings up PostgreSQL ==&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Database_specifications&amp;diff=10118</id>
		<title>Archive:Database specifications</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Database_specifications&amp;diff=10118"/>
		<updated>2008-09-15T11:51:54Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Category_programming}}&lt;br /&gt;
&lt;br /&gt;
== SQL table specifications ==&lt;br /&gt;
&lt;br /&gt;
=== User accounts ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_accounts}}&lt;br /&gt;
{{sqltablerow| id            | INTEGER     | PRIMARY KEY      | | unique id of an account}}                      }}&lt;br /&gt;
{{sqltablerow|username       | TEXT        | NOT NULL UNIQUE  | | username / loginname of an user                }}&lt;br /&gt;
{{sqltablerow|password       | TEXT        | NOT NULL         | | password of an user (sha256 encoded)           }}&lt;br /&gt;
{{sqltablerow|email          | TEXT        | NOT NULL         | | email (sha256 encoded, only for pwd recovery)  }}&lt;br /&gt;
{{sqltablerow|level          | INTEGER     | NOT NULL         | | numeric level of the user account              }}&lt;br /&gt;
{{sqltablerow|banned         | INTEGER     | NOT NULL         | | unixtimestamp until when the account is banned }}&lt;br /&gt;
{{sqltablerow|registration   | INTEGER     | NOT NULL         | | unixtimestamp of account registration          }}&lt;br /&gt;
{{sqltablerow|lastlogin      | INTEGER     | NOT NULL         | | unixtimestamp of last login with client        }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Details ====&lt;br /&gt;
* email&lt;br /&gt;
** The email is stored as a one-way sha256 hash value. This ensures, that the email address a user enters cannot be used to send spam mails. It is only used to validate the mailaddress during password recovery procedure.&lt;br /&gt;
* level&lt;br /&gt;
** describes the user rights in the game (10 = normal user, 50 = gm, 99 = administrator)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Characters ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_characters}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY      |                 | unique id of the character                              }}&lt;br /&gt;
{{sqltablerow|user_id        | INTEGER     | NOT NULL         | tmw_accounts.id | id of the owner                                         }}&lt;br /&gt;
{{sqltablerow|name           | TEXT        | NOT NULL UNIQUE  |                 | name of the character                                   }}&lt;br /&gt;
{{sqltablerow|gender         | INTEGER     | NOT NULL         |                 | gender of the character (0/1)                           }}&lt;br /&gt;
{{sqltablerow|hair_style     | INTEGER     | NOT NULL         |                 | id of the hair sprite                                   }}&lt;br /&gt;
{{sqltablerow|hair_color     | INTEGER     | NOT NULL         |                 | id of the hair color                                    }}&lt;br /&gt;
{{sqltablerow|level          | INTEGER     | NOT NULL         |                 | experience level of the character                       }}&lt;br /&gt;
{{sqltablerow|char_pts       | INTEGER     | NOT NULL         |                 | available points to raise attributes                    }}&lt;br /&gt;
{{sqltablerow|correct_pts    | INTEGER     | NOT NULL         |                 | available points to lower attributes and regain char_pts}}&lt;br /&gt;
{{sqltablerow|money          | INTEGER     | NOT NULL         |                 | GP of the character                                     }}&lt;br /&gt;
{{sqltablerow|x              | INTEGER     | NOT NULL         |                 | x position of the character on the map                  }}&lt;br /&gt;
{{sqltablerow|y              | INTEGER     | NOT NULL         |                 | y position of the character on the map                  }}&lt;br /&gt;
{{sqltablerow|map_id         | INTEGER     | NOT NULL         | tmw_maps.id     | id of the current map the character is located          }}&lt;br /&gt;
{{sqltablerow|str            | INTEGER     | NOT NULL         |                 | strength of the character                               }}&lt;br /&gt;
{{sqltablerow|agi            | INTEGER     | NOT NULL         |                 | agility of the character                                }}&lt;br /&gt;
{{sqltablerow|dex            | INTEGER     | NOT NULL         |                 | dexternity of the character                             }}&lt;br /&gt;
{{sqltablerow|vit            | INTEGER     | NOT NULL         |                 | vitality of the character                               }}&lt;br /&gt;
{{sqltablerow|int            | INTEGER     | NOT NULL         |                 | intelligence of the character                           }}&lt;br /&gt;
{{sqltablerow|will           | INTEGER     | NOT NULL         |                 | willpower of the character                              }}&lt;br /&gt;
{{sqltablerow|unarmed_exp    | INTEGER     | NOT NULL         |                 | Experience: unarmed                                     }}&lt;br /&gt;
{{sqltablerow|knife_exp      | INTEGER     | NOT NULL         |                 | Experience: knifes                                      }}&lt;br /&gt;
{{sqltablerow|sword_exp      | INTEGER     | NOT NULL         |                 | Experience: swords                                      }}&lt;br /&gt;
{{sqltablerow|polearm_exp    | INTEGER     | NOT NULL         |                 | Experience: polearms                                    }}&lt;br /&gt;
{{sqltablerow|staff_exp      | INTEGER     | NOT NULL         |                 | Experience: staffs                                      }}&lt;br /&gt;
{{sqltablerow|whip_exp       | INTEGER     | NOT NULL         |                 | Experience: whips                                       }}&lt;br /&gt;
{{sqltablerow|bow_exp        | INTEGER     | NOT NULL         |                 | Experience: bows                                        }}&lt;br /&gt;
{{sqltablerow|shoot_exp      | INTEGER     | NOT NULL         |                 | Experience: shooting                                    }}&lt;br /&gt;
{{sqltablerow|mace_exp       | INTEGER     | NOT NULL         |                 | Experience: maces                                       }}&lt;br /&gt;
{{sqltablerow|axe_exp        | INTEGER     | NOT NULL         |                 | Experience: axes                                        }}&lt;br /&gt;
{{sqltablerow|thrown_exp     | INTEGER     | NOT NULL         |                 | Experience: throwing                                    }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Concerns ====&lt;br /&gt;
&lt;br /&gt;
* The way experience is part of this table really won&#039;t scale and isn&#039;t flexible in any way. It&#039;s currently already way too many variables in one table row, and these are just the weapon skills. So I think we should really have a separate table for storing skill levels similar to the character inventory table below. So something that has { character_id, skill_id, experience }. The &amp;lt;code&amp;gt;skill_id&amp;lt;/code&amp;gt; should point to a &amp;lt;code&amp;gt;skills.xml&amp;lt;/code&amp;gt; file which describes (and categorizes) each skill. In that way we&#039;ll be able to easily change the set of skills and their names later. --[[User:BjÃ¸rn|BjÃ¸rn]] 18:09, 12 September 2008 (CEST)&lt;br /&gt;
** I think the same should be done with the attributes (str .. will). In theory almost every attribute in this table could be handled that way, it might look like a mess, but would be really friendly in customizing the gameplay elements. --[[User:Kess|kess]] 19:54, 12 September 2008 (CEST)&lt;br /&gt;
** I agree with that completely as this will give us more flexibility and a much more relational database design. I&#039;ve extended the &amp;quot;DAL improvements&amp;quot; task in mantis: #424 --[[User:Exceptionfault|Exceptionfault]] 15:50, 14 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
=== Character Inventory ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_inventories}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY      |                   | unique id of the item                          }}&lt;br /&gt;
{{sqltablerow|owner_id       | INTEGER     | NOT NULL         | tmw_characters.id | id of the owning character                     }}&lt;br /&gt;
{{sqltablerow|slot           | INTEGER     | NOT NULL         |                   | inventory slot where the item is equipped      }}&lt;br /&gt;
{{sqltablerow|class_id       | INTEGER     | NOT NULL         |                   | type of the item, see items.xml file of tmwserv}}&lt;br /&gt;
{{sqltablerow|amount         | INTEGER     | NOT NULL         |                   | amount of items per slot                       }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Comments ====&lt;br /&gt;
* While I havenâ€™t looked how this table is used (my C++ knowledge is rather basic) it seems quite rigid and unflexible (as BjÃ¸rn noted above for the &#039;&#039;&#039;tmw_characters&#039;&#039;&#039; table). I think it would be nicer to have something like {&#039;&#039;owner_id&#039;&#039; FK, &#039;&#039;slot&#039;&#039;, &#039;&#039;item_id&#039;&#039; FK, &#039;&#039;amount&#039;&#039;, PK owner_id + slot}, where class_id shouldnâ€™t directly be needed in this table. --[[User:Kess|kess]] 19:49, 12 September 2008 (CEST)&lt;br /&gt;
* Concerning new features like houses, bank accounts, chests or similar, i think the design of this table needs some more roundtrips. You will need a column which indicates if the item is carried by the character or stored in a chest or in a house; as it makes no sense to have a table for every possible storage type or location. Another point is, that items should be more individualizable (is this a real word? :)). Think about custom colored shirts. So we will need at least one additional table to store individual attributes of items. --[[User:Exceptionfault|Exceptionfault]] 16:02, 14 September 2008 (CEST)&lt;br /&gt;
** We want all equipment to be completely individual with completely unique stats. --[[User:Crush2|Crush2]] 16:13, 14 September 2008 (CEST)&lt;br /&gt;
*** Good to know, so I will extend the DAL improvement task in mantis. --[[User:Exceptionfault|Exceptionfault]] 16:20, 14 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
=== Guilds ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_guilds}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY     |  | unique id of the guid   }}&lt;br /&gt;
{{sqltablerow|name           | TEXT        | NOT NULL UNIQUE |  | unique name of the guild}}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Guild memberships ===&lt;br /&gt;
&lt;br /&gt;
The table &#039;&#039;tmw_guild_members&#039;&#039; stores informations which character is member in which guild and which rights does he has.&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_guild_members}}&lt;br /&gt;
{{sqltablerow|guild_id        | INTEGER     | NOT NULL | tmw_guilds.id     | reference to the guild                                                }}&lt;br /&gt;
{{sqltablerow|member_id       | INTEGER     | NOT NULL | tmw_characters.id | reference to the characters                                           }}&lt;br /&gt;
{{sqltablerow|rights          | INTEGER     | NOT NULL |                   | id showing the rights a character has in this guild (member, admin...)}}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== World state ===&lt;br /&gt;
&lt;br /&gt;
The table &#039;&#039;tmw_world_state&#039;&#039; is used to store persistent informations about the world or individual maps.&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_world_state}}&lt;br /&gt;
{{sqltablerow| state_name      | TEXT     | PRIMARY KEY |             | unique name of a state variable        }} &lt;br /&gt;
{{sqltablerow| map_id          | INTEGER  | NULL        | tmw_maps.id | reference to a map, see details        }}&lt;br /&gt;
{{sqltablerow| value           | TEXT     | NULL        |             | string value of the state              }}&lt;br /&gt;
{{sqltablerow| moddate         | INTEGER  | NOT NULL    |             | date and time of the last modification }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Details ====&lt;br /&gt;
&lt;br /&gt;
* The column &#039;&#039;state_name&#039;&#039; forms the primary key of the table. If &#039;&#039;map_id&#039;&#039; is null, the variable is used globally in the world, otherwise the variable is specific for a map.&lt;br /&gt;
* &#039;&#039;moddate&#039;&#039; is for informational use only as it contains the unixtimestamp of the last modification.&lt;br /&gt;
&lt;br /&gt;
==== Comments ====&lt;br /&gt;
&lt;br /&gt;
* It seems that SQLite doesn&#039;t support composite primary keys (span PK over multiple columns). Therefore it is not possible to allow multiple &#039;&#039;state_name&#039;&#039;s with different &#039;&#039;map_id&#039;&#039;s. So we set a &#039;&#039;state_name&#039;&#039; to unique and use &#039;&#039;map_id&#039;&#039; as notifier if this variable is globally used or just locally for a specific map. --[[User:Exceptionfault|Exceptionfault]] 11:05, 15 September 2008 (CEST)&lt;br /&gt;
** This table is ready for usage, commited as rev. 4629 --[[User:Exceptionfault|Exceptionfault]] 13:51, 15 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Quest states ===&lt;br /&gt;
&lt;br /&gt;
This table is used to store states of quests per character, e.g. if a character has just finished a quest or is currently at the second part of the long journey...&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_quests}}&lt;br /&gt;
{{sqltablerow|owner_id        | INTEGER     | NOT NULL | tmw_characters.id | reference to the character         }}&lt;br /&gt;
{{sqltablerow|name            | TEXT        | NOT NULL |                   | name of the quest variable         }}&lt;br /&gt;
{{sqltablerow|value           | TEXT        | NOT NULL |                   | current value of the quest variable}} &lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Comments ====&lt;br /&gt;
&lt;br /&gt;
* Unless this table is adapted so that it stores the state of a particular quest, this one should have a name which makes it move obvious that it&#039;s storing custom values for &#039;&#039;characters&#039;&#039;. I consider that different from quests variables, which I would expect to be scoped to a certain quest (global quest variables) or quest instance (local quest variables). --[[User:BjÃ¸rn|BjÃ¸rn]] 18:16, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* We might want to have a similar table to this to store custom values for item instances, and also one for custom world-state variables. --[[User:BjÃ¸rn|BjÃ¸rn]] 18:16, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* I always wondered why Silene used the terminology &amp;quot;Quest&amp;quot; for what is basically a system to store/querry persistent character-bound integer variables which can be used for countless purposes, not just quests. I think we should rename this whole system to &amp;quot;character variable&amp;quot; in the database, server source and script bindings. --[[User:Crush2|Crush2]] 23:28, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* I agree with BjÃ¸rn concerning the additional tables for custom item values and custom world-state values. Although the name &amp;quot;tmw_quests&amp;quot; is a little bit confusing and should be renamed, I suggest keeping a table as such to store only quest states of characters and not to mix up with other persistent states. Instead we should provide a much cleaner documentation about the available quests and their persistent states that are possible. I envision something like a questbook in game, where each player can have a look at his finished quests and currently open quests, maybe with hints on the minimap, a todo list .... Besides that, we should be aware of dividing quests into &amp;quot;per-character&amp;quot;, &amp;quot;per-party&amp;quot; or global world quests.  --[[User:Exceptionfault|Exceptionfault]] 16:20, 14 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Reference  ==&lt;br /&gt;
&lt;br /&gt;
Since the database is changing relatively often while we&#039;re still developing 0.1.0 and nobody likes to keep this page up to date, here is the link to the source code that specifies creation of the database tables. The source code is always right!&lt;br /&gt;
&lt;br /&gt;
* [http://themanaworld.svn.sourceforge.net/viewvc/themanaworld/tmwserv/trunk/src/account-server/dalstoragesql.hpp?view=markup View dalstoragesql.hpp]&lt;br /&gt;
* [http://themanaworld.svn.sourceforge.net/viewvc/*checkout*/themanaworld/tmwserv/trunk/src/account-server/dalstoragesql.hpp?revision=4024 Download dalstoragesql.hpp (plain text)]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Suggestions and Todos ==&lt;br /&gt;
&lt;br /&gt;
=== Character attributes ===&lt;br /&gt;
&lt;br /&gt;
This table is intended to store skills and experiences of each character. &lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_char_skills}}&lt;br /&gt;
{{sqltablerow|char_id         | INTEGER     | NOT NULL | tmw_characters.id | reference to the character                    }}&lt;br /&gt;
{{sqltablerow|skill_id        | INTEGER     | NOT NULL | (skills.xml)      | reference to the skill                        }}&lt;br /&gt;
{{sqltablerow|exp             | INTEGER     | NOT NULL |                   | current experience of the char in this skill  }} &lt;br /&gt;
{{sqltablerow|lastusage       | INTEGER     | NOT NULL |                   | date and time of the last usage of this skill }} &lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Comments ====&lt;br /&gt;
&lt;br /&gt;
* I&#039;am not sure, if an INTEGER does the job for column exp?&lt;br /&gt;
* &#039;&#039;lastusage&#039;&#039; gives us the possibility to implement something like: forget skills. This could be interesting for magical skills that have to be trained constantly to not forget them... &lt;br /&gt;
* TODO: remove the skill columns from tmw_characters and let DALStorage use the new table&lt;br /&gt;
--[[User:Exceptionfault|Exceptionfault]] 13:51, 15 September 2008 (CEST)&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Database_specifications&amp;diff=10117</id>
		<title>Archive:Database specifications</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Database_specifications&amp;diff=10117"/>
		<updated>2008-09-15T09:32:04Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: /* World state */ removed different value types as current DAL only supports strings&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Category_programming}}&lt;br /&gt;
&lt;br /&gt;
== SQL table specifications ==&lt;br /&gt;
&lt;br /&gt;
=== User accounts ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_accounts}}&lt;br /&gt;
{{sqltablerow| id            | INTEGER     | PRIMARY KEY      | | unique id of an account}}                      }}&lt;br /&gt;
{{sqltablerow|username       | TEXT        | NOT NULL UNIQUE  | | username / loginname of an user                }}&lt;br /&gt;
{{sqltablerow|password       | TEXT        | NOT NULL         | | password of an user (sha256 encoded)           }}&lt;br /&gt;
{{sqltablerow|email          | TEXT        | NOT NULL         | | email (sha256 encoded, only for pwd recovery)  }}&lt;br /&gt;
{{sqltablerow|level          | INTEGER     | NOT NULL         | | numeric level of the user account              }}&lt;br /&gt;
{{sqltablerow|banned         | INTEGER     | NOT NULL         | | unixtimestamp until when the account is banned }}&lt;br /&gt;
{{sqltablerow|registration   | INTEGER     | NOT NULL         | | unixtimestamp of account registration          }}&lt;br /&gt;
{{sqltablerow|lastlogin      | INTEGER     | NOT NULL         | | unixtimestamp of last login with client        }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Details ====&lt;br /&gt;
* email&lt;br /&gt;
** The email is stored as a one-way sha256 hash value. This ensures, that the email address a user enters cannot be used to send spam mails. It is only used to validate the mailaddress during password recovery procedure.&lt;br /&gt;
* level&lt;br /&gt;
** describes the user rights in the game (10 = normal user, 50 = gm, 99 = administrator)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Characters ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_characters}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY      |                 | unique id of the character                              }}&lt;br /&gt;
{{sqltablerow|user_id        | INTEGER     | NOT NULL         | tmw_accounts.id | id of the owner                                         }}&lt;br /&gt;
{{sqltablerow|name           | TEXT        | NOT NULL UNIQUE  |                 | name of the character                                   }}&lt;br /&gt;
{{sqltablerow|gender         | INTEGER     | NOT NULL         |                 | gender of the character (0/1)                           }}&lt;br /&gt;
{{sqltablerow|hair_style     | INTEGER     | NOT NULL         |                 | id of the hair sprite                                   }}&lt;br /&gt;
{{sqltablerow|hair_color     | INTEGER     | NOT NULL         |                 | id of the hair color                                    }}&lt;br /&gt;
{{sqltablerow|level          | INTEGER     | NOT NULL         |                 | experience level of the character                       }}&lt;br /&gt;
{{sqltablerow|char_pts       | INTEGER     | NOT NULL         |                 | available points to raise attributes                    }}&lt;br /&gt;
{{sqltablerow|correct_pts    | INTEGER     | NOT NULL         |                 | available points to lower attributes and regain char_pts}}&lt;br /&gt;
{{sqltablerow|money          | INTEGER     | NOT NULL         |                 | GP of the character                                     }}&lt;br /&gt;
{{sqltablerow|x              | INTEGER     | NOT NULL         |                 | x position of the character on the map                  }}&lt;br /&gt;
{{sqltablerow|y              | INTEGER     | NOT NULL         |                 | y position of the character on the map                  }}&lt;br /&gt;
{{sqltablerow|map_id         | INTEGER     | NOT NULL         | tmw_maps.id     | id of the current map the character is located          }}&lt;br /&gt;
{{sqltablerow|str            | INTEGER     | NOT NULL         |                 | strength of the character                               }}&lt;br /&gt;
{{sqltablerow|agi            | INTEGER     | NOT NULL         |                 | agility of the character                                }}&lt;br /&gt;
{{sqltablerow|dex            | INTEGER     | NOT NULL         |                 | dexternity of the character                             }}&lt;br /&gt;
{{sqltablerow|vit            | INTEGER     | NOT NULL         |                 | vitality of the character                               }}&lt;br /&gt;
{{sqltablerow|int            | INTEGER     | NOT NULL         |                 | intelligence of the character                           }}&lt;br /&gt;
{{sqltablerow|will           | INTEGER     | NOT NULL         |                 | willpower of the character                              }}&lt;br /&gt;
{{sqltablerow|unarmed_exp    | INTEGER     | NOT NULL         |                 | Experience: unarmed                                     }}&lt;br /&gt;
{{sqltablerow|knife_exp      | INTEGER     | NOT NULL         |                 | Experience: knifes                                      }}&lt;br /&gt;
{{sqltablerow|sword_exp      | INTEGER     | NOT NULL         |                 | Experience: swords                                      }}&lt;br /&gt;
{{sqltablerow|polearm_exp    | INTEGER     | NOT NULL         |                 | Experience: polearms                                    }}&lt;br /&gt;
{{sqltablerow|staff_exp      | INTEGER     | NOT NULL         |                 | Experience: staffs                                      }}&lt;br /&gt;
{{sqltablerow|whip_exp       | INTEGER     | NOT NULL         |                 | Experience: whips                                       }}&lt;br /&gt;
{{sqltablerow|bow_exp        | INTEGER     | NOT NULL         |                 | Experience: bows                                        }}&lt;br /&gt;
{{sqltablerow|shoot_exp      | INTEGER     | NOT NULL         |                 | Experience: shooting                                    }}&lt;br /&gt;
{{sqltablerow|mace_exp       | INTEGER     | NOT NULL         |                 | Experience: maces                                       }}&lt;br /&gt;
{{sqltablerow|axe_exp        | INTEGER     | NOT NULL         |                 | Experience: axes                                        }}&lt;br /&gt;
{{sqltablerow|thrown_exp     | INTEGER     | NOT NULL         |                 | Experience: throwing                                    }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Concerns ====&lt;br /&gt;
&lt;br /&gt;
* The way experience is part of this table really won&#039;t scale and isn&#039;t flexible in any way. It&#039;s currently already way too many variables in one table row, and these are just the weapon skills. So I think we should really have a separate table for storing skill levels similar to the character inventory table below. So something that has { character_id, skill_id, experience }. The &amp;lt;code&amp;gt;skill_id&amp;lt;/code&amp;gt; should point to a &amp;lt;code&amp;gt;skills.xml&amp;lt;/code&amp;gt; file which describes (and categorizes) each skill. In that way we&#039;ll be able to easily change the set of skills and their names later. --[[User:BjÃ¸rn|BjÃ¸rn]] 18:09, 12 September 2008 (CEST)&lt;br /&gt;
** I think the same should be done with the attributes (str .. will). In theory almost every attribute in this table could be handled that way, it might look like a mess, but would be really friendly in customizing the gameplay elements. --[[User:Kess|kess]] 19:54, 12 September 2008 (CEST)&lt;br /&gt;
** I agree with that completely as this will give us more flexibility and a much more relational database design. I&#039;ve extended the &amp;quot;DAL improvements&amp;quot; task in mantis: #424 --[[User:Exceptionfault|Exceptionfault]] 15:50, 14 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
=== Character Inventory ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_inventories}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY      |                   | unique id of the item                          }}&lt;br /&gt;
{{sqltablerow|owner_id       | INTEGER     | NOT NULL         | tmw_characters.id | id of the owning character                     }}&lt;br /&gt;
{{sqltablerow|slot           | INTEGER     | NOT NULL         |                   | inventory slot where the item is equipped      }}&lt;br /&gt;
{{sqltablerow|class_id       | INTEGER     | NOT NULL         |                   | type of the item, see items.xml file of tmwserv}}&lt;br /&gt;
{{sqltablerow|amount         | INTEGER     | NOT NULL         |                   | amount of items per slot                       }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Comments ====&lt;br /&gt;
* While I havenâ€™t looked how this table is used (my C++ knowledge is rather basic) it seems quite rigid and unflexible (as BjÃ¸rn noted above for the &#039;&#039;&#039;tmw_characters&#039;&#039;&#039; table). I think it would be nicer to have something like {&#039;&#039;owner_id&#039;&#039; FK, &#039;&#039;slot&#039;&#039;, &#039;&#039;item_id&#039;&#039; FK, &#039;&#039;amount&#039;&#039;, PK owner_id + slot}, where class_id shouldnâ€™t directly be needed in this table. --[[User:Kess|kess]] 19:49, 12 September 2008 (CEST)&lt;br /&gt;
* Concerning new features like houses, bank accounts, chests or similar, i think the design of this table needs some more roundtrips. You will need a column which indicates if the item is carried by the character or stored in a chest or in a house; as it makes no sense to have a table for every possible storage type or location. Another point is, that items should be more individualizable (is this a real word? :)). Think about custom colored shirts. So we will need at least one additional table to store individual attributes of items. --[[User:Exceptionfault|Exceptionfault]] 16:02, 14 September 2008 (CEST)&lt;br /&gt;
** We want all equipment to be completely individual with completely unique stats. --[[User:Crush2|Crush2]] 16:13, 14 September 2008 (CEST)&lt;br /&gt;
*** Good to know, so I will extend the DAL improvement task in mantis. --[[User:Exceptionfault|Exceptionfault]] 16:20, 14 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
=== Guilds ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_guilds}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY     |  | unique id of the guid   }}&lt;br /&gt;
{{sqltablerow|name           | TEXT        | NOT NULL UNIQUE |  | unique name of the guild}}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Guild memberships ===&lt;br /&gt;
&lt;br /&gt;
The table &#039;&#039;tmw_guild_members&#039;&#039; stores informations which character is member in which guild and which rights does he has.&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_guild_members}}&lt;br /&gt;
{{sqltablerow|guild_id        | INTEGER     | NOT NULL | tmw_guilds.id     | reference to the guild                                                }}&lt;br /&gt;
{{sqltablerow|member_id       | INTEGER     | NOT NULL | tmw_characters.id | reference to the characters                                           }}&lt;br /&gt;
{{sqltablerow|rights          | INTEGER     | NOT NULL |                   | id showing the rights a character has in this guild (member, admin...)}}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Quest states ===&lt;br /&gt;
&lt;br /&gt;
This table is used to store states of quests per character, e.g. if a character has just finished a quest or is currently at the second part of the long journey...&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_quests}}&lt;br /&gt;
{{sqltablerow|owner_id        | INTEGER     | NOT NULL | tmw_characters.id | reference to the character         }}&lt;br /&gt;
{{sqltablerow|name            | TEXT        | NOT NULL |                   | name of the quest variable         }}&lt;br /&gt;
{{sqltablerow|value           | TEXT        | NOT NULL |                   | current value of the quest variable}} &lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Comments ====&lt;br /&gt;
&lt;br /&gt;
* Unless this table is adapted so that it stores the state of a particular quest, this one should have a name which makes it move obvious that it&#039;s storing custom values for &#039;&#039;characters&#039;&#039;. I consider that different from quests variables, which I would expect to be scoped to a certain quest (global quest variables) or quest instance (local quest variables). --[[User:BjÃ¸rn|BjÃ¸rn]] 18:16, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* We might want to have a similar table to this to store custom values for item instances, and also one for custom world-state variables. --[[User:BjÃ¸rn|BjÃ¸rn]] 18:16, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* I always wondered why Silene used the terminology &amp;quot;Quest&amp;quot; for what is basically a system to store/querry persistent character-bound integer variables which can be used for countless purposes, not just quests. I think we should rename this whole system to &amp;quot;character variable&amp;quot; in the database, server source and script bindings. --[[User:Crush2|Crush2]] 23:28, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* I agree with BjÃ¸rn concerning the additional tables for custom item values and custom world-state values. Although the name &amp;quot;tmw_quests&amp;quot; is a little bit confusing and should be renamed, I suggest keeping a table as such to store only quest states of characters and not to mix up with other persistent states. Instead we should provide a much cleaner documentation about the available quests and their persistent states that are possible. I envision something like a questbook in game, where each player can have a look at his finished quests and currently open quests, maybe with hints on the minimap, a todo list .... Besides that, we should be aware of dividing quests into &amp;quot;per-character&amp;quot;, &amp;quot;per-party&amp;quot; or global world quests.  --[[User:Exceptionfault|Exceptionfault]] 16:20, 14 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Reference  ==&lt;br /&gt;
&lt;br /&gt;
Since the database is changing relatively often while we&#039;re still developing 0.1.0 and nobody likes to keep this page up to date, here is the link to the source code that specifies creation of the database tables. The source code is always right!&lt;br /&gt;
&lt;br /&gt;
* [http://themanaworld.svn.sourceforge.net/viewvc/themanaworld/tmwserv/trunk/src/account-server/dalstoragesql.hpp?view=markup View dalstoragesql.hpp]&lt;br /&gt;
* [http://themanaworld.svn.sourceforge.net/viewvc/*checkout*/themanaworld/tmwserv/trunk/src/account-server/dalstoragesql.hpp?revision=4024 Download dalstoragesql.hpp (plain text)]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Suggestions and Todos ==&lt;br /&gt;
&lt;br /&gt;
=== World state ===&lt;br /&gt;
&lt;br /&gt;
As noted above, we need a table to store custom world and map state variables. I suggest the following structure:&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_world_state}}&lt;br /&gt;
{{sqltablerow| state_name      | TEXT     | PRIMARY KEY |             | unique name of a state variable        }} &lt;br /&gt;
{{sqltablerow| map_id          | INTEGER  | NULL        | tmw_maps.id | reference to a map, see details        }}&lt;br /&gt;
{{sqltablerow| value           | TEXT     | NULL        |             | string value of the state              }}&lt;br /&gt;
{{sqltablerow| moddate         | INTEGER  | NOT NULL    |             | date and time of the last modification }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Details ====&lt;br /&gt;
&lt;br /&gt;
* The column &#039;&#039;state_name&#039;&#039; forms the primary key of the table. If &#039;&#039;map_id&#039;&#039; is null, the variable is used globally in the world, otherwise the variable is specific for a map.&lt;br /&gt;
* &#039;&#039;moddate&#039;&#039; is for informational use only as it contains the unixtimestamp of the last modification.&lt;br /&gt;
&lt;br /&gt;
==== Comments ====&lt;br /&gt;
&lt;br /&gt;
* It seems that SQLite doesn&#039;t support composite primary keys (span PK over multiple columns). Therefore it is not possible to allow multiple &#039;&#039;state_name&#039;&#039;s with different &#039;&#039;map_id&#039;&#039;s. So we set a &#039;&#039;state_name&#039;&#039; to unique and use &#039;&#039;map_id&#039;&#039; as notifier if this variable is globally used or just locally for a specific map. --[[User:Exceptionfault|Exceptionfault]] 11:05, 15 September 2008 (CEST)&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Database_specifications&amp;diff=10116</id>
		<title>Archive:Database specifications</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Database_specifications&amp;diff=10116"/>
		<updated>2008-09-15T09:05:46Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: /* World state */  modified constraints of tmw_world_state table&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Category_programming}}&lt;br /&gt;
&lt;br /&gt;
== SQL table specifications ==&lt;br /&gt;
&lt;br /&gt;
=== User accounts ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_accounts}}&lt;br /&gt;
{{sqltablerow| id            | INTEGER     | PRIMARY KEY      | | unique id of an account}}                      }}&lt;br /&gt;
{{sqltablerow|username       | TEXT        | NOT NULL UNIQUE  | | username / loginname of an user                }}&lt;br /&gt;
{{sqltablerow|password       | TEXT        | NOT NULL         | | password of an user (sha256 encoded)           }}&lt;br /&gt;
{{sqltablerow|email          | TEXT        | NOT NULL         | | email (sha256 encoded, only for pwd recovery)  }}&lt;br /&gt;
{{sqltablerow|level          | INTEGER     | NOT NULL         | | numeric level of the user account              }}&lt;br /&gt;
{{sqltablerow|banned         | INTEGER     | NOT NULL         | | unixtimestamp until when the account is banned }}&lt;br /&gt;
{{sqltablerow|registration   | INTEGER     | NOT NULL         | | unixtimestamp of account registration          }}&lt;br /&gt;
{{sqltablerow|lastlogin      | INTEGER     | NOT NULL         | | unixtimestamp of last login with client        }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Details ====&lt;br /&gt;
* email&lt;br /&gt;
** The email is stored as a one-way sha256 hash value. This ensures, that the email address a user enters cannot be used to send spam mails. It is only used to validate the mailaddress during password recovery procedure.&lt;br /&gt;
* level&lt;br /&gt;
** describes the user rights in the game (10 = normal user, 50 = gm, 99 = administrator)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Characters ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_characters}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY      |                 | unique id of the character                              }}&lt;br /&gt;
{{sqltablerow|user_id        | INTEGER     | NOT NULL         | tmw_accounts.id | id of the owner                                         }}&lt;br /&gt;
{{sqltablerow|name           | TEXT        | NOT NULL UNIQUE  |                 | name of the character                                   }}&lt;br /&gt;
{{sqltablerow|gender         | INTEGER     | NOT NULL         |                 | gender of the character (0/1)                           }}&lt;br /&gt;
{{sqltablerow|hair_style     | INTEGER     | NOT NULL         |                 | id of the hair sprite                                   }}&lt;br /&gt;
{{sqltablerow|hair_color     | INTEGER     | NOT NULL         |                 | id of the hair color                                    }}&lt;br /&gt;
{{sqltablerow|level          | INTEGER     | NOT NULL         |                 | experience level of the character                       }}&lt;br /&gt;
{{sqltablerow|char_pts       | INTEGER     | NOT NULL         |                 | available points to raise attributes                    }}&lt;br /&gt;
{{sqltablerow|correct_pts    | INTEGER     | NOT NULL         |                 | available points to lower attributes and regain char_pts}}&lt;br /&gt;
{{sqltablerow|money          | INTEGER     | NOT NULL         |                 | GP of the character                                     }}&lt;br /&gt;
{{sqltablerow|x              | INTEGER     | NOT NULL         |                 | x position of the character on the map                  }}&lt;br /&gt;
{{sqltablerow|y              | INTEGER     | NOT NULL         |                 | y position of the character on the map                  }}&lt;br /&gt;
{{sqltablerow|map_id         | INTEGER     | NOT NULL         | tmw_maps.id     | id of the current map the character is located          }}&lt;br /&gt;
{{sqltablerow|str            | INTEGER     | NOT NULL         |                 | strength of the character                               }}&lt;br /&gt;
{{sqltablerow|agi            | INTEGER     | NOT NULL         |                 | agility of the character                                }}&lt;br /&gt;
{{sqltablerow|dex            | INTEGER     | NOT NULL         |                 | dexternity of the character                             }}&lt;br /&gt;
{{sqltablerow|vit            | INTEGER     | NOT NULL         |                 | vitality of the character                               }}&lt;br /&gt;
{{sqltablerow|int            | INTEGER     | NOT NULL         |                 | intelligence of the character                           }}&lt;br /&gt;
{{sqltablerow|will           | INTEGER     | NOT NULL         |                 | willpower of the character                              }}&lt;br /&gt;
{{sqltablerow|unarmed_exp    | INTEGER     | NOT NULL         |                 | Experience: unarmed                                     }}&lt;br /&gt;
{{sqltablerow|knife_exp      | INTEGER     | NOT NULL         |                 | Experience: knifes                                      }}&lt;br /&gt;
{{sqltablerow|sword_exp      | INTEGER     | NOT NULL         |                 | Experience: swords                                      }}&lt;br /&gt;
{{sqltablerow|polearm_exp    | INTEGER     | NOT NULL         |                 | Experience: polearms                                    }}&lt;br /&gt;
{{sqltablerow|staff_exp      | INTEGER     | NOT NULL         |                 | Experience: staffs                                      }}&lt;br /&gt;
{{sqltablerow|whip_exp       | INTEGER     | NOT NULL         |                 | Experience: whips                                       }}&lt;br /&gt;
{{sqltablerow|bow_exp        | INTEGER     | NOT NULL         |                 | Experience: bows                                        }}&lt;br /&gt;
{{sqltablerow|shoot_exp      | INTEGER     | NOT NULL         |                 | Experience: shooting                                    }}&lt;br /&gt;
{{sqltablerow|mace_exp       | INTEGER     | NOT NULL         |                 | Experience: maces                                       }}&lt;br /&gt;
{{sqltablerow|axe_exp        | INTEGER     | NOT NULL         |                 | Experience: axes                                        }}&lt;br /&gt;
{{sqltablerow|thrown_exp     | INTEGER     | NOT NULL         |                 | Experience: throwing                                    }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Concerns ====&lt;br /&gt;
&lt;br /&gt;
* The way experience is part of this table really won&#039;t scale and isn&#039;t flexible in any way. It&#039;s currently already way too many variables in one table row, and these are just the weapon skills. So I think we should really have a separate table for storing skill levels similar to the character inventory table below. So something that has { character_id, skill_id, experience }. The &amp;lt;code&amp;gt;skill_id&amp;lt;/code&amp;gt; should point to a &amp;lt;code&amp;gt;skills.xml&amp;lt;/code&amp;gt; file which describes (and categorizes) each skill. In that way we&#039;ll be able to easily change the set of skills and their names later. --[[User:BjÃ¸rn|BjÃ¸rn]] 18:09, 12 September 2008 (CEST)&lt;br /&gt;
** I think the same should be done with the attributes (str .. will). In theory almost every attribute in this table could be handled that way, it might look like a mess, but would be really friendly in customizing the gameplay elements. --[[User:Kess|kess]] 19:54, 12 September 2008 (CEST)&lt;br /&gt;
** I agree with that completely as this will give us more flexibility and a much more relational database design. I&#039;ve extended the &amp;quot;DAL improvements&amp;quot; task in mantis: #424 --[[User:Exceptionfault|Exceptionfault]] 15:50, 14 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
=== Character Inventory ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_inventories}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY      |                   | unique id of the item                          }}&lt;br /&gt;
{{sqltablerow|owner_id       | INTEGER     | NOT NULL         | tmw_characters.id | id of the owning character                     }}&lt;br /&gt;
{{sqltablerow|slot           | INTEGER     | NOT NULL         |                   | inventory slot where the item is equipped      }}&lt;br /&gt;
{{sqltablerow|class_id       | INTEGER     | NOT NULL         |                   | type of the item, see items.xml file of tmwserv}}&lt;br /&gt;
{{sqltablerow|amount         | INTEGER     | NOT NULL         |                   | amount of items per slot                       }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Comments ====&lt;br /&gt;
* While I havenâ€™t looked how this table is used (my C++ knowledge is rather basic) it seems quite rigid and unflexible (as BjÃ¸rn noted above for the &#039;&#039;&#039;tmw_characters&#039;&#039;&#039; table). I think it would be nicer to have something like {&#039;&#039;owner_id&#039;&#039; FK, &#039;&#039;slot&#039;&#039;, &#039;&#039;item_id&#039;&#039; FK, &#039;&#039;amount&#039;&#039;, PK owner_id + slot}, where class_id shouldnâ€™t directly be needed in this table. --[[User:Kess|kess]] 19:49, 12 September 2008 (CEST)&lt;br /&gt;
* Concerning new features like houses, bank accounts, chests or similar, i think the design of this table needs some more roundtrips. You will need a column which indicates if the item is carried by the character or stored in a chest or in a house; as it makes no sense to have a table for every possible storage type or location. Another point is, that items should be more individualizable (is this a real word? :)). Think about custom colored shirts. So we will need at least one additional table to store individual attributes of items. --[[User:Exceptionfault|Exceptionfault]] 16:02, 14 September 2008 (CEST)&lt;br /&gt;
** We want all equipment to be completely individual with completely unique stats. --[[User:Crush2|Crush2]] 16:13, 14 September 2008 (CEST)&lt;br /&gt;
*** Good to know, so I will extend the DAL improvement task in mantis. --[[User:Exceptionfault|Exceptionfault]] 16:20, 14 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
=== Guilds ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_guilds}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY     |  | unique id of the guid   }}&lt;br /&gt;
{{sqltablerow|name           | TEXT        | NOT NULL UNIQUE |  | unique name of the guild}}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Guild memberships ===&lt;br /&gt;
&lt;br /&gt;
The table &#039;&#039;tmw_guild_members&#039;&#039; stores informations which character is member in which guild and which rights does he has.&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_guild_members}}&lt;br /&gt;
{{sqltablerow|guild_id        | INTEGER     | NOT NULL | tmw_guilds.id     | reference to the guild                                                }}&lt;br /&gt;
{{sqltablerow|member_id       | INTEGER     | NOT NULL | tmw_characters.id | reference to the characters                                           }}&lt;br /&gt;
{{sqltablerow|rights          | INTEGER     | NOT NULL |                   | id showing the rights a character has in this guild (member, admin...)}}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Quest states ===&lt;br /&gt;
&lt;br /&gt;
This table is used to store states of quests per character, e.g. if a character has just finished a quest or is currently at the second part of the long journey...&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_quests}}&lt;br /&gt;
{{sqltablerow|owner_id        | INTEGER     | NOT NULL | tmw_characters.id | reference to the character         }}&lt;br /&gt;
{{sqltablerow|name            | TEXT        | NOT NULL |                   | name of the quest variable         }}&lt;br /&gt;
{{sqltablerow|value           | TEXT        | NOT NULL |                   | current value of the quest variable}} &lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Comments ====&lt;br /&gt;
&lt;br /&gt;
* Unless this table is adapted so that it stores the state of a particular quest, this one should have a name which makes it move obvious that it&#039;s storing custom values for &#039;&#039;characters&#039;&#039;. I consider that different from quests variables, which I would expect to be scoped to a certain quest (global quest variables) or quest instance (local quest variables). --[[User:BjÃ¸rn|BjÃ¸rn]] 18:16, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* We might want to have a similar table to this to store custom values for item instances, and also one for custom world-state variables. --[[User:BjÃ¸rn|BjÃ¸rn]] 18:16, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* I always wondered why Silene used the terminology &amp;quot;Quest&amp;quot; for what is basically a system to store/querry persistent character-bound integer variables which can be used for countless purposes, not just quests. I think we should rename this whole system to &amp;quot;character variable&amp;quot; in the database, server source and script bindings. --[[User:Crush2|Crush2]] 23:28, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* I agree with BjÃ¸rn concerning the additional tables for custom item values and custom world-state values. Although the name &amp;quot;tmw_quests&amp;quot; is a little bit confusing and should be renamed, I suggest keeping a table as such to store only quest states of characters and not to mix up with other persistent states. Instead we should provide a much cleaner documentation about the available quests and their persistent states that are possible. I envision something like a questbook in game, where each player can have a look at his finished quests and currently open quests, maybe with hints on the minimap, a todo list .... Besides that, we should be aware of dividing quests into &amp;quot;per-character&amp;quot;, &amp;quot;per-party&amp;quot; or global world quests.  --[[User:Exceptionfault|Exceptionfault]] 16:20, 14 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Reference  ==&lt;br /&gt;
&lt;br /&gt;
Since the database is changing relatively often while we&#039;re still developing 0.1.0 and nobody likes to keep this page up to date, here is the link to the source code that specifies creation of the database tables. The source code is always right!&lt;br /&gt;
&lt;br /&gt;
* [http://themanaworld.svn.sourceforge.net/viewvc/themanaworld/tmwserv/trunk/src/account-server/dalstoragesql.hpp?view=markup View dalstoragesql.hpp]&lt;br /&gt;
* [http://themanaworld.svn.sourceforge.net/viewvc/*checkout*/themanaworld/tmwserv/trunk/src/account-server/dalstoragesql.hpp?revision=4024 Download dalstoragesql.hpp (plain text)]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Suggestions and Todos ==&lt;br /&gt;
&lt;br /&gt;
=== World state ===&lt;br /&gt;
&lt;br /&gt;
As noted above, we need a table to store custom world and map state variables. I suggest the following structure:&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_world_state}}&lt;br /&gt;
{{sqltablerow| state_name      | TEXT     | PRIMARY KEY |             | unique name of a state variable        }} &lt;br /&gt;
{{sqltablerow| map_id          | INTEGER  | NULL        | tmw_maps.id | reference to a map, see details        }}&lt;br /&gt;
{{sqltablerow| string_value    | TEXT     | NULL        |             | string value of the state              }}&lt;br /&gt;
{{sqltablerow| number_value    | INTEGER  | NULL        |             | numeric value of the state             }}&lt;br /&gt;
{{sqltablerow| moddate         | INTEGER  | NOT NULL    |             | date and time of the last modification }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Details ====&lt;br /&gt;
&lt;br /&gt;
* The column &#039;&#039;state_name&#039;&#039; forms the primary key of the table. If &#039;&#039;map_id&#039;&#039; is null, the variable is used globally in the world, otherwise the variable is specific for a map.&lt;br /&gt;
* To be able to store strings and numbers (including unixtimestamps), there are two value columns, each with a correct datatype for optimized storage in the database system.&lt;br /&gt;
* &#039;&#039;moddate&#039;&#039; is for informational use only as it contains the unixtimestamp of the last modification.&lt;br /&gt;
&lt;br /&gt;
==== Comments ====&lt;br /&gt;
&lt;br /&gt;
* It seems that SQLite doesn&#039;t support composite primary keys (span PK over multiple columns). Therefore it is not possible to allow multiple &#039;&#039;state_name&#039;&#039;s with different &#039;&#039;map_id&#039;&#039;s. So we set a &#039;&#039;state_name&#039;&#039; to unique and use &#039;&#039;map_id&#039;&#039; as notifier if this variable is globally used or just locally for a specific map. --[[User:Exceptionfault|Exceptionfault]] 11:05, 15 September 2008 (CEST)&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Database_specifications&amp;diff=10115</id>
		<title>Archive:Database specifications</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Database_specifications&amp;diff=10115"/>
		<updated>2008-09-15T07:32:02Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: Added Todo: tmw_world_state&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Category_programming}}&lt;br /&gt;
&lt;br /&gt;
== SQL table specifications ==&lt;br /&gt;
&lt;br /&gt;
=== User accounts ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_accounts}}&lt;br /&gt;
{{sqltablerow| id            | INTEGER     | PRIMARY KEY      | | unique id of an account}}                      }}&lt;br /&gt;
{{sqltablerow|username       | TEXT        | NOT NULL UNIQUE  | | username / loginname of an user                }}&lt;br /&gt;
{{sqltablerow|password       | TEXT        | NOT NULL         | | password of an user (sha256 encoded)           }}&lt;br /&gt;
{{sqltablerow|email          | TEXT        | NOT NULL         | | email (sha256 encoded, only for pwd recovery)  }}&lt;br /&gt;
{{sqltablerow|level          | INTEGER     | NOT NULL         | | numeric level of the user account              }}&lt;br /&gt;
{{sqltablerow|banned         | INTEGER     | NOT NULL         | | unixtimestamp until when the account is banned }}&lt;br /&gt;
{{sqltablerow|registration   | INTEGER     | NOT NULL         | | unixtimestamp of account registration          }}&lt;br /&gt;
{{sqltablerow|lastlogin      | INTEGER     | NOT NULL         | | unixtimestamp of last login with client        }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Details ====&lt;br /&gt;
* email&lt;br /&gt;
** The email is stored as a one-way sha256 hash value. This ensures, that the email address a user enters cannot be used to send spam mails. It is only used to validate the mailaddress during password recovery procedure.&lt;br /&gt;
* level&lt;br /&gt;
** describes the user rights in the game (10 = normal user, 50 = gm, 99 = administrator)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Characters ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_characters}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY      |                 | unique id of the character                              }}&lt;br /&gt;
{{sqltablerow|user_id        | INTEGER     | NOT NULL         | tmw_accounts.id | id of the owner                                         }}&lt;br /&gt;
{{sqltablerow|name           | TEXT        | NOT NULL UNIQUE  |                 | name of the character                                   }}&lt;br /&gt;
{{sqltablerow|gender         | INTEGER     | NOT NULL         |                 | gender of the character (0/1)                           }}&lt;br /&gt;
{{sqltablerow|hair_style     | INTEGER     | NOT NULL         |                 | id of the hair sprite                                   }}&lt;br /&gt;
{{sqltablerow|hair_color     | INTEGER     | NOT NULL         |                 | id of the hair color                                    }}&lt;br /&gt;
{{sqltablerow|level          | INTEGER     | NOT NULL         |                 | experience level of the character                       }}&lt;br /&gt;
{{sqltablerow|char_pts       | INTEGER     | NOT NULL         |                 | available points to raise attributes                    }}&lt;br /&gt;
{{sqltablerow|correct_pts    | INTEGER     | NOT NULL         |                 | available points to lower attributes and regain char_pts}}&lt;br /&gt;
{{sqltablerow|money          | INTEGER     | NOT NULL         |                 | GP of the character                                     }}&lt;br /&gt;
{{sqltablerow|x              | INTEGER     | NOT NULL         |                 | x position of the character on the map                  }}&lt;br /&gt;
{{sqltablerow|y              | INTEGER     | NOT NULL         |                 | y position of the character on the map                  }}&lt;br /&gt;
{{sqltablerow|map_id         | INTEGER     | NOT NULL         | tmw_maps.id     | id of the current map the character is located          }}&lt;br /&gt;
{{sqltablerow|str            | INTEGER     | NOT NULL         |                 | strength of the character                               }}&lt;br /&gt;
{{sqltablerow|agi            | INTEGER     | NOT NULL         |                 | agility of the character                                }}&lt;br /&gt;
{{sqltablerow|dex            | INTEGER     | NOT NULL         |                 | dexternity of the character                             }}&lt;br /&gt;
{{sqltablerow|vit            | INTEGER     | NOT NULL         |                 | vitality of the character                               }}&lt;br /&gt;
{{sqltablerow|int            | INTEGER     | NOT NULL         |                 | intelligence of the character                           }}&lt;br /&gt;
{{sqltablerow|will           | INTEGER     | NOT NULL         |                 | willpower of the character                              }}&lt;br /&gt;
{{sqltablerow|unarmed_exp    | INTEGER     | NOT NULL         |                 | Experience: unarmed                                     }}&lt;br /&gt;
{{sqltablerow|knife_exp      | INTEGER     | NOT NULL         |                 | Experience: knifes                                      }}&lt;br /&gt;
{{sqltablerow|sword_exp      | INTEGER     | NOT NULL         |                 | Experience: swords                                      }}&lt;br /&gt;
{{sqltablerow|polearm_exp    | INTEGER     | NOT NULL         |                 | Experience: polearms                                    }}&lt;br /&gt;
{{sqltablerow|staff_exp      | INTEGER     | NOT NULL         |                 | Experience: staffs                                      }}&lt;br /&gt;
{{sqltablerow|whip_exp       | INTEGER     | NOT NULL         |                 | Experience: whips                                       }}&lt;br /&gt;
{{sqltablerow|bow_exp        | INTEGER     | NOT NULL         |                 | Experience: bows                                        }}&lt;br /&gt;
{{sqltablerow|shoot_exp      | INTEGER     | NOT NULL         |                 | Experience: shooting                                    }}&lt;br /&gt;
{{sqltablerow|mace_exp       | INTEGER     | NOT NULL         |                 | Experience: maces                                       }}&lt;br /&gt;
{{sqltablerow|axe_exp        | INTEGER     | NOT NULL         |                 | Experience: axes                                        }}&lt;br /&gt;
{{sqltablerow|thrown_exp     | INTEGER     | NOT NULL         |                 | Experience: throwing                                    }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Concerns ====&lt;br /&gt;
&lt;br /&gt;
* The way experience is part of this table really won&#039;t scale and isn&#039;t flexible in any way. It&#039;s currently already way too many variables in one table row, and these are just the weapon skills. So I think we should really have a separate table for storing skill levels similar to the character inventory table below. So something that has { character_id, skill_id, experience }. The &amp;lt;code&amp;gt;skill_id&amp;lt;/code&amp;gt; should point to a &amp;lt;code&amp;gt;skills.xml&amp;lt;/code&amp;gt; file which describes (and categorizes) each skill. In that way we&#039;ll be able to easily change the set of skills and their names later. --[[User:BjÃ¸rn|BjÃ¸rn]] 18:09, 12 September 2008 (CEST)&lt;br /&gt;
** I think the same should be done with the attributes (str .. will). In theory almost every attribute in this table could be handled that way, it might look like a mess, but would be really friendly in customizing the gameplay elements. --[[User:Kess|kess]] 19:54, 12 September 2008 (CEST)&lt;br /&gt;
** I agree with that completely as this will give us more flexibility and a much more relational database design. I&#039;ve extended the &amp;quot;DAL improvements&amp;quot; task in mantis: #424 --[[User:Exceptionfault|Exceptionfault]] 15:50, 14 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
=== Character Inventory ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_inventories}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY      |                   | unique id of the item                          }}&lt;br /&gt;
{{sqltablerow|owner_id       | INTEGER     | NOT NULL         | tmw_characters.id | id of the owning character                     }}&lt;br /&gt;
{{sqltablerow|slot           | INTEGER     | NOT NULL         |                   | inventory slot where the item is equipped      }}&lt;br /&gt;
{{sqltablerow|class_id       | INTEGER     | NOT NULL         |                   | type of the item, see items.xml file of tmwserv}}&lt;br /&gt;
{{sqltablerow|amount         | INTEGER     | NOT NULL         |                   | amount of items per slot                       }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Comments ====&lt;br /&gt;
* While I havenâ€™t looked how this table is used (my C++ knowledge is rather basic) it seems quite rigid and unflexible (as BjÃ¸rn noted above for the &#039;&#039;&#039;tmw_characters&#039;&#039;&#039; table). I think it would be nicer to have something like {&#039;&#039;owner_id&#039;&#039; FK, &#039;&#039;slot&#039;&#039;, &#039;&#039;item_id&#039;&#039; FK, &#039;&#039;amount&#039;&#039;, PK owner_id + slot}, where class_id shouldnâ€™t directly be needed in this table. --[[User:Kess|kess]] 19:49, 12 September 2008 (CEST)&lt;br /&gt;
* Concerning new features like houses, bank accounts, chests or similar, i think the design of this table needs some more roundtrips. You will need a column which indicates if the item is carried by the character or stored in a chest or in a house; as it makes no sense to have a table for every possible storage type or location. Another point is, that items should be more individualizable (is this a real word? :)). Think about custom colored shirts. So we will need at least one additional table to store individual attributes of items. --[[User:Exceptionfault|Exceptionfault]] 16:02, 14 September 2008 (CEST)&lt;br /&gt;
** We want all equipment to be completely individual with completely unique stats. --[[User:Crush2|Crush2]] 16:13, 14 September 2008 (CEST)&lt;br /&gt;
*** Good to know, so I will extend the DAL improvement task in mantis. --[[User:Exceptionfault|Exceptionfault]] 16:20, 14 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
=== Guilds ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_guilds}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY     |  | unique id of the guid   }}&lt;br /&gt;
{{sqltablerow|name           | TEXT        | NOT NULL UNIQUE |  | unique name of the guild}}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Guild memberships ===&lt;br /&gt;
&lt;br /&gt;
The table &#039;&#039;tmw_guild_members&#039;&#039; stores informations which character is member in which guild and which rights does he has.&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_guild_members}}&lt;br /&gt;
{{sqltablerow|guild_id        | INTEGER     | NOT NULL | tmw_guilds.id     | reference to the guild                                                }}&lt;br /&gt;
{{sqltablerow|member_id       | INTEGER     | NOT NULL | tmw_characters.id | reference to the characters                                           }}&lt;br /&gt;
{{sqltablerow|rights          | INTEGER     | NOT NULL |                   | id showing the rights a character has in this guild (member, admin...)}}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Quest states ===&lt;br /&gt;
&lt;br /&gt;
This table is used to store states of quests per character, e.g. if a character has just finished a quest or is currently at the second part of the long journey...&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_quests}}&lt;br /&gt;
{{sqltablerow|owner_id        | INTEGER     | NOT NULL | tmw_characters.id | reference to the character         }}&lt;br /&gt;
{{sqltablerow|name            | TEXT        | NOT NULL |                   | name of the quest variable         }}&lt;br /&gt;
{{sqltablerow|value           | TEXT        | NOT NULL |                   | current value of the quest variable}} &lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Comments ====&lt;br /&gt;
&lt;br /&gt;
* Unless this table is adapted so that it stores the state of a particular quest, this one should have a name which makes it move obvious that it&#039;s storing custom values for &#039;&#039;characters&#039;&#039;. I consider that different from quests variables, which I would expect to be scoped to a certain quest (global quest variables) or quest instance (local quest variables). --[[User:BjÃ¸rn|BjÃ¸rn]] 18:16, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* We might want to have a similar table to this to store custom values for item instances, and also one for custom world-state variables. --[[User:BjÃ¸rn|BjÃ¸rn]] 18:16, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* I always wondered why Silene used the terminology &amp;quot;Quest&amp;quot; for what is basically a system to store/querry persistent character-bound integer variables which can be used for countless purposes, not just quests. I think we should rename this whole system to &amp;quot;character variable&amp;quot; in the database, server source and script bindings. --[[User:Crush2|Crush2]] 23:28, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* I agree with BjÃ¸rn concerning the additional tables for custom item values and custom world-state values. Although the name &amp;quot;tmw_quests&amp;quot; is a little bit confusing and should be renamed, I suggest keeping a table as such to store only quest states of characters and not to mix up with other persistent states. Instead we should provide a much cleaner documentation about the available quests and their persistent states that are possible. I envision something like a questbook in game, where each player can have a look at his finished quests and currently open quests, maybe with hints on the minimap, a todo list .... Besides that, we should be aware of dividing quests into &amp;quot;per-character&amp;quot;, &amp;quot;per-party&amp;quot; or global world quests.  --[[User:Exceptionfault|Exceptionfault]] 16:20, 14 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Reference  ==&lt;br /&gt;
&lt;br /&gt;
Since the database is changing relatively often while we&#039;re still developing 0.1.0 and nobody likes to keep this page up to date, here is the link to the source code that specifies creation of the database tables. The source code is always right!&lt;br /&gt;
&lt;br /&gt;
* [http://themanaworld.svn.sourceforge.net/viewvc/themanaworld/tmwserv/trunk/src/account-server/dalstoragesql.hpp?view=markup View dalstoragesql.hpp]&lt;br /&gt;
* [http://themanaworld.svn.sourceforge.net/viewvc/*checkout*/themanaworld/tmwserv/trunk/src/account-server/dalstoragesql.hpp?revision=4024 Download dalstoragesql.hpp (plain text)]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Suggestions and Todos ==&lt;br /&gt;
&lt;br /&gt;
=== World state ===&lt;br /&gt;
&lt;br /&gt;
As noted above, we need a table to store custom world and map state variables. I suggest the following structure:&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_world_state}}&lt;br /&gt;
{{sqltablerow| state_name      | TEXT     | PRIMARY KEY      |             | unique name of a state variable        }} &lt;br /&gt;
{{sqltablerow| map_id          | INTEGER  | PRIMARY KEY NULL | tmw_maps.id | reference to a map, see details        }}&lt;br /&gt;
{{sqltablerow| string_value    | TEXT     | NULL             |             | string value of the state              }}&lt;br /&gt;
{{sqltablerow| number_value    | INTEGER  | NULL             |             | numeric value of the state             }}&lt;br /&gt;
{{sqltablerow| moddate         | INTEGER  | NOT NULL         |             | date and time of the last modification }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Details ====&lt;br /&gt;
* The column &#039;&#039;state_name&#039;&#039; and &#039;&#039;map_id&#039;&#039; form the primary key of the table. If &#039;&#039;map_id&#039;&#039; is null, the variable is used globally in the world, otherwise the variable can have a different value per map.&lt;br /&gt;
* To be able to store strings and numbers (including unixtimestamps), there are two value columns, each with a correct datatype for optimized storage in the database system.&lt;br /&gt;
* &#039;&#039;moddate&#039;&#039; is for informational use only as it contains the unixtimestamp of the last modification.&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Database_specifications&amp;diff=10111</id>
		<title>Archive:Database specifications</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Database_specifications&amp;diff=10111"/>
		<updated>2008-09-14T14:20:17Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: /* Comments */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Category_programming}}&lt;br /&gt;
&lt;br /&gt;
== SQL table specifications ==&lt;br /&gt;
&lt;br /&gt;
=== User accounts ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_accounts}}&lt;br /&gt;
{{sqltablerow| id            | INTEGER     | PRIMARY KEY      | | unique id of an account}}                      }}&lt;br /&gt;
{{sqltablerow|username       | TEXT        | NOT NULL UNIQUE  | | username / loginname of an user                }}&lt;br /&gt;
{{sqltablerow|password       | TEXT        | NOT NULL         | | password of an user (sha256 encoded)           }}&lt;br /&gt;
{{sqltablerow|email          | TEXT        | NOT NULL         | | email (sha256 encoded, only for pwd recovery)  }}&lt;br /&gt;
{{sqltablerow|level          | INTEGER     | NOT NULL         | | numeric level of the user account              }}&lt;br /&gt;
{{sqltablerow|banned         | INTEGER     | NOT NULL         | | unixtimestamp until when the account is banned }}&lt;br /&gt;
{{sqltablerow|registration   | INTEGER     | NOT NULL         | | unixtimestamp of account registration          }}&lt;br /&gt;
{{sqltablerow|lastlogin      | INTEGER     | NOT NULL         | | unixtimestamp of last login with client        }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Details ====&lt;br /&gt;
* email&lt;br /&gt;
** The email is stored as a one-way sha256 hash value. This ensures, that the email address a user enters cannot be used to send spam mails. It is only used to validate the mailaddress during password recovery procedure.&lt;br /&gt;
* level&lt;br /&gt;
** describes the user rights in the game (10 = normal user, 50 = gm, 99 = administrator)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Characters ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_characters}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY      |                 | unique id of the character                              }}&lt;br /&gt;
{{sqltablerow|user_id        | INTEGER     | NOT NULL         | tmw_accounts.id | id of the owner                                         }}&lt;br /&gt;
{{sqltablerow|name           | TEXT        | NOT NULL UNIQUE  |                 | name of the character                                   }}&lt;br /&gt;
{{sqltablerow|gender         | INTEGER     | NOT NULL         |                 | gender of the character (0/1)                           }}&lt;br /&gt;
{{sqltablerow|hair_style     | INTEGER     | NOT NULL         |                 | id of the hair sprite                                   }}&lt;br /&gt;
{{sqltablerow|hair_color     | INTEGER     | NOT NULL         |                 | id of the hair color                                    }}&lt;br /&gt;
{{sqltablerow|level          | INTEGER     | NOT NULL         |                 | experience level of the character                       }}&lt;br /&gt;
{{sqltablerow|char_pts       | INTEGER     | NOT NULL         |                 | available points to raise attributes                    }}&lt;br /&gt;
{{sqltablerow|correct_pts    | INTEGER     | NOT NULL         |                 | available points to lower attributes and regain char_pts}}&lt;br /&gt;
{{sqltablerow|money          | INTEGER     | NOT NULL         |                 | GP of the character                                     }}&lt;br /&gt;
{{sqltablerow|x              | INTEGER     | NOT NULL         |                 | x position of the character on the map                  }}&lt;br /&gt;
{{sqltablerow|y              | INTEGER     | NOT NULL         |                 | y position of the character on the map                  }}&lt;br /&gt;
{{sqltablerow|map_id         | INTEGER     | NOT NULL         | tmw_maps.id     | id of the current map the character is located          }}&lt;br /&gt;
{{sqltablerow|str            | INTEGER     | NOT NULL         |                 | strength of the character                               }}&lt;br /&gt;
{{sqltablerow|agi            | INTEGER     | NOT NULL         |                 | agility of the character                                }}&lt;br /&gt;
{{sqltablerow|dex            | INTEGER     | NOT NULL         |                 | dexternity of the character                             }}&lt;br /&gt;
{{sqltablerow|vit            | INTEGER     | NOT NULL         |                 | vitality of the character                               }}&lt;br /&gt;
{{sqltablerow|int            | INTEGER     | NOT NULL         |                 | intelligence of the character                           }}&lt;br /&gt;
{{sqltablerow|will           | INTEGER     | NOT NULL         |                 | willpower of the character                              }}&lt;br /&gt;
{{sqltablerow|unarmed_exp    | INTEGER     | NOT NULL         |                 | Experience: unarmed                                     }}&lt;br /&gt;
{{sqltablerow|knife_exp      | INTEGER     | NOT NULL         |                 | Experience: knifes                                      }}&lt;br /&gt;
{{sqltablerow|sword_exp      | INTEGER     | NOT NULL         |                 | Experience: swords                                      }}&lt;br /&gt;
{{sqltablerow|polearm_exp    | INTEGER     | NOT NULL         |                 | Experience: polearms                                    }}&lt;br /&gt;
{{sqltablerow|staff_exp      | INTEGER     | NOT NULL         |                 | Experience: staffs                                      }}&lt;br /&gt;
{{sqltablerow|whip_exp       | INTEGER     | NOT NULL         |                 | Experience: whips                                       }}&lt;br /&gt;
{{sqltablerow|bow_exp        | INTEGER     | NOT NULL         |                 | Experience: bows                                        }}&lt;br /&gt;
{{sqltablerow|shoot_exp      | INTEGER     | NOT NULL         |                 | Experience: shooting                                    }}&lt;br /&gt;
{{sqltablerow|mace_exp       | INTEGER     | NOT NULL         |                 | Experience: maces                                       }}&lt;br /&gt;
{{sqltablerow|axe_exp        | INTEGER     | NOT NULL         |                 | Experience: axes                                        }}&lt;br /&gt;
{{sqltablerow|thrown_exp     | INTEGER     | NOT NULL         |                 | Experience: throwing                                    }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Concerns ====&lt;br /&gt;
&lt;br /&gt;
* The way experience is part of this table really won&#039;t scale and isn&#039;t flexible in any way. It&#039;s currently already way too many variables in one table row, and these are just the weapon skills. So I think we should really have a separate table for storing skill levels similar to the character inventory table below. So something that has { character_id, skill_id, experience }. The &amp;lt;code&amp;gt;skill_id&amp;lt;/code&amp;gt; should point to a &amp;lt;code&amp;gt;skills.xml&amp;lt;/code&amp;gt; file which describes (and categorizes) each skill. In that way we&#039;ll be able to easily change the set of skills and their names later. --[[User:BjÃ¸rn|BjÃ¸rn]] 18:09, 12 September 2008 (CEST)&lt;br /&gt;
** I think the same should be done with the attributes (str .. will). In theory almost every attribute in this table could be handled that way, it might look like a mess, but would be really friendly in customizing the gameplay elements. --[[User:Kess|kess]] 19:54, 12 September 2008 (CEST)&lt;br /&gt;
** I agree with that completely as this will give us more flexibility and a much more relational database design. I&#039;ve extended the &amp;quot;DAL improvements&amp;quot; task in mantis: #424 --[[User:Exceptionfault|Exceptionfault]] 15:50, 14 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
=== Character Inventory ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_inventories}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY      |                   | unique id of the item                          }}&lt;br /&gt;
{{sqltablerow|owner_id       | INTEGER     | NOT NULL         | tmw_characters.id | id of the owning character                     }}&lt;br /&gt;
{{sqltablerow|slot           | INTEGER     | NOT NULL         |                   | inventory slot where the item is equipped      }}&lt;br /&gt;
{{sqltablerow|class_id       | INTEGER     | NOT NULL         |                   | type of the item, see items.xml file of tmwserv}}&lt;br /&gt;
{{sqltablerow|amount         | INTEGER     | NOT NULL         |                   | amount of items per slot                       }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Comments ====&lt;br /&gt;
* While I havenâ€™t looked how this table is used (my C++ knowledge is rather basic) it seems quite rigid and unflexible (as BjÃ¸rn noted above for the &#039;&#039;&#039;tmw_characters&#039;&#039;&#039; table). I think it would be nicer to have something like {&#039;&#039;owner_id&#039;&#039; FK, &#039;&#039;slot&#039;&#039;, &#039;&#039;item_id&#039;&#039; FK, &#039;&#039;amount&#039;&#039;, PK owner_id + slot}, where class_id shouldnâ€™t directly be needed in this table. --[[User:Kess|kess]] 19:49, 12 September 2008 (CEST)&lt;br /&gt;
* Concerning new features like houses, bank accounts, chests or similar, i think the design of this table needs some more roundtrips. You will need a column which indicates if the item is carried by the character or stored in a chest or in a house; as it makes no sense to have a table for every possible storage type or location. Another point is, that items should be more individualizable (is this a real word? :)). Think about custom colored shirts. So we will need at least one additional table to store individual attributes of items. --[[User:Exceptionfault|Exceptionfault]] 16:02, 14 September 2008 (CEST)&lt;br /&gt;
** We want all equipment to be completely individual with completely unique stats. --[[User:Crush2|Crush2]] 16:13, 14 September 2008 (CEST)&lt;br /&gt;
*** Good to know, so I will extend the DAL improvement task in mantis. --[[User:Exceptionfault|Exceptionfault]] 16:20, 14 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
=== Guilds ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_guilds}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY     |  | unique id of the guid   }}&lt;br /&gt;
{{sqltablerow|name           | TEXT        | NOT NULL UNIQUE |  | unique name of the guild}}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Guild memberships ===&lt;br /&gt;
&lt;br /&gt;
The table &#039;&#039;tmw_guild_members&#039;&#039; stores informations which character is member in which guild and which rights does he has.&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_guild_members}}&lt;br /&gt;
{{sqltablerow|guild_id        | INTEGER     | NOT NULL | tmw_guilds.id     | reference to the guild                                                }}&lt;br /&gt;
{{sqltablerow|member_id       | INTEGER     | NOT NULL | tmw_characters.id | reference to the characters                                           }}&lt;br /&gt;
{{sqltablerow|rights          | INTEGER     | NOT NULL |                   | id showing the rights a character has in this guild (member, admin...)}}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Quest states ===&lt;br /&gt;
&lt;br /&gt;
This table is used to store states of quests per character, e.g. if a character has just finished a quest or is currently at the second part of the long journey...&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_quests}}&lt;br /&gt;
{{sqltablerow|owner_id        | INTEGER     | NOT NULL | tmw_characters.id | reference to the character         }}&lt;br /&gt;
{{sqltablerow|name            | TEXT        | NOT NULL |                   | name of the quest variable         }}&lt;br /&gt;
{{sqltablerow|value           | TEXT        | NOT NULL |                   | current value of the quest variable}} &lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Comments ====&lt;br /&gt;
&lt;br /&gt;
* Unless this table is adapted so that it stores the state of a particular quest, this one should have a name which makes it move obvious that it&#039;s storing custom values for &#039;&#039;characters&#039;&#039;. I consider that different from quests variables, which I would expect to be scoped to a certain quest (global quest variables) or quest instance (local quest variables). --[[User:BjÃ¸rn|BjÃ¸rn]] 18:16, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* We might want to have a similar table to this to store custom values for item instances, and also one for custom world-state variables. --[[User:BjÃ¸rn|BjÃ¸rn]] 18:16, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* I always wondered why Silene used the terminology &amp;quot;Quest&amp;quot; for what is basically a system to store/querry persistent character-bound integer variables which can be used for countless purposes, not just quests. I think we should rename this whole system to &amp;quot;character variable&amp;quot; in the database, server source and script bindings. --[[User:Crush2|Crush2]] 23:28, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* I agree with BjÃ¸rn concerning the additional tables for custom item values and custom world-state values. Although the name &amp;quot;tmw_quests&amp;quot; is a little bit confusing and should be renamed, I suggest keeping a table as such to store only quest states of characters and not to mix up with other persistent states. Instead we should provide a much cleaner documentation about the available quests and their persistent states that are possible. I envision something like a questbook in game, where each player can have a look at his finished quests and currently open quests, maybe with hints on the minimap, a todo list .... Besides that, we should be aware of dividing quests into &amp;quot;per-character&amp;quot;, &amp;quot;per-party&amp;quot; or global world quests.  --[[User:Exceptionfault|Exceptionfault]] 16:20, 14 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Reference  ==&lt;br /&gt;
&lt;br /&gt;
Since the database is changing relatively often while we&#039;re still developing 0.1.0 and nobody likes to keep this page up to date, here is the link to the source code that specifies creation of the database tables. The source code is always right!&lt;br /&gt;
&lt;br /&gt;
* [http://themanaworld.svn.sourceforge.net/viewvc/themanaworld/tmwserv/trunk/src/account-server/dalstoragesql.hpp?view=markup View dalstoragesql.hpp]&lt;br /&gt;
* [http://themanaworld.svn.sourceforge.net/viewvc/*checkout*/themanaworld/tmwserv/trunk/src/account-server/dalstoragesql.hpp?revision=4024 Download dalstoragesql.hpp (plain text)]&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Database_specifications&amp;diff=10110</id>
		<title>Archive:Database specifications</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Database_specifications&amp;diff=10110"/>
		<updated>2008-09-14T14:20:05Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: /* Comments */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Category_programming}}&lt;br /&gt;
&lt;br /&gt;
== SQL table specifications ==&lt;br /&gt;
&lt;br /&gt;
=== User accounts ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_accounts}}&lt;br /&gt;
{{sqltablerow| id            | INTEGER     | PRIMARY KEY      | | unique id of an account}}                      }}&lt;br /&gt;
{{sqltablerow|username       | TEXT        | NOT NULL UNIQUE  | | username / loginname of an user                }}&lt;br /&gt;
{{sqltablerow|password       | TEXT        | NOT NULL         | | password of an user (sha256 encoded)           }}&lt;br /&gt;
{{sqltablerow|email          | TEXT        | NOT NULL         | | email (sha256 encoded, only for pwd recovery)  }}&lt;br /&gt;
{{sqltablerow|level          | INTEGER     | NOT NULL         | | numeric level of the user account              }}&lt;br /&gt;
{{sqltablerow|banned         | INTEGER     | NOT NULL         | | unixtimestamp until when the account is banned }}&lt;br /&gt;
{{sqltablerow|registration   | INTEGER     | NOT NULL         | | unixtimestamp of account registration          }}&lt;br /&gt;
{{sqltablerow|lastlogin      | INTEGER     | NOT NULL         | | unixtimestamp of last login with client        }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Details ====&lt;br /&gt;
* email&lt;br /&gt;
** The email is stored as a one-way sha256 hash value. This ensures, that the email address a user enters cannot be used to send spam mails. It is only used to validate the mailaddress during password recovery procedure.&lt;br /&gt;
* level&lt;br /&gt;
** describes the user rights in the game (10 = normal user, 50 = gm, 99 = administrator)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Characters ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_characters}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY      |                 | unique id of the character                              }}&lt;br /&gt;
{{sqltablerow|user_id        | INTEGER     | NOT NULL         | tmw_accounts.id | id of the owner                                         }}&lt;br /&gt;
{{sqltablerow|name           | TEXT        | NOT NULL UNIQUE  |                 | name of the character                                   }}&lt;br /&gt;
{{sqltablerow|gender         | INTEGER     | NOT NULL         |                 | gender of the character (0/1)                           }}&lt;br /&gt;
{{sqltablerow|hair_style     | INTEGER     | NOT NULL         |                 | id of the hair sprite                                   }}&lt;br /&gt;
{{sqltablerow|hair_color     | INTEGER     | NOT NULL         |                 | id of the hair color                                    }}&lt;br /&gt;
{{sqltablerow|level          | INTEGER     | NOT NULL         |                 | experience level of the character                       }}&lt;br /&gt;
{{sqltablerow|char_pts       | INTEGER     | NOT NULL         |                 | available points to raise attributes                    }}&lt;br /&gt;
{{sqltablerow|correct_pts    | INTEGER     | NOT NULL         |                 | available points to lower attributes and regain char_pts}}&lt;br /&gt;
{{sqltablerow|money          | INTEGER     | NOT NULL         |                 | GP of the character                                     }}&lt;br /&gt;
{{sqltablerow|x              | INTEGER     | NOT NULL         |                 | x position of the character on the map                  }}&lt;br /&gt;
{{sqltablerow|y              | INTEGER     | NOT NULL         |                 | y position of the character on the map                  }}&lt;br /&gt;
{{sqltablerow|map_id         | INTEGER     | NOT NULL         | tmw_maps.id     | id of the current map the character is located          }}&lt;br /&gt;
{{sqltablerow|str            | INTEGER     | NOT NULL         |                 | strength of the character                               }}&lt;br /&gt;
{{sqltablerow|agi            | INTEGER     | NOT NULL         |                 | agility of the character                                }}&lt;br /&gt;
{{sqltablerow|dex            | INTEGER     | NOT NULL         |                 | dexternity of the character                             }}&lt;br /&gt;
{{sqltablerow|vit            | INTEGER     | NOT NULL         |                 | vitality of the character                               }}&lt;br /&gt;
{{sqltablerow|int            | INTEGER     | NOT NULL         |                 | intelligence of the character                           }}&lt;br /&gt;
{{sqltablerow|will           | INTEGER     | NOT NULL         |                 | willpower of the character                              }}&lt;br /&gt;
{{sqltablerow|unarmed_exp    | INTEGER     | NOT NULL         |                 | Experience: unarmed                                     }}&lt;br /&gt;
{{sqltablerow|knife_exp      | INTEGER     | NOT NULL         |                 | Experience: knifes                                      }}&lt;br /&gt;
{{sqltablerow|sword_exp      | INTEGER     | NOT NULL         |                 | Experience: swords                                      }}&lt;br /&gt;
{{sqltablerow|polearm_exp    | INTEGER     | NOT NULL         |                 | Experience: polearms                                    }}&lt;br /&gt;
{{sqltablerow|staff_exp      | INTEGER     | NOT NULL         |                 | Experience: staffs                                      }}&lt;br /&gt;
{{sqltablerow|whip_exp       | INTEGER     | NOT NULL         |                 | Experience: whips                                       }}&lt;br /&gt;
{{sqltablerow|bow_exp        | INTEGER     | NOT NULL         |                 | Experience: bows                                        }}&lt;br /&gt;
{{sqltablerow|shoot_exp      | INTEGER     | NOT NULL         |                 | Experience: shooting                                    }}&lt;br /&gt;
{{sqltablerow|mace_exp       | INTEGER     | NOT NULL         |                 | Experience: maces                                       }}&lt;br /&gt;
{{sqltablerow|axe_exp        | INTEGER     | NOT NULL         |                 | Experience: axes                                        }}&lt;br /&gt;
{{sqltablerow|thrown_exp     | INTEGER     | NOT NULL         |                 | Experience: throwing                                    }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Concerns ====&lt;br /&gt;
&lt;br /&gt;
* The way experience is part of this table really won&#039;t scale and isn&#039;t flexible in any way. It&#039;s currently already way too many variables in one table row, and these are just the weapon skills. So I think we should really have a separate table for storing skill levels similar to the character inventory table below. So something that has { character_id, skill_id, experience }. The &amp;lt;code&amp;gt;skill_id&amp;lt;/code&amp;gt; should point to a &amp;lt;code&amp;gt;skills.xml&amp;lt;/code&amp;gt; file which describes (and categorizes) each skill. In that way we&#039;ll be able to easily change the set of skills and their names later. --[[User:BjÃ¸rn|BjÃ¸rn]] 18:09, 12 September 2008 (CEST)&lt;br /&gt;
** I think the same should be done with the attributes (str .. will). In theory almost every attribute in this table could be handled that way, it might look like a mess, but would be really friendly in customizing the gameplay elements. --[[User:Kess|kess]] 19:54, 12 September 2008 (CEST)&lt;br /&gt;
** I agree with that completely as this will give us more flexibility and a much more relational database design. I&#039;ve extended the &amp;quot;DAL improvements&amp;quot; task in mantis: #424 --[[User:Exceptionfault|Exceptionfault]] 15:50, 14 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
=== Character Inventory ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_inventories}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY      |                   | unique id of the item                          }}&lt;br /&gt;
{{sqltablerow|owner_id       | INTEGER     | NOT NULL         | tmw_characters.id | id of the owning character                     }}&lt;br /&gt;
{{sqltablerow|slot           | INTEGER     | NOT NULL         |                   | inventory slot where the item is equipped      }}&lt;br /&gt;
{{sqltablerow|class_id       | INTEGER     | NOT NULL         |                   | type of the item, see items.xml file of tmwserv}}&lt;br /&gt;
{{sqltablerow|amount         | INTEGER     | NOT NULL         |                   | amount of items per slot                       }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Comments ====&lt;br /&gt;
* While I havenâ€™t looked how this table is used (my C++ knowledge is rather basic) it seems quite rigid and unflexible (as BjÃ¸rn noted above for the &#039;&#039;&#039;tmw_characters&#039;&#039;&#039; table). I think it would be nicer to have something like {&#039;&#039;owner_id&#039;&#039; FK, &#039;&#039;slot&#039;&#039;, &#039;&#039;item_id&#039;&#039; FK, &#039;&#039;amount&#039;&#039;, PK owner_id + slot}, where class_id shouldnâ€™t directly be needed in this table. --[[User:Kess|kess]] 19:49, 12 September 2008 (CEST)&lt;br /&gt;
* Concerning new features like houses, bank accounts, chests or similar, i think the design of this table needs some more roundtrips. You will need a column which indicates if the item is carried by the character or stored in a chest or in a house; as it makes no sense to have a table for every possible storage type or location. Another point is, that items should be more individualizable (is this a real word? :)). Think about custom colored shirts. So we will need at least one additional table to store individual attributes of items. --[[User:Exceptionfault|Exceptionfault]] 16:02, 14 September 2008 (CEST)&lt;br /&gt;
** We want all equipment to be completely individual with completely unique stats. --[[User:Crush2|Crush2]] 16:13, 14 September 2008 (CEST)&lt;br /&gt;
*** Good to know, so I will extend the DAL improvement task in mantis.&lt;br /&gt;
&lt;br /&gt;
=== Guilds ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_guilds}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY     |  | unique id of the guid   }}&lt;br /&gt;
{{sqltablerow|name           | TEXT        | NOT NULL UNIQUE |  | unique name of the guild}}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Guild memberships ===&lt;br /&gt;
&lt;br /&gt;
The table &#039;&#039;tmw_guild_members&#039;&#039; stores informations which character is member in which guild and which rights does he has.&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_guild_members}}&lt;br /&gt;
{{sqltablerow|guild_id        | INTEGER     | NOT NULL | tmw_guilds.id     | reference to the guild                                                }}&lt;br /&gt;
{{sqltablerow|member_id       | INTEGER     | NOT NULL | tmw_characters.id | reference to the characters                                           }}&lt;br /&gt;
{{sqltablerow|rights          | INTEGER     | NOT NULL |                   | id showing the rights a character has in this guild (member, admin...)}}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Quest states ===&lt;br /&gt;
&lt;br /&gt;
This table is used to store states of quests per character, e.g. if a character has just finished a quest or is currently at the second part of the long journey...&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_quests}}&lt;br /&gt;
{{sqltablerow|owner_id        | INTEGER     | NOT NULL | tmw_characters.id | reference to the character         }}&lt;br /&gt;
{{sqltablerow|name            | TEXT        | NOT NULL |                   | name of the quest variable         }}&lt;br /&gt;
{{sqltablerow|value           | TEXT        | NOT NULL |                   | current value of the quest variable}} &lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Comments ====&lt;br /&gt;
&lt;br /&gt;
* Unless this table is adapted so that it stores the state of a particular quest, this one should have a name which makes it move obvious that it&#039;s storing custom values for &#039;&#039;characters&#039;&#039;. I consider that different from quests variables, which I would expect to be scoped to a certain quest (global quest variables) or quest instance (local quest variables). --[[User:BjÃ¸rn|BjÃ¸rn]] 18:16, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* We might want to have a similar table to this to store custom values for item instances, and also one for custom world-state variables. --[[User:BjÃ¸rn|BjÃ¸rn]] 18:16, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* I always wondered why Silene used the terminology &amp;quot;Quest&amp;quot; for what is basically a system to store/querry persistent character-bound integer variables which can be used for countless purposes, not just quests. I think we should rename this whole system to &amp;quot;character variable&amp;quot; in the database, server source and script bindings. --[[User:Crush2|Crush2]] 23:28, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* I agree with BjÃ¸rn concerning the additional tables for custom item values and custom world-state values. Although the name &amp;quot;tmw_quests&amp;quot; is a little bit confusing and should be renamed, I suggest keeping a table as such to store only quest states of characters and not to mix up with other persistent states. Instead we should provide a much cleaner documentation about the available quests and their persistent states that are possible. I envision something like a questbook in game, where each player can have a look at his finished quests and currently open quests, maybe with hints on the minimap, a todo list .... Besides that, we should be aware of dividing quests into &amp;quot;per-character&amp;quot;, &amp;quot;per-party&amp;quot; or global world quests.  --[[User:Exceptionfault|Exceptionfault]] 16:20, 14 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Reference  ==&lt;br /&gt;
&lt;br /&gt;
Since the database is changing relatively often while we&#039;re still developing 0.1.0 and nobody likes to keep this page up to date, here is the link to the source code that specifies creation of the database tables. The source code is always right!&lt;br /&gt;
&lt;br /&gt;
* [http://themanaworld.svn.sourceforge.net/viewvc/themanaworld/tmwserv/trunk/src/account-server/dalstoragesql.hpp?view=markup View dalstoragesql.hpp]&lt;br /&gt;
* [http://themanaworld.svn.sourceforge.net/viewvc/*checkout*/themanaworld/tmwserv/trunk/src/account-server/dalstoragesql.hpp?revision=4024 Download dalstoragesql.hpp (plain text)]&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Database_specifications&amp;diff=10108</id>
		<title>Archive:Database specifications</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Database_specifications&amp;diff=10108"/>
		<updated>2008-09-14T14:02:37Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: /* Comments */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Category_programming}}&lt;br /&gt;
&lt;br /&gt;
== SQL table specifications ==&lt;br /&gt;
&lt;br /&gt;
=== User accounts ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_accounts}}&lt;br /&gt;
{{sqltablerow| id            | INTEGER     | PRIMARY KEY      | | unique id of an account}}                      }}&lt;br /&gt;
{{sqltablerow|username       | TEXT        | NOT NULL UNIQUE  | | username / loginname of an user                }}&lt;br /&gt;
{{sqltablerow|password       | TEXT        | NOT NULL         | | password of an user (sha256 encoded)           }}&lt;br /&gt;
{{sqltablerow|email          | TEXT        | NOT NULL         | | email (sha256 encoded, only for pwd recovery)  }}&lt;br /&gt;
{{sqltablerow|level          | INTEGER     | NOT NULL         | | numeric level of the user account              }}&lt;br /&gt;
{{sqltablerow|banned         | INTEGER     | NOT NULL         | | unixtimestamp until when the account is banned }}&lt;br /&gt;
{{sqltablerow|registration   | INTEGER     | NOT NULL         | | unixtimestamp of account registration          }}&lt;br /&gt;
{{sqltablerow|lastlogin      | INTEGER     | NOT NULL         | | unixtimestamp of last login with client        }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Details ====&lt;br /&gt;
* email&lt;br /&gt;
** The email is stored as a one-way sha256 hash value. This ensures, that the email address a user enters cannot be used to send spam mails. It is only used to validate the mailaddress during password recovery procedure.&lt;br /&gt;
* level&lt;br /&gt;
** describes the user rights in the game (10 = normal user, 50 = gm, 99 = administrator)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Characters ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_characters}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY      |                 | unique id of the character                              }}&lt;br /&gt;
{{sqltablerow|user_id        | INTEGER     | NOT NULL         | tmw_accounts.id | id of the owner                                         }}&lt;br /&gt;
{{sqltablerow|name           | TEXT        | NOT NULL UNIQUE  |                 | name of the character                                   }}&lt;br /&gt;
{{sqltablerow|gender         | INTEGER     | NOT NULL         |                 | gender of the character (0/1)                           }}&lt;br /&gt;
{{sqltablerow|hair_style     | INTEGER     | NOT NULL         |                 | id of the hair sprite                                   }}&lt;br /&gt;
{{sqltablerow|hair_color     | INTEGER     | NOT NULL         |                 | id of the hair color                                    }}&lt;br /&gt;
{{sqltablerow|level          | INTEGER     | NOT NULL         |                 | experience level of the character                       }}&lt;br /&gt;
{{sqltablerow|char_pts       | INTEGER     | NOT NULL         |                 | available points to raise attributes                    }}&lt;br /&gt;
{{sqltablerow|correct_pts    | INTEGER     | NOT NULL         |                 | available points to lower attributes and regain char_pts}}&lt;br /&gt;
{{sqltablerow|money          | INTEGER     | NOT NULL         |                 | GP of the character                                     }}&lt;br /&gt;
{{sqltablerow|x              | INTEGER     | NOT NULL         |                 | x position of the character on the map                  }}&lt;br /&gt;
{{sqltablerow|y              | INTEGER     | NOT NULL         |                 | y position of the character on the map                  }}&lt;br /&gt;
{{sqltablerow|map_id         | INTEGER     | NOT NULL         | tmw_maps.id     | id of the current map the character is located          }}&lt;br /&gt;
{{sqltablerow|str            | INTEGER     | NOT NULL         |                 | strength of the character                               }}&lt;br /&gt;
{{sqltablerow|agi            | INTEGER     | NOT NULL         |                 | agility of the character                                }}&lt;br /&gt;
{{sqltablerow|dex            | INTEGER     | NOT NULL         |                 | dexternity of the character                             }}&lt;br /&gt;
{{sqltablerow|vit            | INTEGER     | NOT NULL         |                 | vitality of the character                               }}&lt;br /&gt;
{{sqltablerow|int            | INTEGER     | NOT NULL         |                 | intelligence of the character                           }}&lt;br /&gt;
{{sqltablerow|will           | INTEGER     | NOT NULL         |                 | willpower of the character                              }}&lt;br /&gt;
{{sqltablerow|unarmed_exp    | INTEGER     | NOT NULL         |                 | Experience: unarmed                                     }}&lt;br /&gt;
{{sqltablerow|knife_exp      | INTEGER     | NOT NULL         |                 | Experience: knifes                                      }}&lt;br /&gt;
{{sqltablerow|sword_exp      | INTEGER     | NOT NULL         |                 | Experience: swords                                      }}&lt;br /&gt;
{{sqltablerow|polearm_exp    | INTEGER     | NOT NULL         |                 | Experience: polearms                                    }}&lt;br /&gt;
{{sqltablerow|staff_exp      | INTEGER     | NOT NULL         |                 | Experience: staffs                                      }}&lt;br /&gt;
{{sqltablerow|whip_exp       | INTEGER     | NOT NULL         |                 | Experience: whips                                       }}&lt;br /&gt;
{{sqltablerow|bow_exp        | INTEGER     | NOT NULL         |                 | Experience: bows                                        }}&lt;br /&gt;
{{sqltablerow|shoot_exp      | INTEGER     | NOT NULL         |                 | Experience: shooting                                    }}&lt;br /&gt;
{{sqltablerow|mace_exp       | INTEGER     | NOT NULL         |                 | Experience: maces                                       }}&lt;br /&gt;
{{sqltablerow|axe_exp        | INTEGER     | NOT NULL         |                 | Experience: axes                                        }}&lt;br /&gt;
{{sqltablerow|thrown_exp     | INTEGER     | NOT NULL         |                 | Experience: throwing                                    }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Concerns ====&lt;br /&gt;
&lt;br /&gt;
* The way experience is part of this table really won&#039;t scale and isn&#039;t flexible in any way. It&#039;s currently already way too many variables in one table row, and these are just the weapon skills. So I think we should really have a separate table for storing skill levels similar to the character inventory table below. So something that has { character_id, skill_id, experience }. The &amp;lt;code&amp;gt;skill_id&amp;lt;/code&amp;gt; should point to a &amp;lt;code&amp;gt;skills.xml&amp;lt;/code&amp;gt; file which describes (and categorizes) each skill. In that way we&#039;ll be able to easily change the set of skills and their names later. --[[User:BjÃ¸rn|BjÃ¸rn]] 18:09, 12 September 2008 (CEST)&lt;br /&gt;
** I think the same should be done with the attributes (str .. will). In theory almost every attribute in this table could be handled that way, it might look like a mess, but would be really friendly in customizing the gameplay elements. --[[User:Kess|kess]] 19:54, 12 September 2008 (CEST)&lt;br /&gt;
** I agree with that completely as this will give us more flexibility and a much more relational database design. I&#039;ve extended the &amp;quot;DAL improvements&amp;quot; task in mantis: #424 --[[User:Exceptionfault|Exceptionfault]] 15:50, 14 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
=== Character Inventory ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_inventories}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY      |                   | unique id of the item                          }}&lt;br /&gt;
{{sqltablerow|owner_id       | INTEGER     | NOT NULL         | tmw_characters.id | id of the owning character                     }}&lt;br /&gt;
{{sqltablerow|slot           | INTEGER     | NOT NULL         |                   | inventory slot where the item is equipped      }}&lt;br /&gt;
{{sqltablerow|class_id       | INTEGER     | NOT NULL         |                   | type of the item, see items.xml file of tmwserv}}&lt;br /&gt;
{{sqltablerow|amount         | INTEGER     | NOT NULL         |                   | amount of items per slot                       }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Comments ====&lt;br /&gt;
* While I havenâ€™t looked how this table is used (my C++ knowledge is rather basic) it seems quite rigid and unflexible (as BjÃ¸rn noted above for the &#039;&#039;&#039;tmw_characters&#039;&#039;&#039; table). I think it would be nicer to have something like {&#039;&#039;owner_id&#039;&#039; FK, &#039;&#039;slot&#039;&#039;, &#039;&#039;item_id&#039;&#039; FK, &#039;&#039;amount&#039;&#039;, PK owner_id + slot}, where class_id shouldnâ€™t directly be needed in this table. --[[User:Kess|kess]] 19:49, 12 September 2008 (CEST)&lt;br /&gt;
* Concerning new features like houses, bank accounts, chests or similar, i think the design of this table needs some more roundtrips. You will need a column which indicates if the item is carried by the character or stored in a chest or in a house; as it makes no sense to have a table for every possible storage type or location. Another point is, that items should be more individualizable (is this a real word? :)). Think about custom colored shirts. So we will need at least one additional table to store individual attributes of items. --[[User:Exceptionfault|Exceptionfault]] 16:02, 14 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
=== Guilds ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_guilds}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY     |  | unique id of the guid   }}&lt;br /&gt;
{{sqltablerow|name           | TEXT        | NOT NULL UNIQUE |  | unique name of the guild}}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Guild memberships ===&lt;br /&gt;
&lt;br /&gt;
The table &#039;&#039;tmw_guild_members&#039;&#039; stores informations which character is member in which guild and which rights does he has.&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_guild_members}}&lt;br /&gt;
{{sqltablerow|guild_id        | INTEGER     | NOT NULL | tmw_guilds.id     | reference to the guild                                                }}&lt;br /&gt;
{{sqltablerow|member_id       | INTEGER     | NOT NULL | tmw_characters.id | reference to the characters                                           }}&lt;br /&gt;
{{sqltablerow|rights          | INTEGER     | NOT NULL |                   | id showing the rights a character has in this guild (member, admin...)}}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Quest states ===&lt;br /&gt;
&lt;br /&gt;
This table is used to store states of quests per character, e.g. if a character has just finished a quest or is currently at the second part of the long journey...&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_quests}}&lt;br /&gt;
{{sqltablerow|owner_id        | INTEGER     | NOT NULL | tmw_characters.id | reference to the character         }}&lt;br /&gt;
{{sqltablerow|name            | TEXT        | NOT NULL |                   | name of the quest variable         }}&lt;br /&gt;
{{sqltablerow|value           | TEXT        | NOT NULL |                   | current value of the quest variable}} &lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Comments ====&lt;br /&gt;
&lt;br /&gt;
* Unless this table is adapted so that it stores the state of a particular quest, this one should have a name which makes it move obvious that it&#039;s storing custom values for &#039;&#039;characters&#039;&#039;. I consider that different from quests variables, which I would expect to be scoped to a certain quest (global quest variables) or quest instance (local quest variables). --[[User:BjÃ¸rn|BjÃ¸rn]] 18:16, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* We might want to have a similar table to this to store custom values for item instances, and also one for custom world-state variables. --[[User:BjÃ¸rn|BjÃ¸rn]] 18:16, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* I always wondered why Silene used the terminology &amp;quot;Quest&amp;quot; for what is basically a system to store/querry persistent character-bound integer variables which can be used for countless purposes, not just quests. I think we should rename this whole system to &amp;quot;character variable&amp;quot; in the database, server source and script bindings. --[[User:Crush2|Crush2]] 23:28, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Reference  ==&lt;br /&gt;
&lt;br /&gt;
Since the database is changing relatively often while we&#039;re still developing 0.1.0 and nobody likes to keep this page up to date, here is the link to the source code that specifies creation of the database tables. The source code is always right!&lt;br /&gt;
&lt;br /&gt;
* [http://themanaworld.svn.sourceforge.net/viewvc/themanaworld/tmwserv/trunk/src/account-server/dalstoragesql.hpp?view=markup View dalstoragesql.hpp]&lt;br /&gt;
* [http://themanaworld.svn.sourceforge.net/viewvc/*checkout*/themanaworld/tmwserv/trunk/src/account-server/dalstoragesql.hpp?revision=4024 Download dalstoragesql.hpp (plain text)]&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Database_specifications&amp;diff=10107</id>
		<title>Archive:Database specifications</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Database_specifications&amp;diff=10107"/>
		<updated>2008-09-14T13:50:46Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: /* Concerns */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Category_programming}}&lt;br /&gt;
&lt;br /&gt;
== SQL table specifications ==&lt;br /&gt;
&lt;br /&gt;
=== User accounts ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_accounts}}&lt;br /&gt;
{{sqltablerow| id            | INTEGER     | PRIMARY KEY      | | unique id of an account}}                      }}&lt;br /&gt;
{{sqltablerow|username       | TEXT        | NOT NULL UNIQUE  | | username / loginname of an user                }}&lt;br /&gt;
{{sqltablerow|password       | TEXT        | NOT NULL         | | password of an user (sha256 encoded)           }}&lt;br /&gt;
{{sqltablerow|email          | TEXT        | NOT NULL         | | email (sha256 encoded, only for pwd recovery)  }}&lt;br /&gt;
{{sqltablerow|level          | INTEGER     | NOT NULL         | | numeric level of the user account              }}&lt;br /&gt;
{{sqltablerow|banned         | INTEGER     | NOT NULL         | | unixtimestamp until when the account is banned }}&lt;br /&gt;
{{sqltablerow|registration   | INTEGER     | NOT NULL         | | unixtimestamp of account registration          }}&lt;br /&gt;
{{sqltablerow|lastlogin      | INTEGER     | NOT NULL         | | unixtimestamp of last login with client        }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Details ====&lt;br /&gt;
* email&lt;br /&gt;
** The email is stored as a one-way sha256 hash value. This ensures, that the email address a user enters cannot be used to send spam mails. It is only used to validate the mailaddress during password recovery procedure.&lt;br /&gt;
* level&lt;br /&gt;
** describes the user rights in the game (10 = normal user, 50 = gm, 99 = administrator)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Characters ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_characters}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY      |                 | unique id of the character                              }}&lt;br /&gt;
{{sqltablerow|user_id        | INTEGER     | NOT NULL         | tmw_accounts.id | id of the owner                                         }}&lt;br /&gt;
{{sqltablerow|name           | TEXT        | NOT NULL UNIQUE  |                 | name of the character                                   }}&lt;br /&gt;
{{sqltablerow|gender         | INTEGER     | NOT NULL         |                 | gender of the character (0/1)                           }}&lt;br /&gt;
{{sqltablerow|hair_style     | INTEGER     | NOT NULL         |                 | id of the hair sprite                                   }}&lt;br /&gt;
{{sqltablerow|hair_color     | INTEGER     | NOT NULL         |                 | id of the hair color                                    }}&lt;br /&gt;
{{sqltablerow|level          | INTEGER     | NOT NULL         |                 | experience level of the character                       }}&lt;br /&gt;
{{sqltablerow|char_pts       | INTEGER     | NOT NULL         |                 | available points to raise attributes                    }}&lt;br /&gt;
{{sqltablerow|correct_pts    | INTEGER     | NOT NULL         |                 | available points to lower attributes and regain char_pts}}&lt;br /&gt;
{{sqltablerow|money          | INTEGER     | NOT NULL         |                 | GP of the character                                     }}&lt;br /&gt;
{{sqltablerow|x              | INTEGER     | NOT NULL         |                 | x position of the character on the map                  }}&lt;br /&gt;
{{sqltablerow|y              | INTEGER     | NOT NULL         |                 | y position of the character on the map                  }}&lt;br /&gt;
{{sqltablerow|map_id         | INTEGER     | NOT NULL         | tmw_maps.id     | id of the current map the character is located          }}&lt;br /&gt;
{{sqltablerow|str            | INTEGER     | NOT NULL         |                 | strength of the character                               }}&lt;br /&gt;
{{sqltablerow|agi            | INTEGER     | NOT NULL         |                 | agility of the character                                }}&lt;br /&gt;
{{sqltablerow|dex            | INTEGER     | NOT NULL         |                 | dexternity of the character                             }}&lt;br /&gt;
{{sqltablerow|vit            | INTEGER     | NOT NULL         |                 | vitality of the character                               }}&lt;br /&gt;
{{sqltablerow|int            | INTEGER     | NOT NULL         |                 | intelligence of the character                           }}&lt;br /&gt;
{{sqltablerow|will           | INTEGER     | NOT NULL         |                 | willpower of the character                              }}&lt;br /&gt;
{{sqltablerow|unarmed_exp    | INTEGER     | NOT NULL         |                 | Experience: unarmed                                     }}&lt;br /&gt;
{{sqltablerow|knife_exp      | INTEGER     | NOT NULL         |                 | Experience: knifes                                      }}&lt;br /&gt;
{{sqltablerow|sword_exp      | INTEGER     | NOT NULL         |                 | Experience: swords                                      }}&lt;br /&gt;
{{sqltablerow|polearm_exp    | INTEGER     | NOT NULL         |                 | Experience: polearms                                    }}&lt;br /&gt;
{{sqltablerow|staff_exp      | INTEGER     | NOT NULL         |                 | Experience: staffs                                      }}&lt;br /&gt;
{{sqltablerow|whip_exp       | INTEGER     | NOT NULL         |                 | Experience: whips                                       }}&lt;br /&gt;
{{sqltablerow|bow_exp        | INTEGER     | NOT NULL         |                 | Experience: bows                                        }}&lt;br /&gt;
{{sqltablerow|shoot_exp      | INTEGER     | NOT NULL         |                 | Experience: shooting                                    }}&lt;br /&gt;
{{sqltablerow|mace_exp       | INTEGER     | NOT NULL         |                 | Experience: maces                                       }}&lt;br /&gt;
{{sqltablerow|axe_exp        | INTEGER     | NOT NULL         |                 | Experience: axes                                        }}&lt;br /&gt;
{{sqltablerow|thrown_exp     | INTEGER     | NOT NULL         |                 | Experience: throwing                                    }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Concerns ====&lt;br /&gt;
&lt;br /&gt;
* The way experience is part of this table really won&#039;t scale and isn&#039;t flexible in any way. It&#039;s currently already way too many variables in one table row, and these are just the weapon skills. So I think we should really have a separate table for storing skill levels similar to the character inventory table below. So something that has { character_id, skill_id, experience }. The &amp;lt;code&amp;gt;skill_id&amp;lt;/code&amp;gt; should point to a &amp;lt;code&amp;gt;skills.xml&amp;lt;/code&amp;gt; file which describes (and categorizes) each skill. In that way we&#039;ll be able to easily change the set of skills and their names later. --[[User:BjÃ¸rn|BjÃ¸rn]] 18:09, 12 September 2008 (CEST)&lt;br /&gt;
** I think the same should be done with the attributes (str .. will). In theory almost every attribute in this table could be handled that way, it might look like a mess, but would be really friendly in customizing the gameplay elements. --[[User:Kess|kess]] 19:54, 12 September 2008 (CEST)&lt;br /&gt;
** I agree with that completely as this will give us more flexibility and a much more relational database design. I&#039;ve extended the &amp;quot;DAL improvements&amp;quot; task in mantis: #424 --[[User:Exceptionfault|Exceptionfault]] 15:50, 14 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
=== Character Inventory ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_inventories}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY      |                   | unique id of the item                          }}&lt;br /&gt;
{{sqltablerow|owner_id       | INTEGER     | NOT NULL         | tmw_characters.id | id of the owning character                     }}&lt;br /&gt;
{{sqltablerow|slot           | INTEGER     | NOT NULL         |                   | inventory slot where the item is equipped      }}&lt;br /&gt;
{{sqltablerow|class_id       | INTEGER     | NOT NULL         |                   | type of the item, see items.xml file of tmwserv}}&lt;br /&gt;
{{sqltablerow|amount         | INTEGER     | NOT NULL         |                   | amount of items per slot                       }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Comments ====&lt;br /&gt;
* While I havenâ€™t looked how this table is used (my C++ knowledge is rather basic) it seems quite rigid and unflexible (as BjÃ¸rn noted above for the &#039;&#039;&#039;tmw_characters&#039;&#039;&#039; table). I think it would be nicer to have something like {&#039;&#039;owner_id&#039;&#039; FK, &#039;&#039;slot&#039;&#039;, &#039;&#039;item_id&#039;&#039; FK, &#039;&#039;amount&#039;&#039;, PK owner_id + slot}, where class_id shouldnâ€™t directly be needed in this table. --[[User:Kess|kess]] 19:49, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
=== Guilds ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_guilds}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY     |  | unique id of the guid   }}&lt;br /&gt;
{{sqltablerow|name           | TEXT        | NOT NULL UNIQUE |  | unique name of the guild}}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Guild memberships ===&lt;br /&gt;
&lt;br /&gt;
The table &#039;&#039;tmw_guild_members&#039;&#039; stores informations which character is member in which guild and which rights does he has.&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_guild_members}}&lt;br /&gt;
{{sqltablerow|guild_id        | INTEGER     | NOT NULL | tmw_guilds.id     | reference to the guild                                                }}&lt;br /&gt;
{{sqltablerow|member_id       | INTEGER     | NOT NULL | tmw_characters.id | reference to the characters                                           }}&lt;br /&gt;
{{sqltablerow|rights          | INTEGER     | NOT NULL |                   | id showing the rights a character has in this guild (member, admin...)}}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Quest states ===&lt;br /&gt;
&lt;br /&gt;
This table is used to store states of quests per character, e.g. if a character has just finished a quest or is currently at the second part of the long journey...&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_quests}}&lt;br /&gt;
{{sqltablerow|owner_id        | INTEGER     | NOT NULL | tmw_characters.id | reference to the character         }}&lt;br /&gt;
{{sqltablerow|name            | TEXT        | NOT NULL |                   | name of the quest variable         }}&lt;br /&gt;
{{sqltablerow|value           | TEXT        | NOT NULL |                   | current value of the quest variable}} &lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Comments ====&lt;br /&gt;
&lt;br /&gt;
* Unless this table is adapted so that it stores the state of a particular quest, this one should have a name which makes it move obvious that it&#039;s storing custom values for &#039;&#039;characters&#039;&#039;. I consider that different from quests variables, which I would expect to be scoped to a certain quest (global quest variables) or quest instance (local quest variables). --[[User:BjÃ¸rn|BjÃ¸rn]] 18:16, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* We might want to have a similar table to this to store custom values for item instances, and also one for custom world-state variables. --[[User:BjÃ¸rn|BjÃ¸rn]] 18:16, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
* I always wondered why Silene used the terminology &amp;quot;Quest&amp;quot; for what is basically a system to store/querry persistent character-bound integer variables which can be used for countless purposes, not just quests. I think we should rename this whole system to &amp;quot;character variable&amp;quot; in the database, server source and script bindings. --[[User:Crush2|Crush2]] 23:28, 12 September 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Reference  ==&lt;br /&gt;
&lt;br /&gt;
Since the database is changing relatively often while we&#039;re still developing 0.1.0 and nobody likes to keep this page up to date, here is the link to the source code that specifies creation of the database tables. The source code is always right!&lt;br /&gt;
&lt;br /&gt;
* [http://themanaworld.svn.sourceforge.net/viewvc/themanaworld/tmwserv/trunk/src/account-server/dalstoragesql.hpp?view=markup View dalstoragesql.hpp]&lt;br /&gt;
* [http://themanaworld.svn.sourceforge.net/viewvc/*checkout*/themanaworld/tmwserv/trunk/src/account-server/dalstoragesql.hpp?revision=4024 Download dalstoragesql.hpp (plain text)]&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Database_specifications&amp;diff=10097</id>
		<title>Archive:Database specifications</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Database_specifications&amp;diff=10097"/>
		<updated>2008-09-12T13:54:02Z</updated>

		<summary type="html">&lt;p&gt;Exceptionfault: updated tablespecs to use sqltable templates&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Category_programming}}&lt;br /&gt;
&lt;br /&gt;
== SQL table specifications ==&lt;br /&gt;
&lt;br /&gt;
=== User accounts ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_accounts}}&lt;br /&gt;
{{sqltablerow| id            | INTEGER     | PRIMARY KEY      | | unique id of an account}}                      }}&lt;br /&gt;
{{sqltablerow|username       | TEXT        | NOT NULL UNIQUE  | | username / loginname of an user                }}&lt;br /&gt;
{{sqltablerow|password       | TEXT        | NOT NULL         | | password of an user (sha256 encoded)           }}&lt;br /&gt;
{{sqltablerow|email          | TEXT        | NOT NULL         | | email (sha256 encoded, only for pwd recovery)  }}&lt;br /&gt;
{{sqltablerow|level          | INTEGER     | NOT NULL         | | numeric level of the user account              }}&lt;br /&gt;
{{sqltablerow|banned         | INTEGER     | NOT NULL         | | unixtimestamp until when the account is banned }}&lt;br /&gt;
{{sqltablerow|registration   | INTEGER     | NOT NULL         | | unixtimestamp of account registration          }}&lt;br /&gt;
{{sqltablerow|lastlogin      | INTEGER     | NOT NULL         | | unixtimestamp of last login with client        }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
==== Details ====&lt;br /&gt;
* email&lt;br /&gt;
** The email is stored as a one-way sha256 hash value. This ensures, that the email address a user enters cannot be used to send spam mails. It is only used to validate the mailaddress during password recovery procedure.&lt;br /&gt;
* level&lt;br /&gt;
** describes the user rights in the game (10 = normal user, 50 = gm, 99 = administrator)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Characters ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_characters}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY      |                 | unique id of the character                              }}&lt;br /&gt;
{{sqltablerow|user_id        | INTEGER     | NOT NULL         | tmw_accounts.id | id of the owner                                         }}&lt;br /&gt;
{{sqltablerow|name           | TEXT        | NOT NULL UNIQUE  |                 | name of the character                                   }}&lt;br /&gt;
{{sqltablerow|gender         | INTEGER     | NOT NULL         |                 | gender of the character (0/1)                           }}&lt;br /&gt;
{{sqltablerow|hair_style     | INTEGER     | NOT NULL         |                 | id of the hair sprite                                   }}&lt;br /&gt;
{{sqltablerow|hair_color     | INTEGER     | NOT NULL         |                 | id of the hair color                                    }}&lt;br /&gt;
{{sqltablerow|level          | INTEGER     | NOT NULL         |                 | experience level of the character                       }}&lt;br /&gt;
{{sqltablerow|char_pts       | INTEGER     | NOT NULL         |                 | available points to raise attributes                    }}&lt;br /&gt;
{{sqltablerow|correct_pts    | INTEGER     | NOT NULL         |                 | available points to lower attributes and regain char_pts}}&lt;br /&gt;
{{sqltablerow|money          | INTEGER     | NOT NULL         |                 | GP of the character                                     }}&lt;br /&gt;
{{sqltablerow|x              | INTEGER     | NOT NULL         |                 | x position of the character on the map                  }}&lt;br /&gt;
{{sqltablerow|y              | INTEGER     | NOT NULL         |                 | y position of the character on the map                  }}&lt;br /&gt;
{{sqltablerow|map_id         | INTEGER     | NOT NULL         | tmw_maps.id     | id of the current map the character is located          }}&lt;br /&gt;
{{sqltablerow|str            | INTEGER     | NOT NULL         |                 | strength of the character                               }}&lt;br /&gt;
{{sqltablerow|agi            | INTEGER     | NOT NULL         |                 | agility of the character                                }}&lt;br /&gt;
{{sqltablerow|dex            | INTEGER     | NOT NULL         |                 | dexternity of the character                             }}&lt;br /&gt;
{{sqltablerow|vit            | INTEGER     | NOT NULL         |                 | vitality of the character                               }}&lt;br /&gt;
{{sqltablerow|int            | INTEGER     | NOT NULL         |                 | intelligence of the character                           }}&lt;br /&gt;
{{sqltablerow|will           | INTEGER     | NOT NULL         |                 | willpower of the character                              }}&lt;br /&gt;
{{sqltablerow|unarmed_exp    | INTEGER     | NOT NULL         |                 | Experience: unarmed                                     }}&lt;br /&gt;
{{sqltablerow|knife_exp      | INTEGER     | NOT NULL         |                 | Experience: knifes                                      }}&lt;br /&gt;
{{sqltablerow|sword_exp      | INTEGER     | NOT NULL         |                 | Experience: swords                                      }}&lt;br /&gt;
{{sqltablerow|polearm_exp    | INTEGER     | NOT NULL         |                 | Experience: polearms                                    }}&lt;br /&gt;
{{sqltablerow|staff_exp      | INTEGER     | NOT NULL         |                 | Experience: staffs                                      }}&lt;br /&gt;
{{sqltablerow|whip_exp       | INTEGER     | NOT NULL         |                 | Experience: whips                                       }}&lt;br /&gt;
{{sqltablerow|bow_exp        | INTEGER     | NOT NULL         |                 | Experience: bows                                        }}&lt;br /&gt;
{{sqltablerow|shoot_exp      | INTEGER     | NOT NULL         |                 | Experience: shooting                                    }}&lt;br /&gt;
{{sqltablerow|mace_exp       | INTEGER     | NOT NULL         |                 | Experience: maces                                       }}&lt;br /&gt;
{{sqltablerow|axe_exp        | INTEGER     | NOT NULL         |                 | Experience: axes                                        }}&lt;br /&gt;
{{sqltablerow|thrown_exp     | INTEGER     | NOT NULL         |                 | Experience: throwing                                    }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Character Inventory ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_inventories}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY      |                   | unique id of the item                          }}&lt;br /&gt;
{{sqltablerow|owner_id       | INTEGER     | NOT NULL         | tmw_characters.id | id of the owning character                     }}&lt;br /&gt;
{{sqltablerow|slot           | INTEGER     | NOT NULL         |                   | inventory slot where the item is equipped      }}&lt;br /&gt;
{{sqltablerow|class_id       | INTEGER     | NOT NULL         |                   | type of the item, see items.xml file of tmwserv}}&lt;br /&gt;
{{sqltablerow|amount         | INTEGER     | NOT NULL         |                   | amount of items per slot                       }}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Guilds ===&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_guilds}}&lt;br /&gt;
{{sqltablerow|id             | INTEGER     | PRIMARY KEY     |  | unique id of the guid   }}&lt;br /&gt;
{{sqltablerow|name           | TEXT        | NOT NULL UNIQUE |  | unique name of the guild}}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Guild memberships ===&lt;br /&gt;
&lt;br /&gt;
The table &#039;&#039;tmw_guild_members&#039;&#039; stores informations which character is member in which guild and which rights does he has.&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_guild_members}}&lt;br /&gt;
{{sqltablerow|guild_id        | INTEGER     | NOT NULL | tmw_guilds.id     | reference to the guild                                                }}&lt;br /&gt;
{{sqltablerow|member_id       | INTEGER     | NOT NULL | tmw_characters.id | reference to the characters                                           }}&lt;br /&gt;
{{sqltablerow|rights          | INTEGER     | NOT NULL |                   | id showing the rights a character has in this guild (member, admin...)}}&lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Quest states ===&lt;br /&gt;
&lt;br /&gt;
This table is used to store states of quests per character, e.g. if a character has just finished a quest or is currently at the second part of the long journey...&lt;br /&gt;
&lt;br /&gt;
{{beginsqltable|tmw_guild_members}}&lt;br /&gt;
{{sqltablerow|owner_id        | INTEGER     | NOT NULL | tmw_characters.id | reference to the character         }}&lt;br /&gt;
{{sqltablerow|name            | TEXT        | NOT NULL |                   | name of the quest variable         }}&lt;br /&gt;
{{sqltablerow|value           | TEXT        | NOT NULL |                   | current value of the quest variable}} &lt;br /&gt;
{{endsqltable}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Reference  ==&lt;br /&gt;
&lt;br /&gt;
Since the database is changing relatively often while we&#039;re still developing 0.1.0 and nobody likes to keep this page up to date, here is the link to the source code that specifies creation of the database tables. The source code is always right!&lt;br /&gt;
&lt;br /&gt;
* [http://themanaworld.svn.sourceforge.net/viewvc/themanaworld/tmwserv/trunk/src/account-server/dalstoragesql.hpp?view=markup View dalstoragesql.hpp]&lt;br /&gt;
* [http://themanaworld.svn.sourceforge.net/viewvc/*checkout*/themanaworld/tmwserv/trunk/src/account-server/dalstoragesql.hpp?revision=4024 Download dalstoragesql.hpp (plain text)]&lt;/div&gt;</summary>
		<author><name>Exceptionfault</name></author>
	</entry>
</feed>