Scripting "Standards"

Discussions of the design and development of in-game content.

Moderator: Team Members

Post Reply
User avatar
John Adams
Retired
Posts: 9684
Joined: Thu Jul 26, 2007 6:27 am
EQ2Emu Server: EQ2Emulator Test Center
Characters: John
Location: Arizona
Contact:

Scripting "Standards"

Post by John Adams » Tue Sep 16, 2008 11:27 am

Yes, I have too much time on my hands.

Now that we've tackled many different types of scripting, I think we can come up with some standards as far as formatting, naming, etc, that our teams will follow to remain consistent. Naturally, individual admins can do whatever they want - so for you, these are just suggestions for consistent script authoring. Input is welcome.


Naming:

CaSe-SeNsItIvItY!:
  • EVERY LETTER AND SPACE MUST MATCH! If you insert a new quest in the database "My Quest.lua", you MUST name the script in the quest folder "My Quest.lua"... it cannot be "my quest.lua" or any other variation. Case sensitive OS's and Database instances will have a cow trying to find things where case (among other things) do not match. BE CONSISTENT.
SpawnScripts:
  • To coin the term "CamelCasing", I believe this is the clearest, cleanest way to present our SpawnScripts by name. That is to say, every individual word in the script name have an upper-case letter as it's first letter, followed by lower-case.

    Examples:
    CaptainVarlos.lua
    DockmasterWilson.lua

    Names that have non-alpha/numeric characters should drop the character and stick to the CamelCase concept.

    Example:
    TayilNVelex.lua (formerly Tayil N'Velex)
Quest Scripts:
  • They should be named slightly different in that they are not simple NPC/Object names, but phrases. In order to keep these identifiable and not clutter them with CamelCasing (APresenceOfEvil.lua looks kinda crowded), we should name Quests differently.

    Example:
    a_presence_of_evil.lua
Spell Scripts
  • They are assigned PER SPELL. Meaning, every single spell has it's own script, aptly named. They are stored in the Spells\{archetype}\{class}\{subclass} structure.

    Spells that all archetypes can use should be in their archetype folder, and same with class (though I am not 100% sure SOE does this anymore)

    Examples:
    Guardian's Overpower spell: Spells\Fighter\Warrior\Guardian\Overpower.lua
    Fighter\FightingChance.lua - all 6 fighters will get this
    Fighter\Crusaders\BlessedWeapon.lua - both crusader subclasses will get this
Item Scripts
  • These are assigned PER ITEM, and they all live in a single folder called ItemScripts. These are usually clickable items, or items with a proc that need some form of action taken when using them (actions not related to Questing). The naming format is similar to SpawnScripts in the camel-case, and the name of the Item Script is usually the item, or it's purpose, or a combination of both.

    Example:
    ItemScripts/MakeshiftBarricade.lua - this is the quest in Frostfang (Boatload of Work) where you "use" the item given to you by Yasha and it places an object in the zone, completing the quest step.
Zone Scripts
  • These are assigned PER ZONE, and are used for global actions that occur inside a given zone. They are stored in the ZoneScripts folder, and are named after the zone "short name" (FrostfangSea, not Frostfang Sea). A major function of a ZoneScript is the SetLocationProximityFunction() call for things like discovery locations or causing an event to occur at a specific x,y,z radius.

    Example:
    ZoneScripts/FrostfangSea.lua - Using the BoatloadWork example above, when the player enters a specific set of coordinates, a popup message will appear in their client telling them they have arrived at the proper place to set the barricade.

    Note also, they can be used in conjunction with other script types as well, like following an NPC around and certain events occur when you reach coordinates, or using an Item or Spell/Ability.

Folder Structures:
Now that we can preserve folder names in our scripts configurations, I feel it is imperative to start organizing these scripts into a logical structure. One suggestion I have is that we put scripts that are specific to a zone into a folder named after the zone itself.

Example: SpawnScripts for QueensColony -
"SpawnScripts/QueensColony/CaptainVarlos.lua"

Example: Quest scripts for QueensColony -
"Quests/QueensColony/a_presence_of_evil.lua"

That looks like a lot of text, and it is... but I feel, in the long run, it will help isolate troublesome scripts and make for a cleaner-looking EQ2Emu package. Appearances are everything, after all. ;)


