logo logo

 Back to main page

The NWNX Community Forum

 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 
 
First time install of NWNX4 and MySQL

 
Post new topic   Reply to topic    nwnx.org Forum Index -> Database related
View previous topic :: View next topic  
Author Message
Lugoun



Joined: 18 May 2007
Posts: 36

PostPosted: Tue Sep 18, 2007 20:26    Post subject: First time install of NWNX4 and MySQL Reply with quote

I am almost completely inexperienced with server and database administration.

At this time, on my local machine, I have successfully installed MySQL Server and the MySQL Tools, and have successfully run the demo module and verified that the data was persistent (available after a mod/server restart, and located the data in the pwdata table using the MySQL Tools).

Soon I will be working with the server admin to get everything set up on our server (which I understand is one box with several virtual machines), and I have some questions:

1) General advice - Are there any general recommendations/known pitfalls/tips for setting up/structuring/installing MySQL and NWNX on a server for a multi-module PW?

2) DB Management - Are there any suggestions, tips, or advice on management of the persistent data? For example, should I set up multiple tables now to handle major data categories? Exactly what is the use of the "pwobjdata" (may have the name wrong) table if nwnx_sql defaults to "pwdata"?

3) Module Settings - Other than having the include files in the module, are there any other settings that need to be in place to make this system work correctly (like module onload commands etc)?

4) Source/Example Wanted - I am interested in an example that I could use to retrieve persistent player data from the db and set them up as locals on a character when joining the mod for the first time since the last module start. Can someone point me the right direction?

Thanks!
Lugoun
_________________
Lugoun
www.hotta-rpg.org
Back to top
View user's profile Send private message
Lugoun



Joined: 18 May 2007
Posts: 36

PostPosted: Sat Sep 22, 2007 21:42    Post subject: Reply with quote

No advice for the newbie?
_________________
Lugoun
www.hotta-rpg.org
Back to top
View user's profile Send private message
Gryphyn



Joined: 20 Jan 2005
Posts: 431

PostPosted: Sun Sep 23, 2007 0:47    Post subject: Reply with quote

How do I put this... RTFM...

Quote:
At this time, on my local machine, I have successfully installed MySQL Server and the MySQL Tools, and have successfully run the demo module and verified that the data was persistent (available after a mod/server restart, and located the data in the pwdata table using the MySQL Tools).


This indicates (to most of us - me anyway) that you've already answered your questions 1-4. If you've got the demo running your 80% the way there. but here are some more direct answers.

1. There is no single way to do it, check the forums and see the heated discussions (at times). You've got the demo running so that's good enough unless you have a specific question or requirement.

2. "pwobjdata" is used to store game object data. this is a feature of nwnx2, but not yet available to nwnx4. Keep it, it won't hurt. Anything else will be specific to your needs.

3. Your demo is working, so you have your system working correctly. (and)

4. The demo is you source and example. Open the demo module and have a look, that's what it is there for.

Finally, there is plenty of info in the 'Documentation' section of the forum. This covers the basics of installation, module setup and the like. Read it. (and it seems you already have)

Anything else, meaning specific issues, can be addressed as they arise. Check out some of the 'plugins' thay may have extra functionality to meet your needs, or that you can use (also with demo's)

The forums themselves are a good resource, don't limit yourself to recent pages, a great deal of advice and debate on your topics has already taken place - and continues to take place.

Not much extra help I know, but as you state you're most of the way there already.

Cheers
Gryphyn
Back to top
View user's profile Send private message
Lugoun



Joined: 18 May 2007
Posts: 36

PostPosted: Sun Sep 23, 2007 9:04    Post subject: Reply with quote

Quote:
How do I put this... RTFM...

Thats pretty brutal man. I'm sure I showed I've been doing my homework and I dont think the answers to any of my questions are in the FM.

Still, thanks for the tip about the forums and the info about pwobjdata.

I would still appreciate any specific advice or information about other places I can research before trying to reinvent the wheel.
_________________
Lugoun
www.hotta-rpg.org
Back to top
View user's profile Send private message
Gryphyn



Joined: 20 Jan 2005
Posts: 431

PostPosted: Sun Sep 23, 2007 10:05    Post subject: Reply with quote

Lugoun wrote:
Quote:
How do I put this... RTFM...

Thats pretty brutal man. I'm sure I showed I've been doing my homework and I dont think the answers to any of my questions are in the FM.

Still, thanks for the tip about the forums and the info about pwobjdata.

I would still appreciate any specific advice or information about other places I can research before trying to reinvent the wheel.

Sorry 'bout that...
You seemed to have basics down, and you're in the right place.
But your questions are similar to asking about the weather...

OK, for some specific stuff.
Check out NWVault for some of the nwnx contributions - you get all sorts of stuff from HCR, CNR and a whole heap more. Some you'll want others you wont.
Check out the bioware forums - you get a little info there on systems others use, and some of the issues.

It'll be much easier to help, if we have something concrete to aim at/towards.

Since NWN2 the ranks have thinned. We'll try but we're not as responsive as we use to be.

Cheers
Gryphyn
Back to top
View user's profile Send private message
Papillon
x-man


Joined: 28 Dec 2004
Posts: 1060
Location: Germany

PostPosted: Sun Sep 23, 2007 20:53    Post subject: Re: First time install of NWNX4 and MySQL Reply with quote

Lugoun wrote:
4) Source/Example Wanted - I am interested in an example that I could use to retrieve persistent player data from the db and set them up as locals on a character when joining the mod for the first time since the last module start. Can someone point me the right direction?


Store a variable on a character:
SetPersistentString(oPC, "myVariable", "myValue");

Retrieve a variable for a character:
string s = GetPersistentString(oPC, "myVariable");

If you want to store this value as a local, just call SetLocaLString() afterwards. This is a very basic example, but since you asked a basic question, this should point you into the right direction for now.
_________________
Papillon
Back to top
View user's profile Send private message Visit poster's website MSN Messenger
Lugoun



Joined: 18 May 2007
Posts: 36

PostPosted: Wed Sep 26, 2007 18:54    Post subject: Reply with quote

Quote:
But your questions are similar to asking about the weather...

Hmm it seems sensible to me to ask about the weather if you've never seen the sky before Smile


Quote:
If you want to store this value as a local, just call SetLocaLString() afterwards. This is a very basic example, but since you asked a basic question, this should point you into the right direction for now.


Oh, I get it, I wasnt very clear with my question. I'm fine with the Get and Set functions.

I was interested in something that could cycle through the DB and retrieve ALL the player's variables and set them as locals.

As you are aware that is something that cant really be done in nwn script unless you know the names of each and every variable and retrieve each one individually (or if they are like named sequentially, you could probably do a loop of some sort).

I believe that this is something that could be done with SQL.

I dont know if its necessary, but I was hoping to reduce the number of calls to and from the db by setting every variable on the player as a local, and not have to worry about going back and updating the 'Cycle-Retrieve all Persistent, set as Local' script every time I add a new persisent variable.

So, when a player enters for the first time after a module restart, all their persistent data is set as locals. My mod scripts would GetLocal instead of GetPersistent. Whenever I SetPersistent, I would also SetLocal (probably using a custom function combining the two).

Since I have no idea how to build that kind of an SQL function to use in SQLExecDirect, I was hoping for advice on that. It seemed to me something that might be relatively common.

I can go hit the general MySQL documentation and try to figure it out, but this is what I was trying to avoid, if it is something commonly used or easily accomplished.

I'd rather focus on the module scripts for now.
_________________
Lugoun
www.hotta-rpg.org
Back to top
View user's profile Send private message
Gryphyn



Joined: 20 Jan 2005
Posts: 431

PostPosted: Thu Sep 27, 2007 0:11    Post subject: Reply with quote

Quote:
Since I have no idea how to build that kind of an SQL function to use in SQLExecDirect, I was hoping for advice on that. It seemed to me something that might be relatively common.


About NXNX4

Have a look at the "Random Treasure" example (mid page)
This shows the general pattern of usage for SQLExecDirect()

