From The Mana World
m (Archival of a rewrite I started on earlier this year)
(Hrmpf! decided to do it in another way)
Line 1: Line 1:
== Current and proposed practice ==
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.
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;
close;
}
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
=== 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 ===
=== NPC dialogue ===
Currently on eAthena:
Currently on eAthena:
Line 13: Line 150:
Currently on tmwserv:
Currently on tmwserv:


-- A comment!
  do_message(npc, char, "“How do you do my dear quester?”")
  do_message(npc, char, "“How do you do my dear quester?”")


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:
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:


-- A comment!
  message("“How do you do my dear quester?”")
  message("“How do you do my dear quester?”")


I would actually propose to <tt>gettext</tt>-ize it:
I would actually propose to <tt>gettext</tt>-ize it:


-- A comment!
  message(_("“How do you do my dear quester?”"))
  message(_("“How do you do my dear quester?”"))


Line 37: Line 168:
  mes "\"Did you bring " + @variable_1 + " [" + @variable_2$ + "]?\"";
  mes "\"Did you bring " + @variable_1 + " [" + @variable_2$ + "]?\"";


 
-->
Currently on tmwserv:
 
...
 
==== Displaying dialogue options ====
Currently on eAthena:
 
mes "It seems Maji Chan is waiting for an answer...";
next;
menu
"I'm fine!, thanks for asking.", L_a_good_option,
"...", -, // Continue after the menu
"Quite well, and you?", L_another_good_option;
mes "[Maji Chan]";
mes "\"\You could at least say something!\"";
close;
 
Currently on tmwserv:
 
...
 
==== Variable dialogue options ====
Currently on eAthena (easy but quickly unwieldy solution):
 
set @variable = 108;
if (@variable < 100)
menu
"Ye olde dialogue option.", L_usual_option,
"Good bye!", -;
if (@variable >= 100)
menu
"Ye olde dialogue option.", L_usual_option,
"A new exciting option!", L_ohhhh,
"Good bye!", -;
close;
 
Currently on eAthena (more complex solution):
 
...
 
Currently on tmwserv:
 
...
 
=== Starting a script from scratch ===
...


== See also ==
== See also ==
tmwserv:
* [[Scripting|Script bindings]] — things we currently can access through scripts
* [[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
* [[User:Crush/Scripting|Script bindings to do]] — things we should be able to access through scripts... in time
* [http://gitorious.org/tmwserv-data/mainline/blobs/raw/master/scripts/test.lua Current tmwserv script example]
* <tt>[http://gitorious.org/tmwserv-data/mainline/blobs/raw/master/scripts/test.lua <tmwserv-data>/scripts/test.lua]</tt> — current script example
* [[eAthena Scripting Standards|eAthena scripting standards]] — scripting on the old eA server software
 
eAthena:
* [[eAthena Scripting Standards|eAthena scripting standards]]

Revision as of 09:47, 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;

	close;

}

A few good things:

  • Relatively straight-forward language
    • Including label gotos

A few things that could have been easier:

  • Contextual menus

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: