You are here

Scripting Practices & Design (Tutorial)

Author: 
Genisys / Guile
Old Vault Category: 
other

Every NWN Scripter needs to learn the various ways to construct scripts, whether it's a void main or an include file, but there are some subjects that even experienced builders may not be aware of, and so today I'm going to be talking about Scripting Design & Practices, which will cover a whole range of topics, including some basics and even some advanced topics.  One of the best pieces of advice I learned from a veteran coder was, "Every great program ever designed required planning."

Some of you may be scratching your head and going huh?  As I was when I first heard it, because I thought back then, being new to coding, that it was really simple, and all you did was code, but man was I sure wrong about that.  The more things you want a system / program / or script to do, the more coding is required, and if you don't plan it well, then things can turn ugly fast, as you read more and more scripts you'll learn how some people build much differently than others.

Partly because you can see someone carefully planned how they were going to create their scripts, using certain naming conventions, certain functions (Especially switch / case statements), and it really shows in their code work, as it's very neat & tidy, to say the least.  Even if a function or script is scantly commented, it shouldn't be too hard to follow if they are tidy in spacing & layout, otherwise the code can become a pain to read / analyze.  All of which are basic scripting practices, but poor coders use variables off the top of their head, don't space or comment the scripts well, and this leads others to feeling annoying by reading their code work.

Standard code structure should include a title (always), list of authors, creation date, notes, comments, any required includes should be at the top (Under the before mentioned), declared prototypes and functions, main script, and then the definitions of functions at the very bottom, unless of course the main script is only used to run the functions which are customizable, as is the case in some template scripts (Like Tag Based Scripted Item Template Scripts etc).  Take a look at a quality script, so that you can see how it's properly done, and then take a look at a poorly structured script to see how it's NOT TO BE DONE!

You should notice that in the Template Teleport Script, the original coder used funny variable names like  i_oWP, which may sorta throw readers off, but as long as the main script is well commented and readable, this may be no big deal, and though I cleaned up the script some, it could have been much better!  Of course the party loot divider script (Though I purposefully made it horrible to show you an example of bad coding, it was one of my earliest creations.) is almost completely unreadable in many ways, unless of course you know what every symbol means, but it's still confusing because it was not properly planned out well.

Planning is everything when making scripts, first we need to write down what we want to accomplish, while we are brainstorming, because we might forget about some features we wanted to add, then we need to consider how it would be best to implement them, what functions we can create to reduce redundancy (& save for later use in other scripts), what includes may have functions that we can import into a main function script to run the main script (if it's going to be a large main script with multiple includes, it's best to write a new include).  What we don't want to do is have a main script that' small with a massive amount of includes attached to it to do only a few functions, this is just not very efficient.

I may be best to import functions rather than to write small scripts that include multiple includes, as it can start to really tax your RAM when you have massive little files running multiple includes, as I learned the hard way.    Therefore, as you are planning & designing scripts, keep this in mind, otherwise you may end up with a bloody headache & mess!

Another thing to be aware of is what I'd like to call "Theme Scripting", where includes should be grouped in relative functions, e.g. don't go putting inventory functions in a string script, this way you don't forget where functions are, and this is a very tidy way to keep track of what is in an include, so use proper naming conventions in scripts to let people know what's in the includes, e.g. gen_inv_inc / gen_pc_inc / gen_xp_inc / etc...  (Gen is the prefix I set on all of my scripts, so people know who built it & so I can keep all of my scripts together, this way when I import other builder's work I know which system I'm looking at), and this is a very important practice to entertain & use!

Beyond naming conventions & standard coding practices, planning can get complex, especially when designing a module, which in itself can be the equivalent of writing an entire program in itself!  Bare in mind that, even with all of the most careful of planning & careful coding, you are STILL going to run into bugs / issues, testing MUST remain a standard practice WHILE BUILDING, otherwise, you will get lost as to when you injected a bug / issue while coding.  Meaning don't write long sections of coding without testing, build / test as frequently as possible, because even the best coders make mistakes, I guarantee you, and I know some really great coders in this game!

When I write, I pick a topic and then start plugging away at it, I go back and spell check it after I post it (Just to show I'm human), and then I got back and patch it, to show that I'm still care about my work & those who read it.  If I did it the correct way, I would use an outline, just like when we are scripting, we should write it down and link includes so we know what we need to build, and more importantly why, but mainly so we don't forget later on!

I can tell you hear and now that I've scrapped more than one project because it was huge & I poorly planned it, midway I just threw up my hands and said, forget it! :D  I don't want you to be that person, really, it's very frustrating, time consuming, and if we can all just learn to use "best practices", we'd get a whole lot further faster! (With less pain headache medicine too! :)

Beyond the main scripts & includes, functions need to be well focused, not doing X things at once, we should break up functions within functions if they usable in other functions, this way we can reduce coding time, increase efficiency, and test things in peices, instead of "all at once".  Also, we need to make a list of functions that will be common in all of our scripts, then import those into a main include script, this way we have access to the common functions throughout our program for every script within our program / system.

Bioware did a marvellous job on this, if you take a look at the include "x2_inc_itemprop", this include was focused on functions that would be used for items, obviously it has a lot of usage throughout a lot of different scripts, and so this is considered a "main include" for many systems / programs that we will write while making them, so you should take a healthy look at this include and see how the professionals do it.

I say this because the best way to learn is to not only observe the pros, but immitate them, and it is by doing / getting involved that we learn best, for you can read 400 page books on coding and still be a novice, not having the experience you need, which takes time and a whole lot of practice & testing.  Mainly, though, it is the dogged determination to create from our inspirations that drive us to produce code work inside Neverwinter Nights, and we all love quality work, truly!

I liked that download because it truly is high quality work, you can see it was well planned out, and well executed, so if you want to learn some more advanced coding, then take a good look at the scripting involved there, and notice that I use some of my includes in A LOT of my other scripts, like gen_xp_inc / gen_colors_inc / etc.  I've done my best to produce high quality content for the community, though it's taken many years to develop my skills to a level that was more beneficial to everyone (including myself), so you too should expect to spend a long time if you want to become good, and look at it like a hobby, something you can put down and pick back up whenver you get the inspiration. ^.^

I'm going to leave you with this one age old advice: 

Be persistent. When knowledge and ability aren’t enough, be persistent.

Cheers, hope you enjoyed reading, & don't forget you can comment below!

 

Genisys / Guile

Migrate Wizard: 
First Release: 
  • up
    100%
  • down
    0%
Genisys

Did anyone enjoy the article?

 

Feel free to add any comments or "Constructive Criticisms" below...

  • up
    100%
  • down
    0%
Tarot Redhand

I'll read it when I get a chance. Currently got PC problems (as in essence complete rebuild). Also I intend to convert all your recent articles to both pdf and epub format whenever I can. Mainly for my own use. If you are so inclined I'll let you have copies that if you wish you can add to your articles as downloads. However, given my PC woes, don't hold your breath while waiting.

TR

  • up
    50%
  • down
    50%
Genisys

Someone is converting them to PDF this week btw...

(I'll try to spit a few more out soon)

  • up
    50%
  • down
    50%