From The Mana World
(Narrow down scope a bit; rewrote punctuation)
m (→‎eAthena: Some quick thoughts)
 
(2 intermediate revisions by the same user not shown)
Line 1: Line 1:
This is a proposal-in-making on standardizing both eAthena and TMWserv scripting. Any suggestions are welcome to be posted on the discussion page.
In my mind a scripting language should be simple to both understand and use. You should not need to be a C++/Lua hacker to be able to create a dialogue menu where some replies depends on certain circumstances. Here follows a few suggestions how the tmwserv Lua scripting could look.


== Typographical style ==
== Example script ==
There exist various schools on typographical conventions, and most of them vary depending on situation. The following are recommendations for writing scripts in the Mana World. Examples for both [[eAthena Scripting Standards|eAthena]] and [[scripting|TMWserv]] will follow alongside each other. These style recommendations should of course be adjusted to the language in question when doing [[translations]].
In current eAthena and tmwserv script as well as a proposal of a more scripter comfortable tmwserv syntax.


=== Punctuation ===
=== eAthena ===
# Ending a sentence:
#* Use multiple punctuation marks sparingly.
#* Refrain from separating sentences with two or more spaces.
# Something cut off or missing:
#* Use an [http://en.wikipedia.org/wiki/Ellipsis ellipsis] (…) for something missing. (Replace with three dots, ..., in eAthena scripting.)
#* Use an [http://en.wikipedia.org/wiki/Dash#Em_dash em dash] (—) for something cut off. (Replace with two normal dashes in eAthena scripting.)
# Offsetting text parenthetically:
#* Use the [http://en.wikipedia.org/wiki/Dash#Em_dash em dash] (—) surrounded by a single pair of spaces. (Replace with two normal dashes in eAthena scripting.)
# Intervals and other ranges:
#* Use an [http://en.wikipedia.org/wiki/Dash#En_dash en dash] (–) for marking ranges, both numeric and other. (Replace with two normal dashes in eAthena scripting.)
#* Compounds use the normal dash.


'''eAthena example'''
  // Example of NPC script
  // 1. Sentence ending punctuation
