But if I keep beating it, it's bound to move sometime... (Reference types)

Started by monkey0506, Thu 15/08/2013 13:59:49

Previous topic - Next topic

monkey0506

Call it what you will, but AGS needs proper reference types. We need to be able to pass them as parameters to our functions and return them, we need to be able to store them inside of other structs, we need to be able to create dynamic arrays of them. This is not a question of whether we should abandon AGScript, and if it turns into a debate about it I swear I'll make the mods lock it... (laugh) (roll)

Really though, it's not just about the suggestion either though. We've heard it, we've seen it, we've been through it, and we're still right where we are. So, if I'm not just whining, what the hell am I posting for?

I want people to read this. I want them to understand it. I want them to understand that it's not as good or as easy to implement as proper reference types, but I want them to come to realize that once implemented it is in every way as functional as proper reference types would be (down to a few CPU clock cycles, but the function overhead might balance out against the actual dereferencing, I dunno). I want people to know that this is possible to achieve. The core implementation is bulky, I'll give you that, but the people who really need it are the ones designing RPGs and FPSes and RTSes in AGS anyway. Their code is already bulky. And I'd wager that whatever method they've come up with to workaround the issue that doesn't do exactly this is either at least as bulky (if not more) or it is significantly less efficient (or more probably both).

I want to have an intelligent and open discussion about it. Not a debate about whether AGScript is crap. Not read through two dozen people posting, "but it's still a workaround". But an actual discussion. So... Anybody willing to take a look? I mean, it can't be worse than what you're already doing anyway. And it doesn't involve putting everything into strings.

[/totally shameless plug]

Ghost

Quote from: monkey_05_06 on Thu 15/08/2013 13:59:49
Call it what you will, but AGS needs proper reference types. We need to be able to pass them as parameters to our functions and return them, we need to be able to store them inside of other structs, we need to be able to create dynamic arrays of them.

Agreed, absolutely. I read your implementation and it is bulky, but it should be very useful- not just for RPG/RTS games but a lot of "unusual game concepts" (cards and whatnot). And it seems that these days there is a high demand for proper reference types. They are useful and it would be awesome to have some sort of "meta-object" to create instances of, and that could then become an integer or string or whatnot.

I would really like to see that implemented into AGS at some point. It would be a great step towards flexibility and it would remove the need for workarounds that apparently are used so often that they become "common knowledge".

Being more an AGS user than a programmer, however, I don't know how soon someone will get around to implementing the chances. It sounds like a radical change (but I could be wrong).

Calin Leafshade


monkey0506

What's always been kind of funny to me, Calin, is that by-and-large I don't disagree with you. Swapping out AGScript with an existing fully-fledged programming language would solve this and a dozen other problems. There are two particular points where I do have issue.

1) Your attitude. Whether you actually think/believe/feel this way or not, you have given me every impression (and I would be very hard-pressed to be persuaded otherwise at this point) that you believe CJ made a mistake in crafting AGScript in the first place.

2) Your attitude. You have additionally given me the impression that you don't have the slightest recollection of what it's like to know nothing about programming. Your arguments in favor of replacing AGScript have supported this idea (that is, they've done little to nothing to reconcile with those who would be the most impacted).

I am of the opinion that Chris Jones knew what he was doing when he decided to create his own programming language. Admittedly, the entire AGS program was something he cooked up for fun primarily, but I still hold that he understood the views of the non-programmer. Most programming languages have a very steep initial learning curve. A lot of this is attributed to learning basic programming fundamentals that apply to (virtually) every language, but some concepts that are at the very core of these languages bring little to nothing to the average AGS user's adventure game designing experience. AGScript has a significantly lowered learning curve for the everyday user, and it is my belief that this is not a happy accident, but is by design.

At this point asking you not to voice your opinion or refute what I've said would be a rather obscene gesture. I will ask that you please try to respect that I have already expressed a desire to avoid debating this here. By that I mean to ask that you don't try to turn this into another evangelical moment for Lua. I understand and respect that Lua is a good language in its own right, but I remain adamant that replacing AGScript would be more harmful to the less experienced programmers than the benefits you would hope to gain. I bear no opposition to built-in alternatives that could be swapped (or even co-mingled?) at the user's discretion.




That being said, I'm interested in further developing with this method. I'm considering building an RPG framework. Are there any recent tutorials or open-sourced games that have utilized an RPG system? I know the basic stats and the like, but I'm also interested in seeing how others have coped with this particular issue. One thing that came to mind is that you could additionally use AGS' forward declaration system on the Reference pseudo-types. It's probably meaningless, but it could be useful if you have a complex structure but want to keep things organized (e.g., forward declare the SpellReference type in a CharacterStats script (and provide #defines as appropriate) while leaving the definition of SpellReference in the Spell script).

Calin Leafshade

I have already responded to most of the falsehoods you mention here so I won't do so again but I don't think I have mentioned this so I will respond.

Quote from: monkey_05_06 on Fri 16/08/2013 06:11:45
AGScript has a significantly lowered learning curve for the everyday user, and it is my belief that this is not a happy accident, but is by design.

While I totally respect your opinion and your right to make it I do not believe this to be the case.

AGS script has quite a steep learning curve in my opinion. I will offer some examples

Script headers
Having to import/export and declare functions/variables adds a layer of complexity that the vast majority of scripting languages simply don't have. Is it necessary from a design perspective? Why would including something that appears quite arcane to a new user (I speak from experience) be a good thing and lower the barrier of entry.

Strongly typed variables
My major problem here is the int/float situation. Was that a good idea from a design perspective? Why not just a "number" type like most scripting languages?

Pointers
Pointers are a *low level* concept. Is it really necessary to include pointer notation? I don't know of any scripting languages that do. It seems an unnecessary layer of complication.

There are more but I feel those are enough.

You say that I have "given [you] the impression that you don't have the slightest recollection of what it's like to know nothing about programming." but it seems to me that you are the one who is guilty of this. You assume that these complications are trivial to new users but I propose that they are not.

As for your attempted solution, I actually think it's ok. It seems solid, if a little convoluted.
I would say that your talents would probably be better spent trying to add byref passing to the language at a lower level but that is only my opinion.

However, I would like to hear your thoughts on why you believe AGSscript to be well designed, especially for new users because, to be honest, every time I examine this all I see are *bad* design decisions for a scripting language.
Of course, I imagine this is mostly due to AGS's quite significant age.

monkey0506

Quote from: Calin Leafshade on Fri 16/08/2013 06:56:22Script headers
Having to import/export and declare functions/variables adds a layer of complexity that the vast majority of scripting languages simply don't have. Is it necessary from a design perspective? Why would including something that appears quite arcane to a new user (I speak from experience) be a good thing and lower the barrier of entry.

Well importing and exporting variables is now partially deprecated anyway and serves as an advanced feature for users with global struct instances. Anything else (variables) that is global should go in the Global Variables pane.

Importing functions is reminiscent of forward declaration in C++. And imports don't have to appear in the script header, for example if you just want to use them to default an argument. The purpose of the script header itself again is similar to header files in C++ (without the necessity to include them, as they are automatically included in every subsequent script file). It's true that this method then does nothing little to lower the barrier of entry against C++. I'll grant you that many people don't even know how to use script headers properly (like when I see module authors actually defining things (other than structs or enums) in the headers). So while removing them may lower the barrier of entry, it would also pose significant problems to advanced users if they were removed.

If everything suddenly became global then module authors would no longer be able to use internal structures in the way they can now. Clearly some rethinking would have to be done, and perhaps adding a global keyword would be sufficient? I never meant to indicate the current system is perfect, and I support making improvements to what's already there. This could perhaps be a good point to look into.

Quote from: Calin Leafshade on Fri 16/08/2013 06:56:22Strongly typed variables
My major problem here is the int/float situation. Was that a good idea from a design perspective? Why not just a "number" type like most scripting languages?

Off the top of my head, C++, C#, and PHP all have strongly typed numbers. Obviously PHP has a loosely typed variable system altogether, but there are still separate and distinct strong backing types that require conversion to cast between them. All three of these languages have floor and ceil functions. C++ (prior to C++11) doesn't (didn't) even have a round function because there's different interpretations of what would be the "proper" rounding method. Of course in all three languages even after calling the relevant floor/round/ceil method, you still have to cast (C++ and C#) or call intval (PHP) to get the actual integer value out of it as all three of the earlier methods return decimal values. The way that AGS handles this is pretty much on-par, except I think they generally have an implicit IntToFloat conversion.

Quote from: Calin Leafshade on Fri 16/08/2013 06:56:22Pointers
Pointers are a *low level* concept. Is it really necessary to include pointer notation? I don't know of any scripting languages that do. It seems an unnecessary layer of complication.

Despite calling them pointers, what's actually been implemented is references anyway. The whole reason CJ implemented them (insofar as I can tell) is because up to that point AGScript had nothing along the lines of a reference type whatsoever. He wanted to give a distinction to show that you are not creating new instances, but just referencing what is already there. Was a separate notation strictly necessary, probably not. The String type, for example, is a reference type without the notation, but it's also immutable. I think it would actually be useful if AGS did have a distinction between reference types and value types in the way that C# handles it. int (char, short, and the confusingly useless to AGS long) and float would be value types, the managed structs would all be reference types. Implementing a mechanic to allow structs to be passed through functions by-value and adding a separate class keyword for reference types would require a lot of work, but it would solve numerous problems.

I still maintain that just because AGScript is missing some features (and there are admittedly some things that warrant changing) doesn't mean that it warrants total replacement.

Calin Leafshade

Quote from: Calin Leafshade on Fri 16/08/2013 06:56:22
However, I would like to hear your thoughts on why you believe AGSscript to be well designed, especially for new users because, to be honest, every time I examine this all I see are *bad* design decisions for a scripting language.

Would you respond to this? I am genuinely interested.

ThreeOhFour

Quote from: Calin
Quote from: monkey_05_06 on Fri 16/08/2013 06:11:45
AGScript has a significantly lowered learning curve for the everyday user, and it is my belief that this is not a happy accident, but is by design.

While I totally respect your opinion and your right to make it I do not believe this to be the case.

AGS script has quite a steep learning curve in my opinion. I will offer some examples

The everyday user probably chose AGS because they want to make an adventure game with walking, talking and picking up items, all of which AGS makes very easy to do.

Not trying to show an opinion, but for people who want an adventure game engine for creating an adventure game, AGS's learning curve is quite delightfully low.

monkey0506

Quote from: Calin Leafshade on Fri 16/08/2013 21:24:16
Quote from: Calin Leafshade on Fri 16/08/2013 06:56:22
However, I would like to hear your thoughts on why you believe AGSscript to be well designed, especially for new users because, to be honest, every time I examine this all I see are *bad* design decisions for a scripting language.

Would you respond to this? I am genuinely interested.

I wasn't strictly trying to avoid responding to this directly, but I felt that my post kind of spoke for itself. As far as bad design choices, I disagree. I would rather contend that AGScript is simply underdeveloped, not developed in a bad way.

Regarding script headers, that is not actually part of the scripting language, but was added as a means of allowing globals. I already stated that this mechanic is imperfect, and I suggested that perhaps a global keyword added to the language specification could do away with the need for not only script headers, but also the need to import or export anything. import/export are quite similar in many ways to C++'s extern in their own right, and I do not view them as a bad design choice, but I feel that the introduction of a global keyword would be a more user-friendly mechanic and deprecate their usage entirely.

As to floating-point numbers vs. integers, I've already explained that (despite your claim about "most languages" having a unified number type) this is in-line with several other languages. I don't think that this poses a significant barrier to the language, as most people are able to comprehend that int is for whole numbers, float is for decimals. Again, I don't see this as a bad design choice.

I actually conceded that using pointer notation for what ultimately is (nullable) reference types was probably not necessary. I'll even go so far as to say that this was a bad design choice. I'm not sure why CJ chose to call them (and in some instances make them look like) pointers, aside from the fact that they are nullable. Then again, C# reference types are also nullable and don't use any distinct syntax (class vs. struct, obviously) (except in the case if you want to reassign the reference on a specific function argument then you pass that using the ref keyword). This is something that I do feel warrants being redesigned, and preferably including user-defined types as well. If I'm not mistaken, the changes that Crimson Wizard is currently making to the engine plugin API would actually make this redesign much simpler (although, I'm not certain I understand it well enough to make that assertion).

I never said that AGScript is perfect, but for the most part I don't see it as being plagued by bad design choices. I think this is probably a lot more at the root of your concerns. You feel that the bad design choices outweigh the good, so it would be better to start from scratch, and in that case, why not just use something that's already been established. Am I right? If that is how you feel, I still differ in opinion, but I respect yours more out of understanding.

Quote from: ThreeOhFour on Sat 17/08/2013 06:02:07AGS's learning curve is quite delightfully low.

Coming from someone I personally tutored in AGScript (and programming in general), I find this statement quite delightful. :D

Calin Leafshade

Two quick points:

I said that AGS *Script* has a steepish learning curves. Not AGS which I admit is easy to use generally.

I said that most *scripting* languages don't have float and int distinction.

RickJ

Nice work monkey.

;) Ironically the lack of pointers, the subject of the this post, is one of the things that makes AGS easy for beginners. 

