Skip to content

PW Design tips for seasoned SP designer

philbophilbo Member Posts: 19
Hey everyone. I've spent a whole lot of time making SP modules with the Aurora toolset, but I am about to embark on making a PW module.

What are the main things that I should be aware of when designing a PW module as opposed to a SP module? When it comes to scripting, quests, dialog, variables, etc...

I wish I could be more specific, but I simply don't know what I don't know. Any tips would be much appreciated!

Comments

  • GM_ODAGM_ODA Member Posts: 177
    You can never guess how many members or want mix of party members you'll have so.... build your encounters to scale with party size.

    Questing takes some planning since you cannot count on the same player talking to all the NPCs in the quest.

    Plan on 'meeting zones' where traffic can converge an parties form up.

    Come visit the server (Argentum Regio) and we can talk shop if you like. :)

  • philbophilbo Member Posts: 19
    Thank you! This helps immensely.

    While I have you here, perhaps you can help me with a particular concern I have:

    Is it very difficult to update PW modules? I had in mind a game world where new quests and areas are added somewhat regularly. Wondering if this is even possible.
  • FreshLemonBunFreshLemonBun Member Posts: 909
    You pull the server down, upload the new module, put it back up.

    You could use a database to populate some parts of your server so rather than pull it down you update an entry in the database and have the game sync up and switch out the dialogue.

    The Sinfar server is probably the most advanced in that regard allowing them to add whole new areas and dynamically add content without ever switching out the entire module. This even allows them to let players add custom housing from self made areas on the fly. You'll have to ask Mavrixio all the technical details of how they do it. I'm not sure it would be possible with this version of the game.
  • badstrrefbadstrref Member Posts: 124
    edited December 2018
    hello,
    some, tips...

    -You'll have to save characters periodically in case of a server crash. I use a function of this type for recuring tasks (on Module load)
    
    void CycleSaveAll()
    {
    	// Export all characters
    DelayCommand(fDelay, CycleSaveAll()); // Calls itself
    }

    but also single export OnRest, on important event (earned rare loot) etc

    -You'll need NWNX to provide a character deleter in game (or delete by hand by player's request wich can turn daunting), and a watchdog to reboot your server automatically.
    -The basic persistent saving data functions are a bit dangerous to use, NBDE is a solution if you are not using SQL.

    -You will have to decide for a loot / drops cleanup system.
    Sometimes only one member of a party take the loot, if you want everyone to earn it, you can for example spawn a chest, that is empty, but onOpen event generate directly loot in player's inventory, and flag their account name/ cdkey so they cant reuse the chest (and later destroy it)

    - You have to clean AoEs because if they are persistent, and damaging ennemies, while u are on another map trying, for example, talk to a merchant, you will not be able to since "in combat" technically. this can be annoying after you die and then try to use a dialogue to respawn

    -For XP i setup Module's XP scale to zero, and I don't use GiveXPtoCreature function since it takes into account the multiclass penalty, but SetXP(oPC, GetXp(oPC) + nAmount) - its up to you.

    -Players may be hiding their true level, this is bad for many reasons, here are some functions to help :
    
    
    int GetHDFromXP(int nXP, int nHD = 1)
    {
       int nNextLvl;
       int nNextXP;
       int i;
       for (i = nHD; i<=40; i++)
       {
          nNextLvl = i + 1;
          nNextXP = ((nNextLvl * (nNextLvl - 1)) / 2) * 1000;
          if (nXP < nNextXP) return i;
       }
       return nHD;
    }
    
    int GetRealLevel(object oPC)
    {
       int nXP = GetXP(oPC);
       int nHD = GetHitDice(oPC);
       return GetHDFromXP(nXP, nHD);
    }
    
    


    -You must think of everyway a player can abuse your server :
    -Players may block path for other players, prevent them from resting, (by attacking npc and placeable) etc
    -They may keep busy important NPC's by attacking them (use appropriate event to stop it), and preventing quest completion etc.
    -If your NPC is 'pushable' using WASD, players can push them and hide them in a corner,
    If you want a NPC to not move due to player pushing : set it to immobile and reputation toward player faction to 50, because friendly and Ennemy will make it available for pushing (iirc i may not be totally correct here, need to re-test but it IS related to reputation).
    -Players can hide NPC's using invisibility spells, you can catch this on appropriate event.
    -Players may death-log, the on module's leave event can collect some information to sort this out.

    -Public CDKEY, account name, are useful to differenciate players... but both of them will return valid for all characters in your vault, if for example you have opened a personal portal (tagged "PORTAL_"+sCDKey;) with a level 40 for a special area, other players cannot use it but if you log a level 1 character he may use the portal.

    - If your server doesnt enforce legal character then anything the player adds in the override folder can be accepted by your server (class.2da modification for creating characters with 127 abilities or max skills etc)

    - Players may abuse the character description to prevent players (especially in PvP) from accessing easily the buffs and debuffs information that are found beneath the description.

    For multiplayer, I don't remember much more at this moment on top of my head, I will add to the list if I remember anything.



    other general tips... :

    A cell is 10.0f,
    Locations : x = left to right, y = bottom to top, z = height up and down
    I find it dangerous to use directly x,y,z vector, because of the rotate area capacity in the toolset. Instead I use empty object at the desired location and use its vector values. Unless I'm certain that I'll never modify area size / rotation.

    0 to 9 custom tokens are reserved


    ... hope this helps
    Post edited by badstrref on
Sign In or Register to comment.