mes "A sentence. Another sentence!";
   
   
  // 2. Missing or cut off text
  012-3.gat,43,21,0 script NPC Name 123,{
  mes "\"No, I don't want to--\"";
mes "[NPC Name]";
  mes "It seems ... he died.";
mes "\"Yah! This is my first spoken line. What do you want?\"";
next;
L_main_menu:
menu
"A fancier menu.", L_fancy_menu,
"An even fancier menu.", L_fancier_menu,
"Do stuff!", L_change_things,
"Nothing.", -;
   
mes "[NPC Name]";
mes "\"That means the end. Bye!\"";
close;
L_fancy_menu:
if (!(UNSET_GLOBAL_FLAGS & PARTICULAR_ONE) && !(UNSET_GLOBAL_FLAGS & PARTICULAR_TWO))
menu
"Back to main menu.", L_main_menu,
"Close.", -;
if ((UNSET_GLOBAL_FLAGS & PARTICULAR_ONE) && !(UNSET_GLOBAL_FLAGS & PARTICULAR_TWO))
menu
"Back to main menu.", L_main_menu,
"Particular option one.", L_particular_option_one,
"Close.", -;
if (!(UNSET_GLOBAL_FLAGS & PARTICULAR_ONE) && (UNSET_GLOBAL_FLAGS & PARTICULAR_TWO))
menu
"Back to main menu.", L_main_menu,
"Particular option two.", L_particular_option_two,
"Close.", -;
if ((UNSET_GLOBAL_FLAGS & PARTICULAR_ONE) && (UNSET_GLOBAL_FLAGS & PARTICULAR_TWO))
menu
"Back to main menu.", L_main_menu,
"Particular option one.", L_particular_option_one,
"Particular option two.", L_particular_option_two,
"Close.", -;
close;
L_fancier_menu:
// Credit goes to fate for this (relatively) handy one
set @CHOICE_MAIN_MENU,      0;
set @CHOICE_PARTICULAR_ONE, 1;
set @CHOICE_PARTICULAR_TWO, 2;
set @CHOICE_CLOSE,          9;
setarray @menu_options$, "", "", "", "";
set @menu_option, 0;
   
set @menu_options$[@menu_option], "Back to main menu.";
set @menu_choice[@menu_option], @CHOICE_MAIN_MENU;
set @menu_option, @menu_option + 1;
if (UNSET_GLOBAL_FLAGS & PARTICULAR_ONE)
goto L_fancier_menu_one;
goto L_fancier_menu_end;
L_fancier_menu_one:
set @menu_options$[@menu_option], "Particular option one.";
set @menu_choice[@menu_option], @CHOICE_PARTICULAR_ONE;
set @menu_option, @menu_option + 1;
if (UNSET_GLOBAL_FLAGS & PARTICULAR_TWO)
goto L_fancier_menu_two;
goto L_fancier_menu_end;
L_fancier_menu_two:
set @menu_options$[@menu_option], "Particular option two.";
set @menu_choice[@menu_option], @CHOICE_PARTICULAR_TWO;
set @menu_option, @menu_option + 1;
L_fancier_menu_end:
set @menu_options$[@menu_option], "Close.";
set @menu_choice[@menu_option], @CHOICE_CLOSE;
menu
@menu_options$[0], -,
@menu_options$[1], -,
@menu_options$[2], -,
@menu_options$[3], -;
set @menu, @menu - 1;
if (@menu_choice[@menu] == @CHOICE_MAIN_MENU) goto L_main_menu;
if (@menu_choice[@menu] == @CHOICE_PARTICULAR_ONE) goto L_particular_option_one;
if (@menu_choice[@menu] == @CHOICE_PARTICULAR_TWO) goto L_particular_option_two;
close;
   
   
  // 3. Parenthetically offset text
  L_change_things:
mes "By this apple -- and not any other -- she will rule the world.";
heal 500, 100;
   
   
// 4. Ranges
if (countitem("Iten") < 2) goto L_not_enough_items;
mes "Lately the Tulimshar--Hurnscald highway is rather non-lethal.";
if (zeny < 12) goto L_not_enough_money;
mes "\"Give me 100--200 itens, pliz!\"";
delitem "Iten", 2;
 
getitem "Gr8t Iten", 1;
'''TMWserv example'''
set zeny, zeny - 12;
-- 1. Sentence ending punctuation
getexp 42, 0;
do_message(npc, char, "A sentence. Another sentence!")
mes "[42 experience points]";
   
   
-- 2. Missing or cut off text
close;
do_message(npc, char, "“No, I don’t want to—”")
do_message(npc, char, "It seems … he died.")
   
   
  -- 3. Parenthetically offset text
  }
do_message(npc, char, "By this apple — and not any other — she will rule the world.")
 
A few good things:
* Relatively straight-forward language
** Including label <tt>goto</tt>s
 
A few things that could have been easier:
* Contextual <tt>menu</tt>s
* Client side:
** Experience and gold should be announced (per client settings) just like recieved items, such messages should not need to be entered in the script itself
** NPC names should be displayed by the client, not hard coded in place in the script itself
 
=== tmwserv (currently) ===
 
-- TODO
 
A few good things:
* ...
 
A few things that could be made easier:
* More straight-forward language
** Especially with regards to function naming and scope
 
=== tmwserv (proposal) ===
 
-- TODO
 
 
<!--
=== NPC dialogue ===
Currently on eAthena:
 
// A comment!
   
   
  -- 4. Ranges
  mes "[Maji Chan]";
  do_message(npc, char, "Lately the Tulimshar–Hurnscald highway is rather non-lethal.")
  mes "\"How do you do my dear quester?\"";
  do_message(npc, char, "“Give me 100–200 itens, pliz!”")
  next;


=== Quotes ===
Currently on tmwserv:
* Use \" for direct speech.
** For the double quotation mark not to interfere with the scripting code, a backslash needs to be prepended it.
* Contractions and quotes within the direct speech use the single quote '.


  // Quote example
  do_message(npc, char, "“How do you do my dear quester?”")
mes "<span style="color:green;">\"</span>Ah, Agostine! The <span style="color:green;">'legendary tailor'</span>!<span style="color:green;">\"</span>";
mes "<span style="color:green;">\"</span>Aw, you <span style="color:green;">don't</span> have enough gold on you!<span style="color:green;">\"</span>";


=== Text formatting ===
Which is quite unwieldy. When scripting you most often only have the NPC say something to the player, so this could be simplified a fair bit to something like:
* Item and monster names, please use the names in the way shown by the client (e.g., Black Scorpion, Bottle of Sand) outside direct speech in the dialogues.
* Emphasis may be formatted with capital letters, use it sparingly.
* Actions may be put inside asterisks, use it sparingly.


  // Formatting example
  message("“How do you do my dear quester?”")
mes "\"I was fighting <span style="color:green;">scorpions</span> for experience and I bumped into a <span style="color:green;">RED</span> one.\"";
mes "\"I fought, of course! It hit me here <span style="color:green;">*points at a bruise at his shoulder*</span>.\"";