Of course one could argue, and I certainly would, that pointer support would make "easier to use modules" with "beginner features" possible.  All these years I have been pining for function pointers. 

Here is an interesting article related to this discussion.  It's mostly the author's (I'm not the author) opinions but he makes some interesting points.
http://www.tcl.tk/doc/scripting.html

Enjoy

Wyz

Interesting little discussion going on here! :) But in spirit of the first post I will not talk about how I'd like things to be ideally. What we need is a feasible solution which causes a reasonable enough improvement on scripting quality. Also in spirit of the first post I'll not mention the option to switch scripting languages.

Let's first look at AGS Script in its current form. We can see it evolved along with AGS, something that has been a natural process during the past decade or so. AGS Script is clearly inspired on C (not C++) which is something that still shows pretty much in today's version. When object orientated programming became popular CJ chose to add this in his own way to AGS. The way it works is very similar to shared-pointers in C++ yet it only works for managed objects (plugin and built-in objects). Dynamic arrays are the only form of dynamic memory the script language itself has access to. There are also limitations as it comes to using structs: where languages as C would allow structs to be in functions parameters and be part of other structs, AGS Script does not support this.

For general usage this is all pretty much sufficient if you ask me: I've worked with AGS Script for a while now and only ever I find its limitations when I'm working on generic modules. There are two limitations in special that are making it hard for me; one of them is something a more flexible reference type sort of thing would be able to solve. But I have to emphasise it is more useful to see how we could achieve this using what we have now other then drastically changing AGS Script; since if that would be the case I'd suggest something that would monkey have this topic closed if I'd mentioned it. ;)

Suggestion:
So AGS Script is inspired by C and uses 'shared-pointers' for managed objects. We can use the plugin API to create the dynamic allocated structures in all ways we could possible ever want. Let's extend this possibility to AGS Script. So assume we have a structure:
Code: AGS

struct Coord
{
  int X;
  int Y;
};


Now we would be able to use it just as the built-in objects:
Code: AGS

Coord *Foo(Coord *c1, Coord *c2)
{
  Coord c;
  c.X = c1.X + c2.X;
  c.Y = c1.Y + c2.Y;
  return c;
}


So this will look weird from a C++ perspective but let me elaborate:
The pointers are shared-pointers which make sure that the object it points to exists until the last pointer referring to it is deleted. The local variable c will be returned, but when this variable goes out of scope it will actually not be deleted since the function returns a shared-pointer pointing to this variable.
I know that pointers are not the best option if it comes to user-friendliness but this will mostly be used by modules and something the generic user doesn't have to mess with. Yet it will work the same as the already existing built-in objects so it is consistent.

When you need functionality like a constructor you can do something like this (out of the box):
Code: AGS

static Coord *Coord::Create(int X, int Y)
{
  Coord c;
  c.X = X;
  c.Y = Y;
  return c;
}

Coord *Foo(Coord *c1, Coord *c2)
{
  return Coord.Create(c1.X + c2.X, c1.Y + c2.Y);
}


Usage in other structs will also be working out of the box:
Code: AGS

struct Box
{
  Coord *position;
  Coord *size;
};


Of course the developer now needs to make sure the pointers are not null, or have a 'constructor' function that initializes them, but that is just a minor thing if you ask me. Something also generally only modules developers need to fuzz about.

I also wanted to mention the second limitation that is holding me back sometimes but since this post is already ridiculously long I'll let that one go for now.

Edit: fixed script examples
Life is like an adventure without the pixel hunts.

monkey0506

Quote from: Wyz on Sun 18/08/2013 01:57:41But in spirit of the first post I will not talk about how I'd like things to be ideally...Also in spirit of the first post I'll not mention the option to switch scripting languages.

Are they different things? The "also" seems to indicate that your ideal isn't (necessarily) just replacing AGScript altogether. I'm not trying to stifle people having opinions, I just don't want to "discuss" (read as: argue) about whether AGScript should be tossed. If that's your opinion, fine, but you're not going to change mine.

Quote from: Wyz on Sun 18/08/2013 01:57:41
Code: AGS

Coord *function Foo(Coord *c1, Coord *c2)
{
  Coord c;
  c.X = c1.X + c2.X;
  c.Y = c1.Y + c2.Y;
  return c;
}

Obviously the duplicate return type is erroneous (function is just a #define int with some a provision to allow a void return). ;)

Quote from: Wyz on Sun 18/08/2013 01:57:41So this will look weird from a C++ perspective but let me elaborate:
The pointers are shared-pointers which make sure that the object it points to exists until the last pointer referring to it is deleted. The local variable c will be returned, but when this variable goes out of scope it will actually not be deleted since the function returns a shared-pointer pointing to this variable.
I know that pointers are not the best option if it comes to user-friendliness but this will mostly be used by modules and something the generic user doesn't have to mess with. Yet it will work the same as the already existing built-in objects so it is consistent.

I'd actually argue that refining it to what it really is (nullable references with automatic garbage collection) and ditching the pointer syntax altogether would be better. That would be (significantly) more work, so perhaps allowing these pseudo-pointers to the user would be a good middle-ground in the mean time.

Quote from: Wyz on Sun 18/08/2013 01:57:41Of course the developer now needs to make sure the pointers are not null, or have a 'constructor' function that initializes them, but that is just a minor thing if you ask me. Something also generally only modules developers need to fuzz about.

Granted, the majority of cases where this actually becomes an issue is for module authors or people building non-adventure games anyway. Which is why I wanted to create the bit of extra publicity about this particular workaround method, because I've never seen anyone use it. Ultimately it's how memory allocation works anyway. I mean, it would be more like a linked list than an array, but other than that the basic principle still follows.

I would really like to be able to say that this could be implemented in a more generic fashion, but AGS's pseudo-polymorphic abilities fall short in a detrimental way (base class references don't can't call the child class overloads). There's simply not a way to have the base class handle creating the members in the cache. So, it's a bulky workaround to a problem that should be addressed internally, but as far as I see it, it's the best we've got for now (and the end-user code is near-exactly identical in terms of functionality).

Quote from: Wyz on Sun 18/08/2013 01:57:41I also wanted to mention the second limitation that is holding me back sometimes but since this post is already ridiculously long I'll let that one go for now.

What limitation would that be?

Wyz

Well my opinion about ditching AGS Script is not formed by my ideals but rather by what I'd think would be good for the community. If people all of a sudden need to learn a completely new language to use the program they love is not really a good idea. It is the kind of thing that makes people cling to old versions or leave it all together. So in favour of that I don't think it is wise to toss AGS Script.

Other then the amount of work the second reason why I wouldn't remove pointers is that this solution would be 100% backwards compatible. It has the added bonus that old modules and games in progress will still work with that system but new games and modules can make use of the more flexible sides of the system. At some point you'd need to break backwards-compatibility but I don't think now is the time.

Minor detail: Garbage collection and shared-pointers are different beasts. A shared-pointer will delete the resource as soon as the resource counter hits null, so the minute none of the pointers is referencing it. A garbage collector will check for deletable resource periodically (in a separate thread or at a certain point in the game loop) and deletes them in one go. I guess shared-pointer will be the least work to implement so I'd go for that.

I'll come back to you about the second issue tonightmorrow.
Life is like an adventure without the pixel hunts.

Wyz

The second issue is actually related to the import/export system. Actually personally I don't really mind this system but it has one limitation that I can't really work around. AGS Script has an one pass compiler meaning that functions should be defined before used. This also goes for modules: they need to be above the ones using it in the module list. This makes it impossible to have module A call functions from module B when module B also calls functions from module A. It's a classic painter's algorithm flaw and the only way to work around it is to split op one of the modules and sandwich the other in it.

Another problem that I encounter very often when developing modules is the lack of a way to have a module call user defined functions. For instance I made an IRC module a while back and let's say a message arrives. In that case I want another module to do something with that message like displaying it in a chatbox. A way of doing it would be importing a certain function that the user of the IRC module have to define. But because of the one pass compiler this function needs to be defined in a module above the IRC module. This however would make it impossible to have this user defined function call functions from the IRC module (like automatically returning a message or something).

Suggestion:
Changing the compiler to a two pass system would be a solution (and a necessity) but I'd like to take this one step further. I'd love an event system of some sort. There are many of ways in which this can be done; I'll give a few that come to mind.

A solution would be an import system with a fallback. The fallback makes sure that when the user actually did not define the function we won't get a compiler error but instead we can bail out.
Code: AGS

try_import void MessageReceived(String msg, String chan);

void MessageReceived(String msg, String chan)
{
  // No user defined function found, probably do nothing
}

void Process(String data)
{
  ...
  MessageReceived(msg, chan);
  ...
}


A second solution would be allowing functions to be called by name. This is how things work in plugins-land; a method which can be used to fake an event system for plugins.

Code: AGS

void Process(String data)
{
  ...
  if (FunctionDefined("MessageReceived"))
    CallFunction("MessageReceived", msg, chan);
  ...
}


A third way would be a full fledged event system which will looks something like this:
Code: AGS

// Header
event MessageReceived(String msg, String chan); // The event keyword acts as a special import directive

// Script
void Process(String data)
{
  ...
  MessageReceived(msg, chan);
  ...
}

// Script module 1
void MessageReceived(String msg, String chan)
{
  if (chan == chatbox.channel)
    chatbox.Add(msg);
}

// Script module 2
void MessageReceived(String msg, String chan)
{
	if (roomname == chan)
  	cAnnouncer.Say(msg)
}


There are many more methods I guess. The first method is the easiest to implement I think but lacks making the intentions of usage clear to the users of the module in the header file (which is where header files are for to begin with). It also has a slight overhead because the fallback function will be called regardless, even if it is an empty function.

The second way is rather quirky but since the necessary functions already exist still pretty easy to implement. It however adds a lot of processing at run time (where the first solution does this mainly at compile time) since it needs to resolve the name every time and probably also needs to see if the given variables are of the right type. Same as the first solution it lacks showing modules users clearly how it should be used. It is quirky to say the least.

The third way might not be so easy to implement but has some advantages. Firstly it does have a way in the header file to express module users what events are handed to them and what they should look like. It allows the module developer to use the event without worrying if it will ever be used. The biggest advantage is that multiple modules can use the event! This makes the event system effectively a many-to-many system. This system can also be async-ish where events are queued and we don't have to wait handling all the events first when raising them. There is however a downside: this design does not allow return types for events and instead forces them to be void.

A general advantage of an event system is that is makes it possible to define generic events like 'Player collides' and swap the collision module (for instance from a pixel perfect method to a rectangular way) without breaking the rest of the code. Well I can go on and on about this but I think you'll get the gist.
Life is like an adventure without the pixel hunts.

RickJ

Quote
This makes it impossible to have module A call functions from module B when module B also calls functions from module A.
One could argue that this is a good thing in that it keeps undisciplined programmers on the straight and narrow.  Having said that, I must admit, to having had a legitimate need for this on several occasions.

Quote
Another problem that I encounter very often when developing modules is the lack of a way to have a module call user defined functions ...
I absolutely agree.  I think "pointer to function" would be a better solution.  It would make things such as callback functions, which you describe, event systems, jump/vector tables, and more possible.  The solutions you suggest seem to be much more limited IMHO.

I like the idea of looking up objects by a name specified at runtime.  However, if pointers were supported then I would suggest having a function that returns a pointer to the specified object, where the object could be any function, struct, or variable defined within the current scope/execution context. 

Code: AGS

    PointerToObject = GetPointer("SomeObject");


Bottom line is that there is a serious need for proper pointer support.  It would make a lot of issues go away.  Many moons ago CJ mentioned that one of the obstacles was doing the garbage collection.  Poping things in and out of existence (ala C++) is cool to be sure but I would be willing to live without it if that made pointers possible.

Calin Leafshade

These kinds of discussion, as far as I'm concerned, illustrate why a compiling language is a bad choice for a scripting language.

Why should one have to concern oneself with pointers or forward declaration in a high level environment? These things have very good rationales in system programming environments, namely speed and security but it seems absurd to me to force these things onto casual programmers. The idea that one might need to get a function pointer by passing the name of a function as a string to some helper function is just patching a hole that shouldn't be there. I appreciate that we have done this discussion to death at this point and I am very much in a minority but I'm baffled that people think continuing on this programming paradigm is a good idea.


ThreeOhFour

Quote from: monkey_05_06 on Sat 17/08/2013 18:34:59
Quote from: ThreeOhFour on Sat 17/08/2013 06:02:07AGS's learning curve is quite delightfully low.

Coming from someone I personally tutored in AGScript (and programming in general), I find this statement quite delightful. :D

You taught me about arrays and structs, which really has nothing to do with AGS's script at all. ^_^

Monsieur OUXX

Back on topic: implementing references into AGS script would make it much better imo -- then it would give us plenty more time to think about a potential language change, if that ever happens (I'm in favor of it though).

So, it's not "one or the other".
It's: "At first one, then we'll see"

PS: My opinion about AGS script curve not being so smooth: I've been scripting for about 10 years, and I still I hate that import/export bullshit. Every time I need to use them, I can't figure it out myself (just by reading the documentation) -- so, every time, I need to read my older scripts to remember how I made it work, or I need to spend 30 minutes doing trial and error. Every. Single. Time.
 

SMF spam blocked by CleanTalk