WesScriptLayer
Moderator: Forum Moderators
WesScriptLayer
Please note, this first post is still work in progress.
I will inform in the thread about updates.
I have been developing recently an alternative scripting language which builds on WML, which hopes to be easier to use, with some powerful features that WML lacks, and which is easier to implement in a game engine. I am already quite pleased with how the current design is, but now I would like to ask for some feedback from UMC developers.
Wes(mere)ScriptLayer (or short WSL) is an API
for defining content and scripting game mechanics for Wesnoth like games in Lua.
WesScript is a language used to define content and make scripts which use the WesScriptLayer. WesScript is a 'flavor' of MoonScript. MoonScript is a recent scripting language which builds on Lua. MoonScript is entirely compatible with lua (and indeed, is compiled to lua) -- it introduces some syntactic sugar for making tables and functions, and makes use of significant whitespace in order to reduce notational burden to a minimum. MoonScript also adds improved support for object-oriented programming. MoonScript ends up feeling like a hybrid between Python and Lua, perhaps. WesScript is 'flavored' moonscript in that it introduces a further bit of syntactic sugar which allows defining lists in a manner very similar to WML.
I will inform in the thread about updates.
I have been developing recently an alternative scripting language which builds on WML, which hopes to be easier to use, with some powerful features that WML lacks, and which is easier to implement in a game engine. I am already quite pleased with how the current design is, but now I would like to ask for some feedback from UMC developers.
Wes(mere)ScriptLayer (or short WSL) is an API
for defining content and scripting game mechanics for Wesnoth like games in Lua.
WesScript is a language used to define content and make scripts which use the WesScriptLayer. WesScript is a 'flavor' of MoonScript. MoonScript is a recent scripting language which builds on Lua. MoonScript is entirely compatible with lua (and indeed, is compiled to lua) -- it introduces some syntactic sugar for making tables and functions, and makes use of significant whitespace in order to reduce notational burden to a minimum. MoonScript also adds improved support for object-oriented programming. MoonScript ends up feeling like a hybrid between Python and Lua, perhaps. WesScript is 'flavored' moonscript in that it introduces a further bit of syntactic sugar which allows defining lists in a manner very similar to WML.
Motivation
Tags & Tables
Tables & Functions
Functions & Macros
Macros & Scopes
Scopes & Folders
Folders & WesMods
Layers & Kernel
Coding Conventions
Content Definition
Scenario Scripting
Last edited by fendrin on October 30th, 2015, 10:21 pm, edited 4 times in total.
"Wesnoth has many strong points but team and users management are certainly not in them." -- pyrophorus
"The thing a project in the true spirit of open source has to fear is not forking, but clean-room re-implementation. When that happens, you know something is wrong."
"The thing a project in the true spirit of open source has to fear is not forking, but clean-room re-implementation. When that happens, you know something is wrong."
- Pentarctagon
- Project Manager
- Posts: 5564
- Joined: March 22nd, 2009, 10:50 pm
- Location: Earth (occasionally)
Re: WesScriptLayer
So is this meant as a replacement for WML? For lua? Both?
99 little bugs in the code, 99 little bugs
take one down, patch it around
-2,147,483,648 little bugs in the code
take one down, patch it around
-2,147,483,648 little bugs in the code
Re: WesScriptLayer
The WSL can be used with Lua or WesScript.Pentarctagon wrote:So is this meant as a replacement for WML? For lua? Both?
So it replaces only WML.
Although Lua code making use of Wesnoth's Lua api is not supposed to be supported.
So maybe "both" is the correct answer.
"Wesnoth has many strong points but team and users management are certainly not in them." -- pyrophorus
"The thing a project in the true spirit of open source has to fear is not forking, but clean-room re-implementation. When that happens, you know something is wrong."
"The thing a project in the true spirit of open source has to fear is not forking, but clean-room re-implementation. When that happens, you know something is wrong."
- Pentarctagon
- Project Manager
- Posts: 5564
- Joined: March 22nd, 2009, 10:50 pm
- Location: Earth (occasionally)
Re: WesScriptLayer
Reading through the scenario, I think the thing I dislike the most (beyond 'OMG it's different!') is the lack of any closing block markers. It's not really a problem for the scenario since they never get nested too deeply, but it seems like it would be a real pain to try and figure out exactly where certain things end when there are 10, 20, or more tags layered and the full block of code is larger than the height of the screen. One of the things that I always disliked about lua was the mass of useless brackets which tell me nothing about what's actually happening and while this solves the "mass of brackets" annoyance it still gives me less information about what's going on.
A couple other questions:
1) Why do some values use quotes and others use double brackets? For example:
2) When is the "->" supposed to be used? The scenario has it right after an event:
but also not right after the event:
A couple other questions:
1) Why do some values use quotes and others use double brackets? For example:
Code: Select all
DUSK =
id: "dusk"
name: [[Dusk]]
image: "misc/time-schedules/default/schedule-dusk"
green: -20
blue: -20
sound: "ambient/night"
Code: Select all
TimeOver: ->
message
Code: Select all
LastBreath:
filter:
id: "Erlornas"
command: ->
99 little bugs in the code, 99 little bugs
take one down, patch it around
-2,147,483,648 little bugs in the code
take one down, patch it around
-2,147,483,648 little bugs in the code
Re: WesScriptLayer
Both, the indentation level (== tags layered) and the size of a block are manageable.Pentarctagon wrote:Reading through the scenario, I think the thing I dislike the most (beyond 'OMG it's different!') is the lack of any closing block markers. It's not really a problem for the scenario since they never get nested too deeply, but it seems like it would be a real pain to try and figure out exactly where certain things end when there are 10, 20, or more tags layered and the full block of code is larger than the height of the screen. One of the things that I always disliked about lua was the mass of useless brackets which tell me nothing about what's actually happening and while this solves the "mass of brackets" annoyance it still gives me less information about what's going on.
Every language offers features to reduce them.
In WML you have 3 different possibilities, that is why I have never seen 20 or more tags layered:
- Macros
- Calling custom event handlers (emulates the function concept)
- The [insert_wml] tag
Lua/MoonScript offers the function concept for this purpose (and others of course).
Also note that WML tends to get quite nested when it comes to flow control, Lua and WesScript do much better there.
This is one of the points why WML is not a good scripting language.
I will show you some nice examples later.
That said, you can of course when you like to write code that is deeply nested use brackets.
MoonScript knows about them just like Lua does.
They will not only give you a better readability but also throw errors when your indentation fails.
Strings in [[ ]] are meant to be translatable.A couple other questions:
1) Why do some values use quotes and others use double brackets?
"->" is the MoonScript syntax for telling the interpreter that the variable or table entry is to be bound to a function.2) When is the "->" supposed to be used? The scenario has it right after an event:but also not right after the event:Code: Select all
TimeOver: -> message
Code: Select all
LastBreath: filter: id: "Erlornas" command: ->
After -> the body (a block) of the function starts.
In the case of the "TimeOver" event handler there is no filter usage, thus the table would only contain the command entry.
Code: Select all
TimeOver: ->
message
Code: Select all
TimeOver:
command: ->
message
"Wesnoth has many strong points but team and users management are certainly not in them." -- pyrophorus
"The thing a project in the true spirit of open source has to fear is not forking, but clean-room re-implementation. When that happens, you know something is wrong."
"The thing a project in the true spirit of open source has to fear is not forking, but clean-room re-implementation. When that happens, you know something is wrong."
- Pentarctagon
- Project Manager
- Posts: 5564
- Joined: March 22nd, 2009, 10:50 pm
- Location: Earth (occasionally)
Re: WesScriptLayer
My own case is admittedly a bit of an outlier, since it's a modification that contains a single right-click menu item. I split things apart with file includes to help deal with it and better organize things, but if the entire menu was in a single file the greatest tag depth would be in the mid 30s.fendrin wrote:Both, the indentation level (== tags layered) and the size of a block are manageable.Pentarctagon wrote:Reading through the scenario, I think the thing I dislike the most (beyond 'OMG it's different!') is the lack of any closing block markers. It's not really a problem for the scenario since they never get nested too deeply, but it seems like it would be a real pain to try and figure out exactly where certain things end when there are 10, 20, or more tags layered and the full block of code is larger than the height of the screen. One of the things that I always disliked about lua was the mass of useless brackets which tell me nothing about what's actually happening and while this solves the "mass of brackets" annoyance it still gives me less information about what's going on.
Every language offers features to reduce them.
In WML you have 3 different possibilities, that is why I have never seen 20 or more tags layered:
- Macros
- Calling custom event handlers (emulates the function concept)
- The [insert_wml] tag
Lua/MoonScript offers the function concept for this purpose (and others of course).
Also note that WML tends to get quite nested when it comes to flow control, Lua and WesScript do much better there.
This is one of the points why WML is not a good scripting language.
I will show you some nice examples later.
That said, you can of course when you like to write code that is deeply nested use brackets.
MoonScript knows about them just like Lua does.
They will not only give you a better readability but also throw errors when your indentation fails.
99 little bugs in the code, 99 little bugs
take one down, patch it around
-2,147,483,648 little bugs in the code
take one down, patch it around
-2,147,483,648 little bugs in the code
Re: WesScriptLayer
I have promised some examples earlier, now I think translating your menu item would be a good demonstration of what to expect with WesScript.Pentarctagon wrote:My own case is admittedly a bit of an outlier, since it's a modification that contains a single right-click menu item. I split things apart with file includes to help deal with it and better organize things, but if the entire menu was in a single file the greatest tag depth would be in the mid 30s.
Can I have the code?
"Wesnoth has many strong points but team and users management are certainly not in them." -- pyrophorus
"The thing a project in the true spirit of open source has to fear is not forking, but clean-room re-implementation. When that happens, you know something is wrong."
"The thing a project in the true spirit of open source has to fear is not forking, but clean-room re-implementation. When that happens, you know something is wrong."
- Pentarctagon
- Project Manager
- Posts: 5564
- Joined: March 22nd, 2009, 10:50 pm
- Location: Earth (occasionally)
Re: WesScriptLayer
It's on the add-on server here. Translating the entire thing is probably a bit more effort than it's worth though.
99 little bugs in the code, 99 little bugs
take one down, patch it around
-2,147,483,648 little bugs in the code
take one down, patch it around
-2,147,483,648 little bugs in the code
Re: WesScriptLayer
Here is some update, I plan to integrate it into the first post later.
In Wesnoth a UMC Designer can register additional actionWML tags by using the lua api.
Wesmere also allows to register additions to the WSL api which are in other scopes of the game.
Functions used to register game content are called WSL table handlers.
The [unit_type] WML tag's equivalent is one of those for example.
Before the engine reads the data directory it knows only about a single table handler called wsl_table.
It is used to register every other WSL table handler.
The terrain_type makes a simple and good example.
Those are optional:
In Wesnoth a UMC Designer can register additional actionWML tags by using the lua api.
Wesmere also allows to register additions to the WSL api which are in other scopes of the game.
Functions used to register game content are called WSL table handlers.
The [unit_type] WML tag's equivalent is one of those for example.
Before the engine reads the data directory it knows only about a single table handler called wsl_table.
It is used to register every other WSL table handler.
The terrain_type makes a simple and good example.
id: "terrain_type"
The identity later used to call the function.scope: "Terrain"
terrain_type will be available when scanning the "Terrain" folder of a WesMod. Scopes are derived from WML toplevel tags. If scope is missing the table handler is used in WesMod toplevels.description: "Some Text"
description is used to store the WSL api reference entries. This will be used to generate the WSL reference webpage and in the in-game command line.scheme:
The scheme table is used to check against the given table for type correctness and completeness. The engine will also error on unrecognized keys. Note the description:
for each key.Those are optional:
on_scan:
a hook function to do additional checkson_load:
a hook function to do additional data transformation"Wesnoth has many strong points but team and users management are certainly not in them." -- pyrophorus
"The thing a project in the true spirit of open source has to fear is not forking, but clean-room re-implementation. When that happens, you know something is wrong."
"The thing a project in the true spirit of open source has to fear is not forking, but clean-room re-implementation. When that happens, you know something is wrong."
Re: WesScriptLayer
After some more testing the idea how to translate WML variables is getting more stable.
MoonScript comes with the really nice feature to invert Lua's syntax and behavior regarding local and global variables.
Lua
MoonScript
So in the actionWSL context (which is used to execute all event handlers and thus the scope where scenario scripting takes place) local variables can live during the whole execution of the event handler's function.
There is no more need to clean these variables, they are removed from the memory when the execution leaves the current scope (a block in most cases).
UMC scripters not feeling firm with the scope system yet can just define all needed variables at the start of the event-handler function,
making sure they are visible during its whole execution.
Whenever a variable is needed that can be accessed in all event handlers (or in a successive scenario) the global variable concept of Lua comes in handy.
So global Lua variables pretty much work like WML variables do.
Cleaning them up like
Since in Lua (and thus in MoonScript as well) functions are just variables themselves both share the same namespace.
This means
I still wonder if WSL functions should be made read only to avoid this.
Note that I have avoided to use the term "persistence" deliberately until now.
Wesnoth's "persistent variable" concept is a different issue.
MoonScript comes with the really nice feature to invert Lua's syntax and behavior regarding local and global variables.
Lua
Code: Select all
side_number = 2 -- a global variable
local side_number = 2 -- variable is only visible in the current lexical scope
Code: Select all
side_number = 2 -- variable is only visible in the current lexical scope
export side_number = 2 -- a global variable
There is no more need to clean these variables, they are removed from the memory when the execution leaves the current scope (a block in most cases).
UMC scripters not feeling firm with the scope system yet can just define all needed variables at the start of the event-handler function,
making sure they are visible during its whole execution.
Whenever a variable is needed that can be accessed in all event handlers (or in a successive scenario) the global variable concept of Lua comes in handy.
So global Lua variables pretty much work like WML variables do.
Cleaning them up like
side_number = nil
is a good idea to avoid cluttering the global namespace and to reduce memory and safe file footprints.Since in Lua (and thus in MoonScript as well) functions are just variables themselves both share the same namespace.
This means
store_unit = some_value
will overwrite (or at least shadow) the WSL store_unit function.I still wonder if WSL functions should be made read only to avoid this.
Note that I have avoided to use the term "persistence" deliberately until now.
Wesnoth's "persistent variable" concept is a different issue.
"Wesnoth has many strong points but team and users management are certainly not in them." -- pyrophorus
"The thing a project in the true spirit of open source has to fear is not forking, but clean-room re-implementation. When that happens, you know something is wrong."
"The thing a project in the true spirit of open source has to fear is not forking, but clean-room re-implementation. When that happens, you know something is wrong."
Re: WesScriptLayer
While translating some of the macros from data/core/macros I found a nice example:fendrin wrote:I have promised some examples earlier...
https://gist.github.com/fendrin/5e74b3b17c62ea133faf
the WML counterpart:
https://github.com/wesnoth/wesnoth/blob ... s.cfg#L434
"Wesnoth has many strong points but team and users management are certainly not in them." -- pyrophorus
"The thing a project in the true spirit of open source has to fear is not forking, but clean-room re-implementation. When that happens, you know something is wrong."
"The thing a project in the true spirit of open source has to fear is not forking, but clean-room re-implementation. When that happens, you know something is wrong."
- Pentarctagon
- Project Manager
- Posts: 5564
- Joined: March 22nd, 2009, 10:50 pm
- Location: Earth (occasionally)
Re: WesScriptLayer
Maybe I'm mis-remembering, but I thought lua variables weren't stored in savefiles currently.fendrin wrote:Cleaning them up likeside_number = nil
is a good idea to avoid cluttering the global namespace and to reduce memory and safe file footprints.
Also, since there isn't going to be any preprocessing, is there a replacement planned for things like #ifdef, #ifhave, #ifver, etc?
99 little bugs in the code, 99 little bugs
take one down, patch it around
-2,147,483,648 little bugs in the code
take one down, patch it around
-2,147,483,648 little bugs in the code
Re: WesScriptLayer
Yes, I think that is right.Pentarctagon wrote:Maybe I'm mis-remembering, but I thought lua variables weren't stored in savefiles currently.
Most of their use cases can be solved by using global variables or constants.Also, since there isn't going to be any preprocessing, is there a replacement planned for things like #ifdef, #ifhave, #ifver, etc?
The answer how to translate them pretty much depends on the exact use case.
"Wesnoth has many strong points but team and users management are certainly not in them." -- pyrophorus
"The thing a project in the true spirit of open source has to fear is not forking, but clean-room re-implementation. When that happens, you know something is wrong."
"The thing a project in the true spirit of open source has to fear is not forking, but clean-room re-implementation. When that happens, you know something is wrong."
- Pentarctagon
- Project Manager
- Posts: 5564
- Joined: March 22nd, 2009, 10:50 pm
- Location: Earth (occasionally)
Re: WesScriptLayer
I mean more generally though, if there isn't any preprocessing then they'd all basically have to be replaced with if statements as far as I can tell. #ifver's replacement in particular would need a global constant variable to be set and updated per release.fendrin wrote:Most of their use cases can be solved by using global variables or constants.Pentarctagon wrote:Also, since there isn't going to be any preprocessing, is there a replacement planned for things like #ifdef, #ifhave, #ifver, etc?
The answer how to translate them pretty much depends on the exact use case.
99 little bugs in the code, 99 little bugs
take one down, patch it around
-2,147,483,648 little bugs in the code
take one down, patch it around
-2,147,483,648 little bugs in the code
Re: WesScriptLayer
Indeed.Pentarctagon wrote:I mean more generally though, if there isn't any preprocessing then they'd all basically have to be replaced with if statements as far as I can tell. #ifver's replacement in particular would need a global constant variable to be set and updated per release.
Global variables or constants processed by conditional statements will do the trick.
"Wesnoth has many strong points but team and users management are certainly not in them." -- pyrophorus
"The thing a project in the true spirit of open source has to fear is not forking, but clean-room re-implementation. When that happens, you know something is wrong."
"The thing a project in the true spirit of open source has to fear is not forking, but clean-room re-implementation. When that happens, you know something is wrong."