== Scripting style ==
I would actually propose to <tt>gettext</tt>-ize it:
Should in general follow the [[Hacking#Coding_style_guidelines|coding style guidelines]].


=== Comments ===
message(_("“How do you do my dear quester?”"))
* Each file should begin with a comment block describing the scope and use of the file.
** <span style="color:red;">Put a template here?</span>


=== Indentation ===
==== Using variables ====
* All indentations are made with tabs, one for each indentation level.
Currently on eAthena:
* Labels use no indentations at all.
* Menus have all their options on their own lines, and indented one level.
* <span style="color:red;">If clauses...</span>


  // Indentation example
  set @variable_1 = 42; // numeral variable for the local script
  L_label:
set @variable_2$ = "Bottle of Sand"; // string variable for the local script
mes "What do you want to do?";
   
next;
mes "\"Did you bring " + @variable_1 + " [" + @variable_2$ + "]?\"";
menu
 
"Spend money", -,
-->
"Script a fun quest", L_good_choice;
 
close;
== See also ==
tmwserv:
* [[Scripting|Script bindings]] — things we currently can access through scripts
* [[User:Crush/Scripting|Script bindings to do]] — things we should be able to access through scripts... in time
* <tt>[http://gitorious.org/tmwserv-data/mainline/blobs/raw/master/scripts/test.lua <tmwserv-data>/scripts/test.lua]</tt> — current script example


=== Blocks of code ===
eAthena:
* Code blocks should be separated from each other in a dinstinct way; the best way of doing it is to insert a blank line between code blocks.
* [[eAthena Scripting Standards|eAthena scripting standards]]
* Do not add blank lines within individual blocks.
* The opening brackets should be at the end of the parent line, not in a new line; the closing ones should be on a line of their own.

Latest revision as of 09:55, 28 September 2009

In my mind a scripting language should be simple to both understand and use. You should not need to be a C++/Lua hacker to be able to create a dialogue menu where some replies depends on certain circumstances. Here follows a few suggestions how the tmwserv Lua scripting could look.

Example script

In current eAthena and tmwserv script as well as a proposal of a more scripter comfortable tmwserv syntax.

eAthena

// Example of NPC script

012-3.gat,43,21,0	script	NPC Name	123,{
	mes "[NPC Name]";
	mes "\"Yah! This is my first spoken line. What do you want?\"";
	next;

L_main_menu:
	menu
		"A fancier menu.", L_fancy_menu,
		"An even fancier menu.", L_fancier_menu,
		"Do stuff!", L_change_things,
		"Nothing.", -;

	mes "[NPC Name]";
	mes "\"That means the end. Bye!\"";
	close;

L_fancy_menu:
	if (!(UNSET_GLOBAL_FLAGS & PARTICULAR_ONE) && !(UNSET_GLOBAL_FLAGS & PARTICULAR_TWO))
		menu
			"Back to main menu.", L_main_menu,
			"Close.", -;

	if ((UNSET_GLOBAL_FLAGS & PARTICULAR_ONE) && !(UNSET_GLOBAL_FLAGS & PARTICULAR_TWO))
		menu
			"Back to main menu.", L_main_menu,
			"Particular option one.", L_particular_option_one,
			"Close.", -;

	if (!(UNSET_GLOBAL_FLAGS & PARTICULAR_ONE) && (UNSET_GLOBAL_FLAGS & PARTICULAR_TWO))
		menu
			"Back to main menu.", L_main_menu,
			"Particular option two.", L_particular_option_two,
			"Close.", -;

	if ((UNSET_GLOBAL_FLAGS & PARTICULAR_ONE) && (UNSET_GLOBAL_FLAGS & PARTICULAR_TWO))
		menu
			"Back to main menu.", L_main_menu,
			"Particular option one.", L_particular_option_one,
			"Particular option two.", L_particular_option_two,
			"Close.", -;

	close;

L_fancier_menu:
	// Credit goes to fate for this (relatively) handy one
	set @CHOICE_MAIN_MENU,      0;
	set @CHOICE_PARTICULAR_ONE, 1;
	set @CHOICE_PARTICULAR_TWO, 2;
	set @CHOICE_CLOSE,          9;

	setarray @menu_options$, "", "", "", "";
	set @menu_option, 0;

	set @menu_options$[@menu_option], "Back to main menu.";
	set @menu_choice[@menu_option], @CHOICE_MAIN_MENU;
	set @menu_option, @menu_option + 1;

	if (UNSET_GLOBAL_FLAGS & PARTICULAR_ONE)
		goto L_fancier_menu_one;
	goto L_fancier_menu_end;

L_fancier_menu_one:
	set @menu_options$[@menu_option], "Particular option one.";
	set @menu_choice[@menu_option], @CHOICE_PARTICULAR_ONE;
	set @menu_option, @menu_option + 1;

	if (UNSET_GLOBAL_FLAGS & PARTICULAR_TWO)
		goto L_fancier_menu_two;
	goto L_fancier_menu_end;

L_fancier_menu_two:
	set @menu_options$[@menu_option], "Particular option two.";
	set @menu_choice[@menu_option], @CHOICE_PARTICULAR_TWO;
	set @menu_option, @menu_option + 1;

L_fancier_menu_end:
	set @menu_options$[@menu_option], "Close.";
	set @menu_choice[@menu_option], @CHOICE_CLOSE;

	menu
		@menu_options$[0], -,
		@menu_options$[1], -,
		@menu_options$[2], -,
		@menu_options$[3], -;

	set @menu, @menu - 1;

	if (@menu_choice[@menu] == @CHOICE_MAIN_MENU) goto L_main_menu;
	if (@menu_choice[@menu] == @CHOICE_PARTICULAR_ONE) goto L_particular_option_one;
	if (@menu_choice[@menu] == @CHOICE_PARTICULAR_TWO) goto L_particular_option_two;

	close;

L_change_things:
	heal 500, 100;

	if (countitem("Iten") < 2) goto L_not_enough_items;
	if (zeny < 12) goto L_not_enough_money;
	delitem "Iten", 2;
	getitem "Gr8t Iten", 1;
	set zeny, zeny - 12;
	getexp 42, 0;
	mes "[42 experience points]";

	close;

}

A few good things:

  • Relatively straight-forward language
    • Including label gotos

A few things that could have been easier:

  • Contextual menus
  • Client side:
    • Experience and gold should be announced (per client settings) just like recieved items, such messages should not need to be entered in the script itself
    • NPC names should be displayed by the client, not hard coded in place in the script itself

tmwserv (currently)

-- TODO

A few good things:

  • ...

A few things that could be made easier:

  • More straight-forward language
    • Especially with regards to function naming and scope

tmwserv (proposal)

-- TODO


See also

tmwserv:

eAthena: