Scripting Tutorials & Guides

GmOcean

Community Contributors
Messages
371
Points
0
Emulator
Scripting Tutorials and Guides

I'm going to attempt to help everyone here with their scripts while not being directly involved in helping you with them xD.
This will also help future/current scripters get some fresh info and maybe inspire innovative ideas towards scripting.
So that we can prove that us " Scripters " are the superior ragnarok emulation race! Take that Source Code writers!! Jk lol, we need you too
default_biggrin.png
.

What I'm going to do, is write detailed tutorials on how to write a few scripts. Starting from the basics to more advanced scripts.
This way everyone can follow along. And hopefully this will help everyone understand how to write a few scripts and even troubleshoot their own scripts.

Also please read: Scripting Standards.

It will help you understand how to read some of the syntax and way people script things.

// A list of <sprite id>s can be found here: Sprite_IDs Credits: Ai4rei

Scripting Tutorials & Guides

In this section you will learn how to write scripts ranging from Complete Begginer Level Scripts ( Me and Some of you ) -> Expert Level Scripts ( Think, Developer Status O.o; )

- Beginner Scripts -

Scripts for complete beginners and novice scripters.

Basic Healer & Buffer Script ( 5 Parts )

A Basic Healer Script. Here we will cover most, if not all of the basics of scripting.

Basic Item Trader Script ( 2 Parts )

A basic item trader script. Here we will learn how to give players an item in exchange for other items.

Basic Floating Rates Script - Complete ( 2 Parts )

Here we will create a " floating " npc. And have it adjust base & job experience rates.

Basic Player vs Player Script - Complete ( 1 Part )

A Player vs Player script to introduce you to the basics needed to make them work.




- Intermediate Scripts -

Scripts for intermediate level scripters. If you completed my beginner script series, then you are ready for this section.

Intermediate Healer & Buffer Script - Complete ( 2 Parts )

An Intermediate version of the Basic Healer & Buffer script.

Custom AtCommand @buff - Complete ( 2 Parts )

A custom @command, that will buff the player with preset buffs, have a cast time, cost zeny, have a cooldown time, and will unlock more buffs the more they use it !!

Bounty Hunting PvP Script - Complete ( 2 Parts )

An intermediate level PvP script. This script is intended to help improve your scripting abilities, while also making you feel more comfortable about PvP scripts.




- Advanced Scripts -

Scripts for advanced level scripters. If you completed my intermediate script series and have made a few of your own intermediate scripts, then you are ready for this section.





The idea behind this topic, is for new users, and current ones, to have a (second)place they can go to for reference when trying to write a script if they can't figure it out with script_commands.txt file. It will also help people learn how to write scripts. While hopefully, keeping script writing techniques to a ' very ' similar structure!

*Read Me* - I have updated the links on this post to link to the oldboard so these guides can be viewed. However, do note that the script_commands.txt links within those guides are no longer accurate. Enjoy your scripting.

 
Last edited by a moderator:
O.o I didn't know that menu was being removed lmao. In that case I'll switch it around to select. Even though I like using menu in some cases =p

 
pls don't teach them to use "menu" =P

ref: https://github.com/HerculesWS/Hercules/pull/374
This might be problematic when using menu to manipulate array indexes D:

Example:

Code:
	mes .npc_name$;	mes "Hello there, mighty warrior!";	mes "Which arena would you like to test your strength in?";	next;		// Build list of arena names	for (.@i = 0; .@i < getarraysize(.arena_data$); .@i += 4) {		.@arena_name$[.@j++] = .arena_data$[.@i];		.@mode$[.@k++] = .arena_data$[.@i] +" ["+ getmapusers(.arena_data$[.@i + 1]) +"]";	}		// Select desired arena	menu implode(.@mode$, ":"), -;	mes .npc_name$;	.@key = @menu - 1;	// Hercules	//.@key = @menu - 2;		// rAmod	.@index = .@key * 4;		// Determine map name	.@map_name$ = .arena_data$[.@index + 1];		// Determine Base Level requirement	.@base_req = atoi(.arena_data$[.@index + 2]);		// Determine room limit	.@room_limit = atoi(.arena_data$[.@index + 3]);
*I'm also extremely rusty on scripting so maybe there's a better method by now lul

 
Last edited by a moderator:
I like using menu when I have few option that all lead to same result. switch(select) + default seems like a bit too much for such an easy task
default_tongue.png


Anyways, nice one. I believe there was also a somewhat guide on scripting rules as in use of intendation/naming scheme and all that. Might help make scripts cleaner and easier to read for everyone if you'll link it somewhere.

 
Mumbles: see my reply in the pull request. It actually becomes easier with .@select, as you don't even need to use the @menu variable.

Garr: but using labels is even worse than using a switch, and makes the script less readable. If several options lead to the same result, their case labels in the switch can be grouped together without break in between, if you don't wish to use select. Or, nobody forces you to use a switch, and you can use if/else conditions if you prefer.

