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: | ||
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: | ||
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: | ||
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: | ||
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$ + "]?\""; | ||
--> | |||
== 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 | * <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]] | |||
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:
- Script bindings — things we currently can access through scripts
- Script bindings to do — things we should be able to access through scripts... in time
- <tmwserv-data>/scripts/test.lua — current script example
eAthena: