General Tips and Tricks POL Development

Sometimes you need to share your knowledge. This is where you can do it. A place for POL and Script guides.
Post Reply
blckfire
Apprentice Poster
Posts: 54
Joined: Thu Feb 26, 2015 10:28 am

General Tips and Tricks POL Development

Post by blckfire »

Hi there! I'm blckfire and I've been developing code under a POL96 shard version. I also work as software developer/engineer.

These are just a collection of random tips and tricks I've gathered during these 2 years and how to improve testing and development time in POL.
  1. "If you need more than 3 levels of indentation, you're screwed anyway, and should fix your program.", as said by Linus Torvalds (Linux creator).

    Try to gather your exiting conditions in the beginning of your function to avoid "if" nesting.

    Code: Select all

    function GreetCustomer(customer)
    
    	if (customer.isA(POLCLASS_NPC))
    		return;
    	endif
    
    	if (customer.concealed)
    		return;
    	endif
    
    	if (!CheckLineOfSight(me, customer ))
    		return;
    	endif
    	
    	...
    
    endfunction
    
  2. Include files should not contain "use ..." or "include ..." lines (since they are not compiled) they should contain a comment that mentions all the uses and includes needed to compile that include file.

    Code: Select all

     /*
     *	File: includename.inc
     *
     * Version: 1.0
     *
     *	Description: General description of the includes content
     *
     *	Creator: Unknown
     *	Maintainer: blckfire
     *	Email: blckfire@gmail.com
     *
     * Dependencies: modules and includes the functions are dependent.
     * 					so that you include them in the script file that uses this include
     *
     *
     *
     *	Changelog:
     *	14/06/2015	- Some change
     *
     *
     *
     *
     *	Function List:
     *
     */
    
  3. Make sure to use Notepad++ as your software development tool it's free and it has tons of potential:
    - When you add NPP Exec extension you can use the following snippet to compile the script you're working on and get feedback inside Notepad++, thus gaining a lot of time.

    Code: Select all

    SET compiler = C:\POL\scripts\ecompile.exe
    NPP_SAVE
    cd C:\POL\
    "$(compiler)" "$(FULL_CURRENT_PATH)"
    UNSET compiler
    
    - Has an amazing search functionality allowing you to specify which kind of files you want to search a term for. Usually helpful when trying to access where a package/file/function is used across your server or when searching data files.

    Note: I can write a more detailed HOWTO on this matter if people are interested in taking full advantage of Notepad++
  4. Move your execution to another script file to ease your testing process, extremely useful while coding bits of code that normally would need a server restart. By moving the execution to another script your main script stays the same while your secondary script (which does all the work) can be unloaded and tested on the fly.

    Code: Select all

    function handle_request(event)
    	var character := event.source;
    	...	
    	var parms := array;
    	parms[1] := me;
    	parms[2] := character;
    	start_script(":package:npcs/scripts/workscript", parms);
    	
    	return;
    	
    endfunction
    
    This last one I'm not really sure if it affects performance but I find it makes it easy to write and test your code. I personally favor this method while coding NPCs and item interaction (there might be some other situations where it can be made useful).
Please don't take everything literally, these are just guidelines and tips and tricks I've been gathering for the past 2 years.
Skinny
Expert Poster
Posts: 76
Joined: Wed Dec 19, 2012 10:27 pm

Re: General Tips and Tricks POL Development

Post by Skinny »

blckfire wrote:[*]Make sure to use Notepad++ as your software development tool it's free and it has tons of potential:
- When you add NPP Exec extension you can use the following snippet to compile the script you're working on and get feedback inside Notepad++, thus gaining a lot of time.

Code: Select all

SET compiler = C:\POL\scripts\ecompile.exe
NPP_SAVE
cd C:\POL\
"$(compiler)" "$(FULL_CURRENT_PATH)"
UNSET compiler
Line 4, you can add the flag -Au:

Code: Select all

"$(compiler)" -Au "$(FULL_CURRENT_PATH)"
This way, the ecompile.exe only compile changed files rather than compile all files.
blckfire
Apprentice Poster
Posts: 54
Joined: Thu Feb 26, 2015 10:28 am

Re: General Tips and Tricks POL Development

Post by blckfire »

Skinny wrote:
blckfire wrote:[*]Make sure to use Notepad++ as your software development tool it's free and it has tons of potential:
- When you add NPP Exec extension you can use the following snippet to compile the script you're working on and get feedback inside Notepad++, thus gaining a lot of time.

Code: Select all

SET compiler = C:\POL\scripts\ecompile.exe
NPP_SAVE
cd C:\POL\
"$(compiler)" "$(FULL_CURRENT_PATH)"
UNSET compiler
Line 4, you can add the flag -Au:

Code: Select all

"$(compiler)" -Au "$(FULL_CURRENT_PATH)"
This way, the ecompile.exe only compile changed files rather than compile all files.
Actually FULL_CURRENT_PATH regards the file you are working on, so it'll only compile the one file. ;)
guialtran
Grandmaster Poster
Posts: 120
Joined: Wed Jul 30, 2008 12:42 pm

Re: General Tips and Tricks POL Development

Post by guialtran »

This can be downloaded inside the tool "tab plugins ".

NppExec = plugin for notepad++ "notepad-plus-plus.org"

To be able to compile the scripts using it.

https://sourceforge.net/p/npp-plugins/d ... /db04bd47/

1 install notepad++
2 go tab plugins install NppExec
3 restart program
4 tab plugins->NppExec ->Execute... (f6)
5 Command(s):
NPP_SAVE
"C:\UO\Pol\scripts\ecompile.exe" "$(FULL_CURRENT_PATH)"
6 save new name "pol0992016"
7 press ok

8 ctrl+F6 compile script =]

* Abilities:
* 1) Run multiple commands from the "Execute..." dialog
* 2) Run stand-alone command from the Console Dlg
* 3) Separate console for each NppExec.dll (e.g. NppExec1.dll, NppExec2.dll)
* 4) Additional commands:
* cls - clear Console screen
* cd - shows current path
* cd <path> - changes current directory (absolute or relative)
* cd <drive:\path> - changes current drive and directory
* dir - lists subdirs and files
* dir <mask> - lists subdirs and files matched the mask
* dir <path\mask> - lists subdirs and files matched the mask
* echo <text> - prints a text in the Console
* if <condition> goto <label> - jumps to the label if the condition is true
* goto <label> - jumps to the label
* set - shows all user's variables
* set <var> - shows the value of user's variable <var>
* set <var> = <value> - sets the value of user's variable <var>
* set <var> ~ <math expression> - calculates the math expression
* set <var> ~ strlen <string> - calculates the string length
* set <var> ~ strlenutf8 <string> - calculates the UTF-8 string length
* set <var> ~ strupper <string> - returns the string in upper case
* set <var> ~ strlower <string> - returns the string in lower case
* set <var> ~ substr <pos> <len> <string> - returns the substring
* set <var> ~ strfind <s> <t> - returns the first position of <t> in <s>
* set <var> ~ strrfind <s> <t> - returns the last position of <t> in <s>
* set <var> ~ strreplace <s> <t0> <t1> - replaces all <t0> with <t1>
* set local - shows all user's local variables
* set local <var> - shows the value of user's local variable <var>
* set local <var> = ... - sets the value of user's local variable <var>
* set local <var> ~ ... - calculates the value of user's local variable
* unset <var> - removes user's variable <var>
* unset local <var> - removes user's local variable <var>
* env_set <var> - shows the value of environment variable <var>
* env_set <var> = <value> - sets the value of environment variable <var>
* env_unset <var> - removes/restores the environment variable <var>
* inputbox "message" - shows InputBox, sets $(INPUT)
* inputbox "message" : initial_value - InputBox, sets $(INPUT)
* inputbox "message" : "value_name" : initial_value - InputBox customization
* con_colour <colours> - sets the Console's colours
* con_filter <filters> - enables/disables the Console's output filters
* con_loadfrom <file> - loads a file's content to the Console
* con_load <file> - see "con_loadfrom"
* con_saveto <file> - saves the Console's content to a file
* con_save - see "con_saveto"
* sel_loadfrom <file> - replace current selection with a file's content
* sel_load <file> - see "sel_loadfrom"
* sel_saveto <file> - save the selected text to a file
* sel_saveto <file> : <encoding> - save the selected text to a file
* sel_save <file> : <encoding> - see "sel_saveto"
* sel_settext <text> - replace current selection with the text specified
* sel_settext+ <text> - replace current selection with the text specified
* npp_exec <script> - execute commands from specified script
* npp_exec <file> - execute commands from specified file (*)
* npp_close - close current file in Notepad++
* npp_close <file> - close specified file opened in Notepad++ (*)
* npp_console <on/off/keep> - show/hide the Console window
* npp_console <enable/disable> - enable/disable output to the Console
* npp_console <1/0/?> - show/hide the Console window
* npp_console <+/-> - enable/disable output to the Console
* npp_menucommand <menu\item\name> - executes (invokes) a menu item
* npp_open <file> - open a file in Notepad++
* npp_open <mask> - open files matched the mask
* npp_open <path\mask> - open files matched the mask
* npp_run <command> - run external process/command
* npp_save - save current file in Notepad++
* npp_save <file> - save a file in Notepad++ (if it's opened) (*)
* npp_saveall - save all modified files
* npp_switch <file> - switch to specified opened file (*)
* npp_sendmsg <msg> - send a message (msg) to Notepad++
* npp_sendmsg <msg> <wparam> - message with parameter (wparam)
* npp_sendmsg <msg> <wparam> <lparam> - msg to Notepad++
* npp_sendmsgex <hwnd> <msg> <wparam> <lparam> - msg to hwnd
* sci_sendmsg <msg> - send a message (msg) to current Scintilla
* sci_sendmsg <msg> <wparam> - message with parameter (wparam)
* sci_sendmsg <msg> <wparam> <lparam> - msg to Scintilla
* npe_cmdalias - show all command aliases
* npe_cmdalias <alias> - shows the value of command alias
* npe_cmdalias <alias> = - removes the command alias
* npe_cmdalias <alias> = <command> - sets the command alias
* npe_console <options> - set/modify Console options/mode
* npe_debuglog <on/off> - enable/disable Debug Log
* npe_noemptyvars <1/0> - enable/disable replacement of empty vars
* (*) these commands work with a partial file path/name also
* i.e. npp_save c:\dir\f.txt is the same as npp_save f.txt
* 5) Additional console commands (Console Dlg only):
* help - show available commands
* ver - show plugin's version
* manual - show NppExec User Guide
* about - show NppExec Help/About
* CTRL+C - terminate current child process
* CTRL+BREAK - terminate current child process
* CTRL+Z - send ^Z to current child process
* 6) All Notepad++ environment variables are supported:
* $(FULL_CURRENT_PATH) : E:\my Web\main\welcome.html
* $(CURRENT_DIRECTORY) : E:\my Web\main
* $(FILE_NAME) : welcome.html
* $(NAME_PART) : welcome
* $(EXT_PART) : .html
* $(NPP_DIRECTORY) : the full path of notepad++'s directory
* $(CURRENT_WORD) : word(s) you selected in Notepad++
* $(CURRENT_LINE) : current line number
* $(CURRENT_COLUMN) : current column number
* 7) Additional environment variables:
* $(#0) : C:\Program Files\Notepad++\notepad++.exe
* $(#N), N=1,2,3... : full path of the Nth opened document
* $(LEFT_VIEW_FILE) : current file path-name in primary (left) view
* $(RIGHT_VIEW_FILE) : current file path-name in second (right) view
* $(PLUGINS_CONFIG_DIR) : full path of the plugins configuration directory
* $(CWD) : current working directory of NppExec (use "cd" to change it)
* $(ARGC) : number of arguments passed to the NPP_EXEC command
* $(ARGV) : all arguments passed to the NPP_EXEC command after the script name
* $(ARGV[0]) : script name - first parameter of the NPP_EXEC command
* $(ARGV[N]) : Nth argument (N=1,2,3...)
* $(RARGV) : all arguments in reverse order (except the script name)
* $(RARGV[N]) : Nth argument in reverse order (N=1,2,3...)
* $(INPUT) : this value is set by the 'inputbox' command
* $(INPUT[N]) : Nth field of the $(INPUT) value (N=1,2,3...)
* $(OUTPUT) : this value can be set by the child process, see npe_console v+
* $(OUTPUT1) : first line in $(OUTPUT)
* $(OUTPUTL) : last line in $(OUTPUT)
* $(EXITCODE) : exit code of the last executed child process
* $(MSG_RESULT) : result of 'npp_sendmsg[ex]' or 'sci_sendmsg'
* $(MSG_WPARAM) : wParam (output) of 'npp_sendmsg[ex]' or 'sci_sendmsg'
* $(MSG_LPARAM) : lParam (output) of 'npp_sendmsg[ex]' or 'sci_sendmsg'
* $(SYS.<var>) : system's environment variable, e.g. $(SYS.PATH)
*
****************************************************************************
Last edited by guialtran on Sun Jan 08, 2017 2:02 pm, edited 2 times in total.
Nando
POL Developer
Posts: 282
Joined: Wed Sep 17, 2008 6:53 pm
Contact:

Re: General Tips and Tricks POL Development

Post by Nando »

Very nice tips, thanks for posting them! guialtran, could you edit your post to explain what is that list of commands/options? I guess it's related to Notepad++, but it may not be so clear to others. :)
xeon
Forum Regular
Posts: 338
Joined: Fri Oct 31, 2008 3:18 am
Location: Italy

Re: General Tips and Tricks POL Development

Post by xeon »

Yes good post, I've too many things that I could post from our experience on ZHI

I personally don't agree with number 2
Include files should not contain "use ..." or "include ..." lines (since they are not compiled) they should contain a comment that mentions all the uses and includes needed to compile that include file.
To me, when I include an include file, I expect it to provide everything it need to make work its functions. So I use include and use declaration inside the lib. Otherwise you've to put them in every script, wasting time
guialtran
Grandmaster Poster
Posts: 120
Joined: Wed Jul 30, 2008 12:42 pm

Re: General Tips and Tricks POL Development

Post by guialtran »

I'm trying to modify 1 xml specific notepad ++ to be able to autocomplete all functions XXX (a, b, c) and properties .XXX, .XXX (abc)
guialtran
Grandmaster Poster
Posts: 120
Joined: Wed Jul 30, 2008 12:42 pm

Re: General Tips and Tricks POL Development

Post by guialtran »

If I can finish this, I'll give this file to everyone.
Attachments
Captura de tela 2017-01-12 14.36.36.png
Captura de tela 2017-01-12 14.37.29.png
blckfire
Apprentice Poster
Posts: 54
Joined: Thu Feb 26, 2015 10:28 am

Re: General Tips and Tricks POL Development

Post by blckfire »

xeon wrote:Yes good post, I've too many things that I could post from our experience on ZHI

I personally don't agree with number 2
Include files should not contain "use ..." or "include ..." lines (since they are not compiled) they should contain a comment that mentions all the uses and includes needed to compile that include file.
To me, when I include an include file, I expect it to provide everything it need to make work its functions. So I use include and use declaration inside the lib. Otherwise you've to put them in every script, wasting time
I don't see why I would include an include file in another include file, because if I need to include this file I'll just set it up in the .src file I'm going to use it with the other include file, that's why I also posted the code snippets with the comments, to make your life easy, you just need to copy paste what's in there to the script where you gonna put your include file. It also prevents that you have several scripts that are including the same stuff. If you do it this way everything is done one time in the .src file.

I don't know if this has an effect on script performance, but, if I was to guess I would have to say yes.
blckfire
Apprentice Poster
Posts: 54
Joined: Thu Feb 26, 2015 10:28 am

Re: General Tips and Tricks POL Development

Post by blckfire »

guialtran wrote:If I can finish this, I'll give this file to everyone.
I'd use it gladly! Improved quality of life, that's for sure.
guialtran
Grandmaster Poster
Posts: 120
Joined: Wed Jul 30, 2008 12:42 pm

Re: General Tips and Tricks POL Development

Post by guialtran »

Takes a long time. :deadhorse:
Attachments
Captura de tela 2017-01-13 13.10.40.png
DaleYan
New User
Posts: 1
Joined: Wed Sep 27, 2017 7:56 am

Re: General Tips and Tricks POL Development

Post by DaleYan »

blckfire wrote: Thu Jan 12, 2017 12:26 pm
guialtran wrote:If I can finish this, I'll give this file to everyone.
I'd use Quick Extender Pro all the time gladly! Improved quality of life, that's for sure.
Thanks everyone for sharing. Great stuff!
Last edited by DaleYan on Wed Nov 10, 2021 4:51 am, edited 2 times in total.
Yukiko
Distro Developer
Posts: 2825
Joined: Thu Feb 02, 2006 1:41 pm
Location: San Antonio, Texas
Contact:

Re: General Tips and Tricks POL Development

Post by Yukiko »

Include files should not contain "use ..." or "include ..." lines (since they are not compiled) they should contain a comment that mentions all the uses and includes needed to compile that include file.
I missed this when I read the original post.

I think you are incorrect about include files "not being compiled". Some part of the code in the include file gets "included" in the referring script. Maybe not the whole include file but at least the functions being used.

You are correct about the modules in "use" statements. They are directives to the compiler (and probably POL) to 'use' the functions already present in POL. This is different than include files because the functions referenced in modules already exist in the Core whereas those called in include files are code that does get executed. Just compare the uo.em file with an include file. You will see that uo.em merely defines the constants and functions but an include file actually has eScript code in it.

I would like a Core developer to comment and correct me if I am incorrect and also if include code is added to a script is it the entire include file's code or just those functions used.
Turley
POL Developer
Posts: 670
Joined: Sun Feb 05, 2006 4:45 am

Re: General Tips and Tricks POL Development

Post by Turley »

Since yukiko asks so nice I will write a bit about it :)
I also do not get the second point about not including in an include.
It makes in my opinion no sense to force the user of your interface to know your internal dependencies (in any language). If I want to eg kill a character which is defined as function in "vitals.inc" I don't care that it depends on cmdlevels which are defined in "cmdlevels.inc" and sends a custom packet which of cause is defined in "packets.inc".
And of cause the core has no clue and does not care if you used includes or not. The only one who cares about is is ecompile.
Ecompile removes unused functions before generating the ecl.
The compiler also checks the filemodification timestamp for all dependent files in the case you don't want to compile always everything. (-u -D flag combination)

And for the people who want proves just compile with -l which outputs the content of the ecl in the way the core executes it in readable format and -xt which generates an overview of the content of the ecl.
Turley
POL Developer
Posts: 670
Joined: Sun Feb 05, 2006 4:45 am

Re: General Tips and Tricks POL Development

Post by Turley »

Forget to mention "use":
The only special meaning which exists is the npc.em. you can only have them in AI scripts, the remaining are just for grouping the functions. So I see also no reason to not have them in include files. It makes no difference where they are.
Yukiko
Distro Developer
Posts: 2825
Joined: Thu Feb 02, 2006 1:41 pm
Location: San Antonio, Texas
Contact:

Re: General Tips and Tricks POL Development

Post by Yukiko »

Thank you Turley for the information about 'include' files. I have wondered if the whole include file was added to the ecl or just the functions used in the include. I could have checked easily enough but never did. I'm glad I was close with the 'use' statement. Maybe I will post your longer explanation from the Discord channel. :)
Post Reply