From The Mana World

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: