Re: LunaLua Offical Thread - SMBX Usermod Framework
Posted: Wed Apr 13, 2016 10:38 pm
Hey everyone! Creator of cinematX, textblox, paralX and other such infamous ambitious lua libraries here with a bit of a PSA about a problem that's recently come to my attention: selfish message parsing.
Back when cinematX was in its' early stages I decided to try and utilize npcs' message text to allow users to define unique properties for each npc in the editor in an effort to make the library a bit more user-friendly. Though getting the library to a stable release has been somewhat of an uphill battle since v0.7, the message tags still became a key feature of cinematX... and now, as I understand it, the feature seems to be catching on.
If I had the foresight to anticipate this I would've designed and implemented cinematX's message parsing differently, as the format of a cinematX message doesn't take into account other libraries that may want to use the npc message text as well. Any npcs that have cinematX properties in their message text can't have properties for any other library that uses this kind of system, and vice versa. And the more we use such "selfish" message parsing systems, the more libraries we'll have that are fundamentally incompatible with one another.
The folks behind Lunalua, SMBX 2.0 and the PGE are working on phasing out the .lvl format in favor of the more flexible .lvlx format, which would allow more unique data for npcs, but as I understand it there's a lot of work involved in that so it's a long-term goal. In the meantime, we need a standardized method of parsing message text that:
A) Allows for all libraries to store data in the message string without conflicting with one another,
B) Allows users to define both a regular message string and parsed data,
C) Has a clear syntax that makes it easy to differentiate between regular message text and extra data,
D) Is as user-friendly as possible
I'm working on a possible candidate for this, tentatively called npcParse. It parses lua tables from NPC message strings and copies the information to each npc's pnpc data. The library should satisfy criteria A through C, though I'm not so sure about D.
npcParse-standard message strings would be formatted as nested tables, with a "newMsg" key corresponding to the replacement message text and everything else being stored in the pnpc data as-is, like so:
If the library doesn't detect the initial "{", it treats the text like a regular message, and if newMsg isn't specified the npc will behave as if it has no message. But again, I don't know how readable this syntax is for most folks, so it may not be the best candidate.
But whether it be npcParse or some other system, the sooner we have a standard, the better. If too many libraries start using selfish parsing and then end up having to switch to standardized parsing for compatibility with other libraries, that will break levels that use those libraries.
Now, what if you don't want to use a standardized parsing system? Well, it's your library, you have the right to code it however you want. Just keep in mind that you'd be preventing users from combining your library with others' and you'd be perpetuating a bad programming practice for other potential lua devs. And maybe that's not so big an issue for smaller, more specialized projects, but it's probably not something we should use in official SMBX 2.0 code or other higher-profile libraries. As it is, I'll be switching cinematX over to the new system as soon as it's been established. This will break every cinematX level that uses npc message tags, but I don't see much of a way around that.
This has been rockythechao with the Super-Serious Alarmist Evening News Time Report Thingy. My deepest apologies for essentially starting the SMBX equivalent of Y2K, and I sincerely hope these concerns of mine end up being overblown.
EDIT: Another possible option is that we could have a system that's similar to npcParse but instead of keeping all the library properties in the message text they could be stored as JSON in an external file, and the message text would just have a reference key and replacement message:
Back when cinematX was in its' early stages I decided to try and utilize npcs' message text to allow users to define unique properties for each npc in the editor in an effort to make the library a bit more user-friendly. Though getting the library to a stable release has been somewhat of an uphill battle since v0.7, the message tags still became a key feature of cinematX... and now, as I understand it, the feature seems to be catching on.
If I had the foresight to anticipate this I would've designed and implemented cinematX's message parsing differently, as the format of a cinematX message doesn't take into account other libraries that may want to use the npc message text as well. Any npcs that have cinematX properties in their message text can't have properties for any other library that uses this kind of system, and vice versa. And the more we use such "selfish" message parsing systems, the more libraries we'll have that are fundamentally incompatible with one another.
The folks behind Lunalua, SMBX 2.0 and the PGE are working on phasing out the .lvl format in favor of the more flexible .lvlx format, which would allow more unique data for npcs, but as I understand it there's a lot of work involved in that so it's a long-term goal. In the meantime, we need a standardized method of parsing message text that:
A) Allows for all libraries to store data in the message string without conflicting with one another,
B) Allows users to define both a regular message string and parsed data,
C) Has a clear syntax that makes it easy to differentiate between regular message text and extra data,
D) Is as user-friendly as possible
I'm working on a possible candidate for this, tentatively called npcParse. It parses lua tables from NPC message strings and copies the information to each npc's pnpc data. The library should satisfy criteria A through C, though I'm not so sure about D.
npcParse-standard message strings would be formatted as nested tables, with a "newMsg" key corresponding to the replacement message text and everything else being stored in the pnpc data as-is, like so:
Code: Select all
-- Message string
{newMsg="Hi there.", particles={spawnrate=5, name="robert", waffle=true}, cinematx={key="goopasib2", icon=1, scene="cutscene_TestQuest3"}, customlotus={bullets=999}, rinkas={and so on}}
-- Output
pnpcref.data.particles.spawnrate --> 5
pnpcref.data.particles.name --> "robert"
pnpcref.data.particles.waffle --> true
pnpcref.data.cinematx.key --> "goopasib2"
pnpcref.data.cinematx.icon --> 1
pnpcref.data.cinematx.scene --> "cutscene_TestQuest3"
pnpcref.data.cinematx.scene --> "cutscene_TestQuest3"
pnpcref.data.customlotus.bullets --> 999
But whether it be npcParse or some other system, the sooner we have a standard, the better. If too many libraries start using selfish parsing and then end up having to switch to standardized parsing for compatibility with other libraries, that will break levels that use those libraries.
Now, what if you don't want to use a standardized parsing system? Well, it's your library, you have the right to code it however you want. Just keep in mind that you'd be preventing users from combining your library with others' and you'd be perpetuating a bad programming practice for other potential lua devs. And maybe that's not so big an issue for smaller, more specialized projects, but it's probably not something we should use in official SMBX 2.0 code or other higher-profile libraries. As it is, I'll be switching cinematX over to the new system as soon as it's been established. This will break every cinematX level that uses npc message tags, but I don't see much of a way around that.
This has been rockythechao with the Super-Serious Alarmist Evening News Time Report Thingy. My deepest apologies for essentially starting the SMBX equivalent of Y2K, and I sincerely hope these concerns of mine end up being overblown.
EDIT: Another possible option is that we could have a system that's similar to npcParse but instead of keeping all the library properties in the message text they could be stored as JSON in an external file, and the message text would just have a reference key and replacement message:
Code: Select all
-- Message text in the editor
{id="boss", newMsg="Hi there."}
-- [level folder]/npcdata.json
{
"boss": {
"particles": {
"name": "robert"
}
"cinematX": {
"icon": 1
}
"customlotus": {
"bullets": 999
}
}
}