switch (select("a:b:c:d:e")) {case 1:case 2:case 4: mes "a, b and d lead here."; break;case 3: mes "this is c."; break;}// and e does nothing
Or

Code:
.@choice = select("a:b:c:d:e"));if (.@choice == 3) {    mes "this is c.";} else if (.@choice < 5) {    mes "a, b and d lead here.";}// and e does nothing
 
First script in the beginner series is complete.

Next I'll be moving on to a basic item trader script, that gives players one item in exchange for other items.

If you found this helpful to you let me know, if it wasn't, still let me know lol.

 
GmOcean, good job there! Can I ask you to edit a little something, so that people will script according to the scripting style standards we're setting? (see working draft at http://herc.ws/board/topic/5062-scripting-standards/ )

Setting variables should always happen through direct assignment and without the use of the 'set' command, where possible. So, instead of set Zeny, Zeny - 1000, it should be Zeny -= 1000; instead of set .heal_price, 1000, it should be .heal_price = 1000; and so on.

Some parts of the scripting standards are still being changed, so don't take everything you see there as set in stone, but the part about using 'set' to manipulate variables already is.

Thank you!

 
I am definitely going to be setting variables like that in the future, starting with my next script tutorial. I just feel that using " set " as a corner stone for scripting is almost a necessity for helping people understand the process of how to set a variable. This will also help make the shift to the new standard easier imo. It's just that's how I learned, so I figured it'd be easier to teach if they go through the same process.

But thank you for letting me know. I guess i'm using a mix of Kernel and K&R style @.@; How mixed I must be lol.

 
We'll be updating the guidelines and including them in the doc folder of the repository soon, to give them more visibility.

About the use of set, the reason why I recommend against using it at all (other than it being deprecated) is that by using direct assignment, the language is probably easier for newcomers. If they ever used any other scripting or programming language (and chance is they did at school, perhaps), they'll be probably used to direct assignment rather than a command to set variables. This way they won't have to learn a new (arguably useless) thing such as using 'set'.

 
Hmm, that does make sense. Alright, since there really is no down side to changing it, I'll go ahead and make those changes D:.

 
Just 3 things for now to say

1) Encourage constants to be used (making it easy to read, like sprite 936, i would have no idea what it is, but replacing 936 by 4_F_ARUNA_POP would give me idea about what sprite that is and so same applies to monster and item constants to be used (for future tuts))

2) make if condition more readable if you want to use it.

ex, instead of

if( Zeny < 1000 && @menu == 1 || Zeny < 5000 && @menu == 2 ) {

Have

if( (Zeny < 1000 && @menu == 1) || (Zeny < 5000 && @menu == 2) ) {

This make clear about what condition is.

3) Direction constants

DIR_NORTH 0

DIR_NORTHWEST 1

DIR_WEST 2

DIR_SOUTHWEST 3

DIR_SOUTH 4

DIR_SOUTHEAST 5

DIR_EAST 6

DIR_NORTHEAST 7

 
Last edited by a moderator:
@Dastgir - Noted and changed. I'll try to do that from now on lol. Constants for items, are kind of new for me, because I don't think rAthena has them, and I've only recently made the switch to Herc.

Edit: Okay, figured out how item constants are listed =P. I'll make sure to use them from now on, atleast in my tuts lol. No promises for script releases
default_ho.gif
Also, for some reason, my scripts won't load when using Direction Constants in a script header :/

Edit:

@Haru - Alright, well. For now I'll leave it as numbers, since that's what's working. And I'll change it to the constants once it's been implemented.

 
Last edited by a moderator:
That's right, we unfortunately still don't support the direction constants in script headers, but only in commands (i.e. movenpc) x.x

I guess that would make for a nice pull request, if anyone feels like to implement it before we do

 
This would be awesome if people who knows how to script can collaborate with GmOcean to make this topic as good as possible.
default_tongue.png


This topic should be pinned in my opinion

 
Last edited by a moderator:
Update!

Finished Basic Item Trader with 2 parts ( for lack of other things to add to it D: ).

Created & Finished Basic Floating Rates NPC with 2 parts.

Edit:

Going to start intermediate scripts next, anyone got any idea's for one? If not I'll just throw in a more detailed and modified version of the Healer & Buffer script.

 
Last edited by a moderator:
Update!

Finished Advanced Healer & Buffer.

Going to take a small break from updating this as I plan out the next script to write a tutorial for, as well as to give me time to other tasks I'm currently falling behind on.

 
1)

.buff_price = atoi(""+ ( .include_buffs?"0":"5000" ) +""); 
Why not have it something like

.buff_price = ((.include_buffs)?0:5000);
2)

switch( select("Yes, heal me.", ""+ ( .include_buffs?"::":"I want buffs" ) +"", "No thank you") ) { 
TO

switch( select("Yes, heal me.", ( .include_buffs?"":"I want buffs" ), "No thank you") ) {
you don't require those ""+, you can directly start with those conditions.

Else everything seems fine, keep updating the guide.
default_biggrin.png


 
Last edited by a moderator:
Back
Top