Architecture:
Logical layout of our scripts is critical for both aesthetics and troubleshooting. If you have functions that follow no particular order, the troubleshooter will have a hard time trying to follow the flow of the script. One suggestion is to follow the logical flow of the spawn as it appears in the zone.

function spawn(NPC) - should be first, so when the NPC spawns, this is the first thing that gets executed.

function respawn(NPC) - Again, having to do with spawns arrival in zone

function hailed(NPC)

function attacked(NPC)

function {Quest_Related_Functions} - Interaction functions can start here.

Functions related to conversations or quests should follow a top-down order if possible. Meaning, as you progress through the conversation, have the next function for the conversation right after the current function:
function hailed(NPC)
-- call function Greeting
-- call function Goodbye
end

function Greeting()
end

function Goodbye()
end
Sometimes it is necessary to leap back and forth if the responses later are the same as the previous, but wherever possible, flow top-down.


Indents:
Everyone has a different way to lay out their code. Some use indent 2 spaces, some 3, some a tab. Let's find a common indentation and stick to it. I suggest a 4-space indent is adequate, especially since my editor currently does not handle tabs quite well :)

Write all scripts in any LUA editor you wish, (vi, Notepad++, Jabantiz's LUA Editor, etc just no RTF-formatting! Plain Text!) then paste the results into the web-based DB Editor and save.


Comments:
Doing something fancy that doesn't appear to make sense? Comments, comments, comments! LUA Script has two ways of making comments:
-- this is a comment, single line.
--[[
this is
a multi-line
comment
--]]

Script Header: IMPORTANT!
While everything I have suggested above is optional but wishful... one thing I must insist on is Script Header. The Content Team has adopted the following as an exceptional script header we would like to see in ALL our "official" scripts. If you are writing quests for the EQ2Emulator project, please follow at least this formatting suggestion.
Note: Being "lazy" or feeling you are "above it" and putting no header and your script
will be rejected and deleted from SVN. This is not negotiable.

For SpawnScripts (conversations, movement, etc):

Code: Select all

--[[
	Script Name     : <script-name>
	Script Author   : <author-name>
	Script Date     : <date>
	Script Notes    : <special-instructions>
	Script Purpose  : <purpose>
--]]
(Notes/Purpose optional)


For Quests scripts:

Code: Select all

--[[
	Script Name     : <script-name>
	Script Purpose  : <purpose>
	Script Author   : <author-name>
	Script Date     : <date>

	Script Notes    : <special-instructions>
        Zone            : <zone-name>
        Quest Giver     : <NPC-name>
        Preceded by     : <preceding-quest-name>
        Followed by     : <quest-to-follow>
--]]
Note: Not all of that is mandatory, but at least providing some info on what this quest is tied to will help in chasing down potential problems, or give the quest authors/editors a clearer view of what is going on.


For Spells scripts:

Code: Select all

--[[
	Script Name     : <script-path>
	Script Author   : <author-name>
	Script Date     : <date>
	Script Purpose  : <purpose>
	Script Notes    : <special-instructions>
--]]

ItemScripts:

Code: Select all

--[[
	Script Name    : <script-path>
	Script Purpose : <purpose>
	Script Author  : <author-name>
	Script Date    : <date>
	Script Notes   : <special-instructions>
--]]

ZoneScripts:

Code: Select all

--[[
	Script Name    : <script-path>
	Script Purpose : <purpose>
	Script Author  : <author-name>
	Script Date    : <date>
	Script Notes   : <special-instructions>
--]]

id variables: IMPORTANT!
Using variables for ids will make updating any changes to spawns, items, etc ids in the future easier to update in scripts.
Examples:

Code: Select all

local TaskAboardTheFarJourney = 524
This is for the quest Task Aboard The Far Journey. The current Id is 524. Now you can use the variable TaskAboardTheFarJourney in place of the id in the script like this.

Code: Select all

if not HasQuest(Spawn, TaskAboardTheFarJourney)
Doing this means that the id will only need to be changed in one location vs hunting through the scripts to replace all instances of the id placement. Also, it will make the code easier to read further down the line. Task Aboard The Far Journey is a lot easier to understand than 524.


Using DialogModule
More scripts are starting to use the dialog module and it is worth it to read through the topic and understand how it works.


Understand that these "Standards" are here for a purpose; to keep things clearly identifiable and organized because we're still at the beginning of a very long road, and we do not need to spend hours troubleshooting or trying to figure out what some long-gone Content Designer had in mind when writing their scripts.


Edit: JA 2009.03.27 - added Case Sensitivity standard
Edit: JA 2013.11.22 - updated to current standards and practices
John Adams
EQ2Emulator - Project Ghost
"Everything should work now, except the stuff that doesn't" ~Xinux

User avatar
Arremis
Retired
Posts: 388
Joined: Sun Sep 02, 2007 10:11 am
Location: Memphis, TN

Post by Arremis » Tue Sep 16, 2008 1:49 pm

I agree we do need a standard for official scripts. Good one, John :)
I am the UI Master...there is no charge for my awesomeness.

User avatar
Xanibunib
Retired
Posts: 121
Joined: Thu Mar 06, 2008 11:01 pm
EQ2Emu Server: RENS
Location: Colorado

Re: Scripting "Standards"

Post by Xanibunib » Thu Mar 12, 2009 4:37 pm

As standardized scripting header sounds like a great idea, as well as a standard directory structure. I can see this getting very very messy if we don't have a way of keeping this all in line... As for the quests, I have been setting my directories up like your example...

"ZoneName/NPCName/QuestName.Lua"

I know this is thinking way ahead here but what happens when we get into instances? Maybe even instances of the same zone but with different NPCs in them depending on what flags your character has...
Village idiot...

User avatar
John Adams
Retired
Posts: 9684
Joined: Thu Jul 26, 2007 6:27 am
EQ2Emu Server: EQ2Emulator Test Center
Characters: John
Location: Arizona
Contact:

Re: Scripting "Standards"

Post by John Adams » Thu Mar 12, 2009 6:28 pm

Xanibunib wrote:"ZoneName/NPCName/QuestName.Lua"
I actually see no need for a NPCName on the Quest path. How many quests can there possibly be for 1 NPC? Then you have hundreds of folders with 1 file in them.

Plus, it's a little late to change 100's of scripts already set in place. Unless this is something Scatman wants us to change, I say nix that idea, go with what we have now. ZoneName/quest_full_name.lua

User avatar
Scatman
Retired
Posts: 1688
Joined: Wed Apr 16, 2008 5:44 am
EQ2Emu Server: Scatman's Word
Characters: Scatman
Location: New Jersey

Re: Scripting "Standards"

Post by Scatman » Thu Mar 12, 2009 6:30 pm

The spawns will have a script set to them whether they are spawned or not. However, whether the spawn actually get spawned will be dependent upon the character flags. I think that's what you were asking?

User avatar
Xanibunib
Retired
Posts: 121
Joined: Thu Mar 06, 2008 11:01 pm
EQ2Emu Server: RENS
Location: Colorado

Re: Scripting "Standards"

Post by Xanibunib » Thu Mar 12, 2009 8:20 pm

True some NPC do only have one quest on them... I can see adding the NPC name wouldn't be a great idea. For instance the Heritage quest in Zek for the SBS. Depending on what part of the quest your on different mobs spawn in the cave at the bottom of the mine.
Village idiot...

User avatar
Xanibunib
Retired
Posts: 121
Joined: Thu Mar 06, 2008 11:01 pm
EQ2Emu Server: RENS
Location: Colorado

Re: Scripting "Standards"

Post by Xanibunib » Fri Mar 13, 2009 2:22 am

Another thing that comes to mind when lookin at quest script headers is it may be a good idea to add in the questID # as well?

Code: Select all

	
[[--
   Quest Template
	Script Name	: A_Puppy_for_your_Potion.lua
	Script Purpose	: Handles the quest, "A Puppy for Your Potion"
	Script Author	: Xanibunib	
	Script Date	: 2009.03.13

        Zone            : The Scale Yard
        Quest Giver     : Brood Matron Vrim Malthyk
        QuestID #	    : 100
        Preceded by     : None
        Followed by     : He Said, he said (He_said_he_said.lua)
--]]
Village idiot...

User avatar
Scatman
Retired
Posts: 1688
Joined: Wed Apr 16, 2008 5:44 am
EQ2Emu Server: Scatman's Word
Characters: Scatman
Location: New Jersey

Re: Scripting "Standards"

Post by Scatman » Fri Mar 13, 2009 10:04 am

Wouldn't be a bad idea :)

User avatar
John Adams
Retired
Posts: 9684
Joined: Thu Jul 26, 2007 6:27 am
EQ2Emu Server: EQ2Emulator Test Center
Characters: John
Location: Arizona
Contact:

Re: Scripting "Standards"

Post by John Adams » Fri Mar 13, 2009 11:40 am

What is the chance of using the same Script for different NPCs? Al la the Tradeskill tutorials. Each one seems to do the same thing, so having a single script for each would be redundant.

And if the answer is "return to NPC ID", then there is yet another argument why this data should be in the DB and not LUA.

User avatar
Scatman
Retired
Posts: 1688
Joined: Wed Apr 16, 2008 5:44 am
EQ2Emu Server: Scatman's Word
Characters: Scatman
Location: New Jersey

Re: Scripting "Standards"

Post by Scatman » Fri Mar 13, 2009 11:46 am

The answer is "return to NPC ID" :) But it wouldn't be hard to write the quest to only suite one npc.

if GetSpawnID(NPC) == the_one_in_graystone
-- add a quest step chat with this one's id
else GetSpawnID(NPC) == the_one_in_baubbleshire
-- add a quest step chat for this one's id

or were you talking about something different?

User avatar
John Adams
Retired
Posts: 9684
Joined: Thu Jul 26, 2007 6:27 am
EQ2Emu Server: EQ2Emulator Test Center
Characters: John
Location: Arizona
Contact:

Re: Scripting "Standards"

Post by John Adams » Fri Mar 13, 2009 12:00 pm

No that's it I think. I don't care if we add Quest ID to the header. It is a good idea...

User avatar
John Adams
Retired
Posts: 9684
Joined: Thu Jul 26, 2007 6:27 am
EQ2Emu Server: EQ2Emulator Test Center
Characters: John
Location: Arizona
Contact:

Re: Scripting "Standards"

Post by John Adams » Sat Mar 28, 2009 1:22 am

A new issue just came up that I am adding to our "Scripting Standards" list. CASE-SENSITIVITY must always be considered. Your LUA script names need to match the exact same name, case and all, that you named in the database. Certain OS's and Database configs are very picky about this (just spent an hour tracking something down that was a single upper-case letter that shouldn't have been)

Wild_Times_On_Norrath.lua is NOT the same as wild_times_on_norrath.lua.

Be mindful when naming your scripts, since NPCs names are used in our SpawnScripts, try not manually typing them. The editor does a very nice job ~ahem~ of "guessing" for you. If it does not, I need to know about it so I can fix it.

Please review the Standards above (again) for how the different types of scripts are to be named. This is for consistency, not to make your lives hard. ;)

User avatar
John Adams
Retired
Posts: 9684
Joined: Thu Jul 26, 2007 6:27 am
EQ2Emu Server: EQ2Emulator Test Center
Characters: John
Location: Arizona
Contact:

Re: Scripting "Standards"

Post by John Adams » Sat Nov 23, 2013 11:04 am

With more people poking their head up and offering to do LUA I thought I'd freshen this Standards post a little.

While mostly just a "Guideline", understand that standardizing how we do things only helps us all in the long run... this ain't just some JA OCD happy farm :)

User avatar
Cynnar
Project Leader
Posts: 738
Joined: Sat Sep 27, 2014 1:22 am
EQ2Emu Server: Eq2emulator
Characters: Vlash
Veinlash
Taragak
Cynnar

Re: Scripting "Standards"

Post by Cynnar » Sat Aug 20, 2022 10:42 am

Updated post to include using variables for ids and linking to dialog module.
[ 01000011 01111001 01101110 01101110 01100001 01110010 ]

Follow on:
Twitter Facebook

Contact me:
PM Discord chat email

Hardware: the parts of a computer that can be kicked

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest