AGS-Lua Evangelism

Started by Calin Leafshade, Mon 24/12/2012 13:23:28

Previous topic - Next topic

Calin Leafshade

Hello everyone,

Wasn't sure where to put this.. its sort of technical but not technical enough to warrant the tech forum.

Anyway, I have come to the conclusion that everyone should stop using AGS script and move over to Lua for a wealth of reasons. it seems like a no brainer to me and yet I have seen a lot of resistance. I would like to know why that is and I would like to help wherever I can.

Are there modules you need for lua that I can code for you?
Are you just not sure how to link ags and lua together?
Are you afraid of putting in the effort of learning a new language?
Do you not see the benefits?

Tell me why, AGS forumers and I will do my best to help and ease the transition because I think it is a wasted opportunity for all you cavemen still languishing in AGSScript land.

Peder 🚀

What would you say are the key benefits of using Lua instead?

miguel

I understand that LUA should be a more powerful language than the one we get with AGS, but is it as easy to learn?
The one thing that gets people into AGS is its easy learning-curve.
Working on a RON game!!!!!

Crimson Wizard

Usually one would need a reason to use something above the standard features. That reason should be strong enough to stimulate learning (and using).
The reason appears when standard features are not enough to make what you want. This depends both on complexity of your game and your programming skills, or, maybe, programmer's way of thinking. Novices are often using very basic techniques to produce overcomplicated code simply because they do not know that they are doing it wrong. Even when you become more skilled, it may not be obvious that your program will become better (optimized, terse) if you'd use features that exist in other scripting language and do not exist in the one you are using.

In other words, people should know not only a list of features, but also a distinct examples of what they may do with them. Not "for fun", but serious practical examples of code (preferably fit for adventure game) that is not possible with AGS script, or requires too much effort with AGS script, while possible to do with less effort with Lua.

Calin Leafshade

#4
I suppose I did put the cart before the horse and should make my case first. Ok here I go.

First I should be honest. In terms of actual results, there isnt much that lua can do that AGSscript absolutely can't do but it might be *alot* easier in lua.

Ok a quick example. In my latest adventure game I have a contextual interface. That is to say that when you right click a hotspot you get a list of named actions. I tried to code this in AGSScript before i had lua and it was a fucking nightmare. If/Else statements coming out my wazoo. Because functions pointers dont exist in lua i had to tie all my interactions to cursor modes to separate them which was messy, made no sense and was stupid.

In lua however, i can set up a system where i can add an interaction to a hotspot like this:

Code: lua

RegisterInteraction(roomNumber, hotspotIndex, "Hit the table", function()
    player:Say("I hit the table!")
end)


And I can do this for as many hotspots and interactions as i like with no limitation.

Notice that I used a function like a variable. In lua you can do this which is *very* useful for adventure games.

Another example is that I can add arbitrary values to ags objects at runtime. Let's say my NPC had a 'suspicion' level and when it reached 100 he found me out in my misdeeds or whatever.
In ags I would store this in a different variable. If i had one for each npc I would store it in an array somewhere probably. In lua i can simply type:

Code: lua

    ags.cNPC.Suspicion = 50


And it's done, it's all in the same object and it makes semantic sense.

Also, all lua function and variables do NOT have to be declared before use. In AGS it's impossible to organise nice systems that depend on one another. Say you have a Camera struct and a Map struct and the camera wants to interact with the map but the map also needs to know where the camera is. This is impossible because AGS has no system for forward declaration which means your code has to be messy and shitty.

Reason 4 or 5 or whatever i'm on is that Lua is an established language with a lot of resources available. If you want code to do some pathfinding then there are dozens of Lua scripts already available in nice little modules.

Lua has a couple of plugins for oft-requested ags functions including TCP/IP.

Lua has coroutines which I've use in my RPG engine to have a custom say function which isn't hashed together bollocks like is required with ags and a million if/elses in repex.

Speaking of my RPG engine, I've managed to make an (almost) fully working RPG system with a nice inventory and map system in lua and it took me a few days max. Something no one else has done (to my knowledge) in AGS for a long time.

Lua will allow module makers to make more intuitive modules because we can have classes and inheritance and events and function pointers.

AGS teaches you a worthless skill badly.
AGS script is basically like C but with all the good bits missing and what this does (in my opinion) is teach you to be a poor programmer. You don't learn in terms of data structures because in AGS working with data structures is a chore. Not being able to pass structs either by value or by reference is a *massive* problem when it comes to teaching people how to code. Also, AGS script is only used in AGS. You might as well learn Lua and have another skill to add to your repetoir.

Sorry for the brain dump.. i just kept typing.

(And this before i've even mentioned the magic of tables)

Radiant

Quote from: Calin Leafshade on Mon 24/12/2012 14:24:50
In lua however, i can set up a system where i can add an interaction to a hotspot like this:

Code: lua

RegisterInteraction(roomNumber, hotspotIndex, "Hit the table", function()
    player:Say("I hit the table!")
end)


And I can do this for as many hotspots and interactions as i like with no limitation.

That's funny because I've written and used similar systems for AGS. For example, Quasar uses one for the NPC interactions. Maybe I should put that up on the forum as a game template.

Calin Leafshade

As i said, most of what lua can do (with the possible exception of coroutines) AGSscript can also do in a roundabout fashion. But I think the lua version is likely to be cleaner and more intuitive.

Crimson Wizard

Well, personally I have no objections to use this myself (if I'd ever be making my game, that is (roll)).
But I am not sure how easy it would be for scripting beginners to use lua. Also, working on engine with JJS made me concern portability more.

Calin Leafshade

#8
The lua plugin is as portable as any other plugin and lua itself is exceptionally portable so I doubt portability is a concern unless you're talking abotu running it on a toaster or something.

Also, i'd argue that lua is easier for a beginner because it doesnt have some of the weird idiosyncracies of AGSscript (no forward declarations, weird variable casting and so on)

AGA

The main reason people wouldn't want to swap to LUA is that they know AGS already, and any time and effort taken to learn LUA would be unnecessary.  Also, people who are in the middle of one or more game projects would have to start again from scratch.

Technocrat

Quote from: AGA on Mon 24/12/2012 17:11:18
The main reason people wouldn't want to swap to LUA is that they know AGS already, and any time and effort taken to learn LUA would be unnecessary.  Also, people who are in the middle of one or more game projects would have to start again from scratch.

This, 100% this. I'm sticking to AGS while I learn how Unity works, and don't need to have to figure out Lua from scratch as well!

Yeppoh

#11
If the LUA plugin for AGS appeared very early on when I began working on my game, there were high chances I would have used that scripting language. Mostly for coroutines which my game relies a lot. And lots of lots of data management.
I would say I know mastered coroutines with the AGSscript, but I agree looking back at it I would surely use it as a weapon to kill coders with an aneurysm. Also there are a couple of stuff I wanted to code into my game that I didn't, because it was very difficult (read lots of work) to make it run properly while keeping track of everything.

While I can't switch on LUA with my current game, I will surely try out that scripting language on future games. Personally I think I maxed out the possibilities I can do with the AGSscript.

Crimson Wizard

#12
I think few demo games, demonstrating some tasks implemented in lua, would help to a) understand what is it all about, b) compare to AGS script.

IMO, it is not much of problem to learn new syntax, it is usually a time-consuming to learn new ways of making things you made in AGS script before. I mean - learning effective use of a new scripting language.

monkey0506

Quote from: Calin Leafshade on Mon 24/12/2012 14:24:50In terms of actual results, there isnt much that lua can do that AGSscript absolutely can't do but it might be *alot* easier in lua.

I'm not familiar with this British term "alot". Care to clarify for me? :P

Quote from: Calin Leafshade on Mon 24/12/2012 14:24:50Because functions pointers dont exist in lua i had to tie all my interactions to cursor modes to separate them which was messy, made no sense and was stupid.

First of all:

Quote from: Calin Leafshade on Mon 24/12/2012 14:24:50Because functions pointers dont exist in lua

lolwut. :)

Function pointers may not exist in AGS, but that doesn't mean you couldn't set up a custom function to handle the work internally anyway. Your issue of function ordering (which you address later) does come into play, but it's not terribly difficult to do this (although in fairness Lua's function pointers would simplify things via function pointers):

Code: ags
function SomeDelegatedFunction(int param1, int param2)
{
  // ...
}

function OtherDelegatedFunction(int param1)
{
  // ...
}

enum DelegatedFunction
{
  eDelegateSomeDelegatedFunction,
  eDelegateOtherDelegatedFunction
};

function CallDelegatedFunction(DelegatedFunction func, int param1, int param2, int param3, int param4, int param5, int param6) // optionalized in import
{
  if (func == eDelegateSomeDelegatedFunction) SomeDelegatedFunction(param1, param2);
  else if (func == eDelegateOtherDelegatedFunction) OtherDelegatedFunction(param1);
}


Quote from: Calin Leafshade on Mon 24/12/2012 14:24:50Another example is that I can add arbitrary values to ags objects at runtime. Let's say my NPC had a 'suspicion' level and when it reached 100 he found me out in my misdeeds or whatever.
In ags I would store this in a different variable. If i had one for each npc I would store it in an array somewhere probably. In lua i can simply type:

Code: lua

    ags.cNPC.Suspicion = 50


And it's done, it's all in the same object and it makes semantic sense.

While it may make semantic sense in Lua, many would argue that this creates more pitfalls than the potential benefit. What happens if I mistype "Suspicion" as "suspicion" or "Suspcion"? I've inadvertently created an entirely separate variable which, at a glance, may not be readily apparent. I would actually advocate taking the idea of AGScript's extender methods further by allowing static extender methods and member extenders (via accessors, which AGS is already using internally anyway, so the precedent is already set). Of course it's an open matter of debate and preference here, but the fact that AGScript doesn't allow undeclared extensions is a feature IMO, not a drawback.

Quote from: Calin Leafshade on Mon 24/12/2012 14:24:50Also, all lua function and variables do NOT have to be declared before use. In AGS it's impossible to organise nice systems that depend on one another. Say you have a Camera struct and a Map struct and the camera wants to interact with the map but the map also needs to know where the camera is. This is impossible because AGS has no system for forward declaration which means your code has to be messy and shitty.

This is just blatantly false. AGS has a well defined mechanic for forward declaring a struct (case in point: GUIControl and its child types). To be fair though, an undefined (but declared) struct is only useful for defining pointers, and AGScript doesn't allow pointers to user-defined types. So instead of pouring filthy misrepresentations of AGScript, I feel that perhaps the pointer mechanic it already includes should be extended to allow pointers to user-defined types. Even if you could only define pointers to "managed" types (meaning it uses the AGS "managed" keyword) with a static Create and member Destroy method, that would give all the functionality you'd need.

Quote from: Calin Leafshade on Mon 24/12/2012 14:24:50Reason 4 or 5 or whatever i'm on is that Lua is an established language with a lot of resources available. If you want code to do some pathfinding then there are dozens of Lua scripts already available in nice little modules.

Lua has a couple of plugins for oft-requested ags functions including TCP/IP.

These are actually good rationales for using Lua, but that doesn't preclude replacing AGScript with Lua altogether.

Quote from: Calin Leafshade on Mon 24/12/2012 14:24:50Lua has coroutines which I've use in my RPG engine to have a custom say function which isn't hashed together bollocks like is required with ags and a million if/elses in repex.

I'm not sure if you mean to indicate extender methods as "hashed together bollocks" or you instead meant a "from scratch" function which doesn't use the built-in Character.Say or Character.SayBackground methods. In any case, I know for a fact that AGS can't handle a million else clauses, but I've never tried a million separate if statements (or a combination thereof summing up to a million). Oh wait, that was a hyperbole? Must have been your British accent causing the confusion. :P Still, I've personally written dozens of custom say functions (both with and without the use of the built-in methods) and I would be hard pressed to refer to the experience as "hashed together bollocks". Then again, I've never seriously looked into coroutines, so I can't much speak on how Lua might make it easier.

Quote from: Calin Leafshade on Mon 24/12/2012 14:24:50Speaking of my RPG engine, I've managed to make an (almost) fully working RPG system with a nice inventory and map system in lua and it took me a few days max. Something no one else has done (to my knowledge) in AGS for a long time.

I would say challenge accepted if I weren't so bloody apathetic at this point. The only reason I'm posting this is because you, Calin, have a dirty habit of spreading lies about AGScript and it disgusts me. :D

Quote from: Calin Leafshade on Mon 24/12/2012 14:24:50Lua will allow module makers to make more intuitive modules because we can have classes and inheritance and events and function pointers.

AGScript already allows module writers to use classes and inheritance. I've already addressed that function pointers aren't inconceivably difficult to work around. As for events, it's true that AGS doesn't have a separate construct for user-defined events, but in the end wouldn't that just be syntactic sugar for an if-statement inside of repeatedly_execute? What's more, since the module can have its own rep_ex, it's not like it would even have to contend with the code from other modules - many of my modules have their own rep_ex with just a few lines.

Quote from: Calin Leafshade on Mon 24/12/2012 14:24:50AGS teaches you a worthless skill badly.

I see nothing worthless in learning the basic principles of programming. Just because it's a separate language doesn't mean it is wrong. With the plethora of languages that exist, AGScript makes it easy for someone with any level of programming experience to make adventure games - which, by the way, is what AGS is designed for. :P

Quote from: Calin Leafshade on Mon 24/12/2012 14:24:50AGS script is basically like C but with all the good bits missing and what this does (in my opinion) is teach you to be a poor programmer. You don't learn in terms of data structures because in AGS working with data structures is a chore. Not being able to pass structs either by value or by reference is a *massive* problem when it comes to teaching people how to code. Also, AGS script is only used in AGS. You might as well learn Lua and have another skill to add to your repetoir.

I agree that learning a mainstream language may have more real-world benefit than learning a proprietary one. I am a living testament to this. However, I feel that you are extremely poorly educated and excessively critical in terms of AGScript. The one change of being able to define pointers to user-defined types (even with stipulation) would fit your every requirement for making the user-side of AGScript more object-oriented. I will admit that this is a valid point when scripting more advanced features, but only in terms of OO languages. There are still many non-OO languages that are highly popular.

As for function pointers (coming back to that), you yourself wrote a plugin that exposed a way to dynamically link functions in AGS. By your own admission the plugin was a simple task - exposing this directly to the engine itself would be trivial. Most of "the good bits" that you claim AGScript has removed are there in some fashion. It would require changes to the engine to include the functionality that you are seeking. The relatively few number of changes that would need to be made to add these features though, to me that stands as all the more justification for not scrapping AGScript.

Quote from: Calin Leafshade on Mon 24/12/2012 14:24:50(And this before i've even mentioned the magic of tables)

My very primitive understanding of tables in Lua is that they're basically the Lua equivalent of a struct or class (the ability to add members simply by referencing them is an inherent part of the Lua language itself). The meta table in so far as I can tell would be comparable to overloading operators and such.

All in all, I'm not saying that AGScript is better than Lua (or vice versa), I'm just making a point that AGScript isn't the wretched creature everyone tries to make it out to be. Honestly, I feel that both should be an option, and more should options should be added. I do not feel that AGScript should be removed any time in the near future however, because it does have a relatively low learning curve, and it is far more capable than many would like to assume.

ddq

I'm sure there's a shorter way to say "I'm a pedantic prick".

monkey0506

No, I checked. There's not.

Calin Leafshade

A lot of your criticism of my argument is pendantry at best and just lying at worst.

To argue that AGS can support some kind of function pointer functionality by coding a big if else block to run different funtions based on an enum is laughable. I mean do you even understand what a function pointer is and why they are useful?

Your argument for predefined variables is one of language semantics and could go either way depending on your stance on such things. For a scripting language I'd argue that dynamic, non-typed variables are better but opinions vary.

On writing intuitive modules:

Are you suggesting that, with the function pointer example (maybe an event of some kind), it is better and neater to tell your user to add a new value to an enum in your code, create a new function higher up in the script and add calling the function to the module code? As opposed to just telling them to pass a function? If so then lol.

On a custom say function: What if i don't want it to be blocking? What if i want the user to be able to answer yes or no to a question? In Lua (it's not an abbriviation by the way while we're being pedants) coroutines allow you to essentially have a kind of threaded system.

Code: lua

    player:MyCustomSay("Hi!")
    if player:Ask("Are you a pedant", "Yes", "No") == "Yes" then
        player:MyCustomSay("You are a pedant")
    end


Now, I have no doubt that such a system is perfectly possible in AGS but it wouldn't be as pretty and you couldn't make it non-blocking because AGS only has a single scripting thread and no coroutines.

AGS Script was a great idea 10 years ago. Computers weren't fast enough to have a JIT compiled scripting language and a pre compiled option was a good idea but now it's obsolete. Let's look at the things AGSScript doesn't have that lua does.

dynamic, multi dimensional arrays
function pointers
ternary ops
for loops
dynamically typed variables (you don't get tired of IntToFloat?)
keyed arrays
*proper* forward definition
functions as first-class citizens
the ability to pass data structures (seriously lol)

I could go on.

Quote
These are actually good rationales for using Lua, but that doesn't preclude replacing AGScript with Lua altogether.

Look up 'preclude'.

ThreeOhFour

For a stock-standard adventure game, I can't think of anything I'd want to do that is actually difficult in AGS script, or overly messy, to be honest.

I've been writing in AGS script for years, and it's not that I feel that another style of coding would be less efficient, it's that I feel that I as the designer would be less efficient at using the script. It's hard to be bothered to move over to another style of scripting when I know I can do pretty much anything I want in AGS script and more importantly, I already understand how.

In saying that, your custom say function looks interesting. This is something that would maybe convince me to move over, because it's a practical, and instantly obvious with how it is easier to use.

But yeah, it's hard to want to learn new stuff when I can already make the games I want to make with the stuff I already know. I think you need to illustrate your point in a more compelling light - perhaps create a quick example game script which illustrates the simplicity and functionality you are trying to promote.

Crimson Wizard

#18
Of all the things being said above,

This:
Quote from: monkey_05_06 on Tue 25/12/2012 02:51:23
Quote from: Calin Leafshade on Mon 24/12/2012 14:24:50Another example is that I can add arbitrary values to ags objects at runtime. Let's say my NPC had a 'suspicion' level and when it reached 100 he found me out in my misdeeds or whatever.
In ags I would store this in a different variable. If i had one for each npc I would store it in an array somewhere probably. In lua i can simply type:

Code: lua

    ags.cNPC.Suspicion = 50


And it's done, it's all in the same object and it makes semantic sense.

While it may make semantic sense in Lua, many would argue that this creates more pitfalls than the potential benefit. What happens if I mistype "Suspicion" as "suspicion" or "Suspcion"?
was my concern too. Actually I found this behavior unacceptable, and if there would be some kind of "switch" to disable it in lua, I'd set it by default.
It would be more convenient, if Lua just allowed to define new variables in certain place. Maybe it does?

The AGSScript-way of implementing "function pointers" is just terrible, though. Same about user events... The whole idea of computers is automatization of human work, and sticking to such constructions doesn't do any good.

Quote from: Calin Leafshade on Mon 24/12/2012 14:24:50
On a custom say function: What if i don't want it to be blocking? What if i want the user to be able to answer yes or no to a question? In Lua (it's not an abbriviation by the way while we're being pedants) coroutines allow you to essentially have a kind of threaded system.
<...>
Now, I have no doubt that such a system is perfectly possible in AGS but it wouldn't be as pretty and you couldn't make it non-blocking because AGS only has a single scripting thread and no coroutines.
Now. That's simply not true. I can make a non-blocking custom say function in AGSScript, since AGSScript has repeatedly_execute functions it is possible to organize a classic state machine there. The fact that it has only one thread means only organizational problem (but so does multi-threading). To be frank, I found this statement quite naive... not to offend you, Calin, but how do you suppose any program could run any number of simultaneous tasks having one thread? Such things are, of course, possible and valid.

Quote from: Calin Leafshade on Mon 24/12/2012 14:24:50
AGS Script was a great idea 10 years ago. Computers weren't fast enough to have a JIT compiled scripting language and a pre compiled option was a good idea but now it's obsolete.
I was rewriting AGS script interpreter, making it a more type-safe along the way, and recently a user of PSP port reported that certain game became quite slow because of that. And this is still precompiled AGS script.
I don't want to make any assumptions here, but it would be good to know how fast Lua actually works when handling lots of scripting tasks.
(There's of course such thing as optimization. The problem I mentioned may be related to the way AGSScript handles basic operations)


In any case it would be interesting to compare benefits of using Lua (or other script language) and developing AGSScript further. But I am afraid this gets beyond the topic.
Using fully developed language is a huge benefit on its own. And to be honest, the monkey_05_06's position looks like defending something only because he got used to it, or devoted a lot of time for it.

Calin Leafshade

#19
Quote from: Crimson Wizard on Tue 25/12/2012 08:06:20
Quote from: Calin Leafshade on Mon 24/12/2012 14:24:50
On a custom say function: What if i don't want it to be blocking? What if i want the user to be able to answer yes or no to a question? In Lua (it's not an abbriviation by the way while we're being pedants) coroutines allow you to essentially have a kind of threaded system.
<...>
Now, I have no doubt that such a system is perfectly possible in AGS but it wouldn't be as pretty and you couldn't make it non-blocking because AGS only has a single scripting thread and no coroutines.
Now. That's simply not true. I can make a non-blocking custom say function in AGSScript, since AGSScript has repeatedly_execute functions it is possible to organize a classic state machine there. The fact that it has only one thread means only organizational problem (but so does multi-threading). To be frank, I found this statement quite naive... not to offend you, Calin, but how do you suppose any program could run any number of simultaneous tasks having one thread? Such things are, of course, possible and valid.

Not naive, factual.

Certainly you *could* cobble together a non-blocking say function but how would you chain calls in an easy way?

For instance:

Code: ags

    player.CustomNonBlockingSay("Hi There!");
    player.CustomNonBlockingSay("Uh oh.. this function has run immediately after the preceding one...");
    player.CustomNonBlockingSay("Oh no! Now i've missed two say functions because the function kept running!");


Lua avoids this problem with coroutines.

Quote
Quote from: Calin Leafshade on Mon 24/12/2012 14:24:50
AGS Script was a great idea 10 years ago. Computers weren't fast enough to have a JIT compiled scripting language and a pre compiled option was a good idea but now it's obsolete.
I was rewriting AGS script interpreter, making it a more type-safe along the way, and recently a user of PSP port reported that certain game became quite slow because of that. And this is still precompiled AGS script.
I don't want to make any assumptions here, but it would be good to know how fast Lua actually works when handling lots of scripting tasks.
(There's of course such thing as optimization. The problem I mentioned may be related to the way AGSScript handles basic operations)

My preliminary findings suggest that Lua is faster than AGS Script when doing pure arithmetic and stuff that is confined within the Lua universe (string operations and so forth).
It is slower than AGS when accessing AGS functions because of all the interop stuff going on.

EDIT:

I should point out that coroutines are not actually threads in the traditional sense. They are just a way of having parallel functions running in a single threaded environment like a scripting thread.

SMF spam blocked by CleanTalk