Skip to content

SetCampaignInt

Hi,
first time poster, fresh builder with basic programming knowledge.

The function
int iXP;
iXP = GetXP(oPC);
SetCampaignInt("XP","PLAYERXP",iXP,oPC);

results in no new record in the database, when the players xp is zero. Nor does any other int with 0 value.

Whereas
SetCampaignString("XP","PLAYERXP",IntToString(iXP),oPC);

SetCampaignJson("XP","PLAYERXP",JsonInt(iXP),oPC);

both work. Or at least both lead to the result
INSERT INTO "main"."db" ("payload") VALUES (X'43504442030000000200000002000000010000000000000028b52ffd200211000030');

aka

CPDB............ ........(./. ... .0

Is this wad or am I missing something?

Comments

  • MelkiorMelkior Member Posts: 181
    This is interesting and I can only speculate that it was done this way because the non-existence of a numeric variable in a database will always return zero if you attempt to read that variable from the database. In other words, it makes no difference whether a zero is stored or not; when you go to read that variable back, you will get zero back rather than an error.

    While only the original programmers of the system could confirm my speculation, I believe it was done this way just to save disk space.
  • CommonerXCommonerX Member Posts: 7
    Melkior wrote: »
    This is interesting and I can only speculate that it was done this way because the non-existence of a numeric variable in a database will always return zero if you attempt to read that variable from the database. In other words, it makes no difference whether a zero is stored or not; when you go to read that variable back, you will get zero back rather than an error.

    While only the original programmers of the system could confirm my speculation, I believe it was done this way just to save disk space.

    Thank you for answering. This has a certain logic to it, although a bit sloppy and not completely without issues.
  • CommonerXCommonerX Member Posts: 7
    edited December 2023
    Melkior wrote: »
    This is interesting and I can only speculate that it was done this way because the non-existence of a numeric variable in a database will always return zero if you attempt to read that variable from the database. In other words, it makes no difference whether a zero is stored or not; when you go to read that variable back, you will get zero back rather than an error.

    While only the original programmers of the system could confirm my speculation, I believe it was done this way just to save disk space.
    Melkior wrote: »
    This is interesting and I can only speculate that it was done this way because the non-existence of a numeric variable in a database will always return zero if you attempt to read that variable from the database. In other words, it makes no difference whether a zero is stored or not; when you go to read that variable back, you will get zero back rather than an error.

    While only the original programmers of the system could confirm my speculation, I believe it was done this way just to save disk space.

    As information, a test run with
    int iXP;
    object oPC = GetEnteringObject();
    string s;
    iXP = GetXP(oPC);
    SetCampaignInt("AVATAR_PERSISTENCE","PLAYERXP",iXP,oPC);
    s = IntToString(GetCampaignInt("AVATAR_PERSISTENCE","PLAYERXP",oPC));
    SendMessageToPC(oPC, "You have "+s+" XP.");
    

    returned with "You have 0 XP."

    EDIT: typos
    Post edited by CommonerX on
  • NeverwinterWightsNeverwinterWights Member Posts: 339
    CommonerX wrote: »
    int iXP;
    object oPC = GetEnteringObject();
    string s;
    iXP = GetXP(oPC);
    SetCampaignInt("XP","PLAYERXP",iXP,oPC);
    s = IntToString(GetCampaignInt("AVATAR_PERSISTENCE","PLAYERXP",oPC));
    SendMessageToPC(oPC, "You have "+s+" XP.");
    

    returned with "You have 0 XP."

    It looks as though you are setting the variable "PLAYERXP" in one campaign database ("XP") and then trying to retrieve it from another ("AVATAR_PERSISTENCE").
  • CommonerXCommonerX Member Posts: 7
    CommonerX wrote: »
    int iXP;
    object oPC = GetEnteringObject();
    string s;
    iXP = GetXP(oPC);
    SetCampaignInt("XP","PLAYERXP",iXP,oPC);
    s = IntToString(GetCampaignInt("AVATAR_PERSISTENCE","PLAYERXP",oPC));
    SendMessageToPC(oPC, "You have "+s+" XP.");
    

    returned with "You have 0 XP."

    It looks as though you are setting the variable "PLAYERXP" in one campaign database ("XP") and then trying to retrieve it from another ("AVATAR_PERSISTENCE").

    Thank you. That is a copy/paste error. :smile: Actual script had it with the same name.
  • ForSeriousForSerious Member Posts: 446
    I've had issues with oPC parameter. I gave up on it working consistently. I made a tagging system and add that as a prefix or suffix on the variable name.
  • MelkiorMelkior Member Posts: 181
    ForSerious wrote: »
    I've had issues with oPC parameter. I gave up on it working consistently. I made a tagging system and add that as a prefix or suffix on the variable name.

    Long ago, I gave up on even attempting to use fancy parameters in databases, or for the most part, even attempting to store anything but a NPC into a database (with just one exception). Instead, the NPC holds an undroppable object which is given all of the parameters relating to a particular PC, and the file name for the database is comprised of the account name and CD key for the PC. To prevent database bloat, I always delete the database entirely before saving the NPC to a database with the same name.

    I do it that way because if you save a new entry to a database and the new entry has the same identifier as a previously saved entry, it doesn't actually delete the previous entry but just marks it as unused and appends the replacement to the end of the database.

    The only exception which I've ever used was a "flag" database which was never going to be changed. That was used to make a server restart on a real-world fixed schedule. The server would, every module heartbeat, attempt to read an integer from a database. Since the database didn't exist, the integer would come back zero and the module would continue uninterrupted.

    The Task Scheduler in Windows was set to automatically copy a database into the correct folder at a certain time of day. That database contained the integer with a non-zero value which would signal the module to start the "reset" sequence, which used NWNX2 to complete the shutdown-restart sequence (after issuing warnings in plenty of time for players to finish what they were doing). Part of the shutdown sequence included deleting the database so that the server would not instantly go back into shutdown mode right after starting up again.
  • CommonerXCommonerX Member Posts: 7
    This looks like a problem with the interface to the database. Maybe a mix-up with <update> and <insert> commands.
    <SetCampaign> overwrites without further ado, even if the data type for the same VarName changes. At least this is the case with my tiny test databases.
  • ForSeriousForSerious Member Posts: 446
    I believe that that has always been the case.
  • DazDaz Member Posts: 126
    Pre-EE the campaign databases used Codebase(iirc) which suffered from not actually deleting things when you told it to. EE changed the database backend to SQLite, which doesn't suffer from that issue.
  • MelkiorMelkior Member Posts: 181
    Daz wrote: »
    Pre-EE the campaign databases used Codebase(iirc) which suffered from not actually deleting things when you told it to. EE changed the database backend to SQLite, which doesn't suffer from that issue.

    I remember reading something about the database backend being changed, but didn't know what that implied. I'm glad to know that it finally deletes things when asked instead of leaving garbage behind.
  • CommonerXCommonerX Member Posts: 7
    Melkior wrote: »
    I remember reading something about the database backend being changed, but didn't know what that implied. I'm glad to know that it finally deletes things when asked instead of leaving garbage behind.

    My very little experimenting with the sql functions so far didn't bring up any issue. Even set up a DB with external means and adressed it with <SqlPrepareQueryCampaign> and <SqlStep> without problems.
Sign In or Register to comment.