Cheers
Gryphyn
Back to top
View user's profile Send private message
Lugoun



Joined: 18 May 2007
Posts: 36

PostPosted: Thu Sep 27, 2007 2:25    Post subject: Reply with quote

Ok, I mined some of the older forum scripts for info, and found something that appears to do something like what I need. Here it is modified for my purposes:

Code:

#include "nwnx_sql"

void main()

object oEntering = GetEnteringObject();
int nPersistentRetrieved = GetLocalInt(oEntering, "nPersistentRetrieved");

if(GetIsPC(oEntering) && !GetIsDM(oEntering) && nPersistentRetrieved == FALSE)
{
   string sPlayer = SQLEncodeSpecialChars(GetPCPlayerName(oEntering));

   string sSQL =    "SELECT name, val" +
         "FROM pwdata " +
         "WHERE player= '" + sPlayer + "'";
   SQLExecDirect(sSQL);
   while(SQLFetch() == SQL_SUCCESS)
   {
      string sVarName = SQLGetData(1);
      string sVarType = GetStringLeft(sVarName, 1);

      if (sVarType == "n" || sVarType == "b")
         SetLocalInt(oEntering, sVarName, StringToInt(SQLGetData(2)));
      else if(sVarType == "f")
         SetLocalFloat(oEntering, sVarName, StringToFloat(SQLGetData(2)));
      else if(sVarType == "s")
         SetLocalString(oEntering, sVarName, SQLGetData(2));
      else
         //debug message variable name does not begin with expected prefix
         SetLocalString(oEntering, sVarName, SQLGetData(2));
   }
   
   SetLocalInt(oEntering, "nPersistentRetrieved", TRUE);
}


Is there anything very obviously wrong with this? I wasnt sure if it would be necessary to call the SQLExecDirect again at the bottom of the while, or what needed to be done to prompt it to get the next variable and do it again?

Any other info comments and suggestions would be appreciated.
_________________
Lugoun
www.hotta-rpg.org
Back to top
View user's profile Send private message
Gryphyn



Joined: 20 Jan 2005
Posts: 431

PostPosted: Thu Sep 27, 2007 9:44    Post subject: Reply with quote

SQLExecDirect() = Ask the question,
SQLFetch() = Get the next row (if there is one)

calling SQLExecDirect() a second time would have created a new set of data

... you need a bit more information to get data form the 'pwdata' table.
Players usually have more than one character. Have a look at the demo mod and see how it's done.

... but for what you're trying to do you would be better off just using the
GetPersistent...() and SetPersistent...() functions. All the SQL stuff will be done for you.

Code:
#include "nwnx_sql"
void main()
{
   object oEntering = GetEnteringObject();
   int nPersistentRetrieved = GetLocalInt(oEntering, "nPersistentRetrieved");
  if(GetIsPC(oEntering) & !GetIsDM(oEntering) & nPersistentRetrieved != 1)
  {
     SetLocal...(oEntering, "varName", GetPersistent...(oEntering, "varName"));
     ...
     SetLocalInt(oEntering, "nPersistentRetrieved", 1);
  }
}

You should know what the "varNames" are, so you can just make a list of them in your code, rather than trying to maintain a database of them. It's the values you won't know.

Cheers
Gryphyn
Back to top
View user's profile Send private message
Lugoun



Joined: 18 May 2007
Posts: 36

PostPosted: Thu Sep 27, 2007 20:02    Post subject: Reply with quote

Great, the first part was really helpful.

There are several reasons I wish to loop and find the variables this way, not the least of which is less maintenance (not having to update a script everytime a new variable for player is to be tracked, and the extra coordination that involves when working with a team). Also, many scripts were written with a different system in mind and those involve GetLocal. Im also not interested in tracking those down and editing them if its not necessary. I can think of other applications that this loop could be used for as well.

Anyway, based on the additional information I've updated the code a bit. So, does adding SQLFetch() at the end do the trick? Or, is it just called again in the "while(SQLFeth() == SQL_SUCCESS)" making the added SQLFetch unnecessary? If it looks good either way (with or without the exta SQLFetch), I'll try to test this weekend.

Code:

#include "nwnx_sql"

void main()

object oEntering = GetEnteringObject();
int nPersistentRetrieved = GetLocalInt(oEntering, "nPersistentRetrieved");

if(GetIsPC(oEntering) && !GetIsDM(oEntering) && nPersistentRetrieved == FALSE)
{
   string sPlayer = SQLEncodeSpecialChars(GetPCPlayerName(oEntering));
   string sTag = SQLEncodeSpecialChars(GetName(oEntering));

   string sSQL =    "SELECT name, val " +
         "FROM pwdata " +
         " WHERE player='" + sPlayer + "' AND tag='" + sTag + "'";
   SQLExecDirect(sSQL);
   while(SQLFetch() == SQL_SUCCESS)
   {
      string sVarName = SQLGetData(1);
      string sVarType = GetStringLeft(sVarName, 1);

      if (sVarType == "n" || sVarType == "b")
         SetLocalInt(oEntering, sVarName, StringToInt(SQLGetData(2)));
      else if(sVarType == "f")
         SetLocalFloat(oEntering, sVarName, StringToFloat(SQLGetData(2)));
      else if(sVarType == "s")
         SetLocalString(oEntering, sVarName, SQLGetData(2));
      else
         //debug message variable name does not begin with expected prefix
         SetLocalString(oEntering, sVarName, SQLGetData(2));
      
**added------>      SQLFetch();
   }
   
   SetLocalInt(oEntering, "nPersistentRetrieved", TRUE);
}

_________________
Lugoun
www.hotta-rpg.org
Back to top
View user's profile Send private message
Gryphyn



Joined: 20 Jan 2005
Posts: 431

PostPosted: Thu Sep 27, 2007 23:59    Post subject: Reply with quote

No, you don't want that last SQLFetch()

what happens is, when the while tests for the condition. it does a SQLFetch() to get the next row.

An extra one would have you reading every 2nd row. Wink


Cheers
Gryphyn
Back to top
View user's profile Send private message
Papillon
x-man


Joined: 28 Dec 2004
Posts: 1060
Location: Germany

PostPosted: Sun Sep 30, 2007 12:16    Post subject: Reply with quote

@Lugoun: I might be able to offer a piece of advice.

Start small and simple.

You probably do not have a the complete picture of your world and the corresponding database structure in mind, yet. What you are trying to do sounds like it would actually degrade performance at some point in time:

a) You will have many, many variables that might only be read once in a couple of hours. A player logging in with many variables might therefore make the server hiccup a little. Also, most variables will not be used in a single session and so their space is wasted.

b) You are not going to use the advanced data structures that are possible with SQL, since you only want to optimize the GET/SET persistent functions. Better structures mean much more performance improvement than caching the basic pwdata structure.

I would start with the basic functions in nwnx_sql, only. The database answers quite fast, so you will not notice performance problems if you do not query 100's of variables every second (which you will not do as a sensible programmer). After that, you will probably create specialized tables that optimally reflect the type of data you want to store.
_________________
Papillon
Back to top
View user's profile Send private message Visit poster's website MSN Messenger
Lugoun



Joined: 18 May 2007
Posts: 36

PostPosted: Tue Oct 02, 2007 2:54    Post subject: Reply with quote

Thanks for the advice.

I actually am trying to get things mapped out for the future and its making my head hurt Smile

After consideration this weekend, I did end up scrapping the idea of doing the whole data dump pwdata to locals and will update existing scripts to nwnx_sql as necessary.

For the time being I've settled on three tables, pwdata and two of my own, one for quests and another for faction data (basically duplicates of pwdata).

I will still be using a modified version of the loop above to add quests to the nwn campaign journal after mod restarts. This will be handy because it wont be necessary to modify the script every time a quest is added, and every row for that player should be needed.

Thanks again. I'm sure Ill be back Smile
_________________
Lugoun
www.hotta-rpg.org
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    nwnx.org Forum Index -> Database related All times are GMT + 2 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group