Improving The AGS Scripting Language

Started by Calin Leafshade, Mon 04/06/2012 19:36:52

Previous topic - Next topic

Calin Leafshade

Morning gents,

So AGS.Native has been around for a few weeks now and I've spent a few hours going through the compiler.

I'll be honest and say i don't really understand a lot of it due to all the assembly required but I think we should make a conscious effort now to improve the scripting language.

I think we should start by adding the ability to reference custom structs and pass them as parameters. This addition would essentially make AGS capable of creating full (read useful) OOP constructs.

Does anyone have any insight on how hard this would be? AGS can already create managed objects and already has a pool for them since they can be created using plugins so it seems like there isnt that much more to do.

Any thoughts?

Alan v.Drake

I don't have enough time to help but I'll cheer you on.


- Alan

monkey0506

The biggest reason that CJ ever stated for not doing this was simply that the save game files could possibly become invalidated...but I see no difference between custom struct pointers and managed struct pointers in this case when save games can reference static custom struct instances just fine...

I think it simply was never enough of a priority, because there are SEVERAL ways of accomplishing the same end-result. It would certainly make design-time better for programmers though (rewrite half my modules? here I come!).

Just make sure we can create dynamic arrays of pointers to custom structs. Coz, y'know, we need those.

Also, dynamic arrays within structs.

Also, dynamic array length members.

Get busy dude!! :P

Terrorcell

Also, the 'const' keyword:
Code: AGS

struct foo { int data; };
int a = 10, b = 30;
const int c = a * b; // const would be sooo handy, or at least let 'readonly' act the same as const
foo arr1[c];
foo arr2[a * b];

Instead of having to use #define (could not use #define if we did not yet know the value of a and/or b before declaring the arrays).
AND everything that monkey said. All of it.
Cheers :tongue:

Ryan Timothy B

ArrayList.
That would be the ultimate addition along side the ability to pass custom structs as pointers.

Calin Leafshade

Quote from: Ryan Timothy on Wed 06/06/2012 21:53:07
ArrayList.

I think the goal should be to create an environment in which you can effectively code your own array list rather than just exposing one from the layer below.

subspark

Three extensions on existing code that would be particularly handy:

Read/Write .Name properties

monkey0506

#7
Hotspot.Name and Object.Name already exist but they are read-only at run-time. I don't think it was ever thoroughly explained to me why this couldn't be changed, although perhaps it was something to do with only one room being loaded into memory at any given time and save game stuff...

Named rooms are technically possible by using an enum:

Code: ags
enum RoomNames
{
  rForestEntrance = 1,
  rForestGarden = 2,
  rForestLake = 3,
  rForestWhyNotAnotherRoomInTheForest = 4,
  // ...
};


It might actually cause some confusion to have AGS built-in names like that (especially if they represented script objects and not just enumerated values) unless the whole "only one room loaded into memory at any given time" bit was changed.

Edit: What? Ugh, typing posts 5 mins before I go to sleep... (laugh)

SpeechCenter

Quote from: Calin Leafshade on Wed 06/06/2012 22:48:43
Quote from: Ryan Timothy on Wed 06/06/2012 21:53:07
ArrayList.

I think the goal should be to create an environment in which you can effectively code your own array list rather than just exposing one from the layer below.
I looked at the code, I don't think that adding a struct as pointer parameter is that complex, just a matter of loading the address to SREG_MAR. However, that's far from being able to do an ArrayList because you'll quickly need the ability to create a new object in the heap. Then of course you run into the question of deleting the object.

Furthermore, should the syntax have struct* and if so how do you pass the address of struct as parameter? (and do we really want the C notion of pointers in scripts?)

I believe language changes like that require careful planning, otherwise it will create backwards/forwards compatibility problems.

Calin Leafshade

Quote from: monkey_05_06 on Thu 07/06/2012 05:17:56
It might actually cause some confusion to have AGS built-in names like that (especially if they represented script objects and not just enumerated values) unless the whole "only one room loaded into memory at any given time" bit was loaded.

Agreed, things like this are not changes to the scripting language. They are just additions to the environment. This is something we want to avoid really.

Quote from: SpeechCenter on Thu 07/06/2012 07:07:35
I looked at the code, I don't think that adding a struct as pointer parameter is that complex, just a matter of loading the address to SREG_MAR. However, that's far from being able to do an ArrayList because you'll quickly need the ability to create a new object in the heap. Then of course you run into the question of deleting the object.

Creating objects on the heap was also my concern. As I said, AGS already has the mechanisms to handle an object pool in a managed way and has a suitable garbage collector.

Quote from: SpeechCenter on Thu 07/06/2012 07:07:35
Furthermore, should the syntax have struct* and if so how do you pass the address of struct as parameter? (and do we really want the C notion of pointers in scripts?)

I agree here. Pointers dont make a lot of sense in a scripting environment like this. I am of the opinion that all structs should be reference types and the idea of pointers should be abstracted away. There's no real reason to make a distinction between a ref type and a value type.

Alternatively we could make an entirely new construct and call it a class. Then we leave structs as value types and classes as reference types. This avoids any backward compatibility issues.

like this:

Code: AGS

class MyClass
{
    int LOL;
};

struct MyStruct
{
    int LOL;
}

function foo()
{
    MyClass classRef; // this would now be null
    MyStruct structVal; // this would not.
    MyClass classRef = new MyClass; // classRef is now not null and a new object has been created on the heap.
    //classRef will now go out of scope and will be garbage collected just like a DynamicSprite would be.
}


Quote from: SpeechCenter on Thu 07/06/2012 07:07:35
I believe language changes like that require careful planning, otherwise it will create backwards/forwards compatibility problems.

Planning, yes. Hesitance, no.

SSH

Would be great to have some higher order datatypes built in, like perl or python does: lists, hashes, etc. as well as the ability to build your own. Pre-made ones would be easier for those with less of a programming background. Ideally, if you could access all the namespaces themselves as a dictionary like python can, it would also provide a way for people to make their own savegame mechanisms that didn't get broken for compatibility every time the game is recompiled.
12

subspark

QuoteNamed rooms are technically possible by using an enum
You missed my point slighty so I'll elaborate.  ;)
I remember being able once AGS 2.8? to call cEgo.ChangeRoom("Room Description"). This was helpful when I wanted to re-order rooms into a much more logical list.

monkey0506

I don't see the drastic difference between that and what I did. I mean, if you changed the room numbers then you'd be responsible for updating your list...but...how often do you change room numbers?

Regarding the whole bit about about list types and the like...we'd really need templates to make that truly useful. I've pondered on the idea of trying to have an editor plugin to auto-generate specialized structs based on usage of a pseudo-template. The template struct itself would be commented out immediately before saving the game, and then uncommented after compilation. Never really did get around to implementing it, obviously. Of course now that the compiler is available, we could look at just doing it the "right" way.

As for the proposed reference class type, that sounds like a good solution to me. I haven't really looked into it, but AGS already has garbage collection for things like DynamicSprites, dynamic arrays, ViewFrames, DrawingSurfaces, and other on-the-fly types that are cleaned up if there's no more pointers to them lying around. Would it be terribly difficult to extend this to user-defined reference classes?

SpeechCenter

Quote from: Calin Leafshade on Thu 07/06/2012 08:11:20
Quote from: SpeechCenter on Thu 07/06/2012 07:07:35
I believe language changes like that require careful planning, otherwise it will create backwards/forwards compatibility problems.

Planning, yes. Hesitance, no.
Not advocating hesitance, but don't want to pay the price of easily avoidable mistakes. If you create a 'new' keyword for objects, constructors and destructors easily come to mind, which of course further complicate things.
As for garbage collection, I didn't check, but does the current garbage collector handle loop reference? For example object A references object B and object B references object A (or something more elaborate)? I didn't check, but maybe this wasn't a concern for the current use case and if we start adding data structure library (which is a good idea) this has to be handled. The template option (or generics) is also an important subject. Anyway, all this is much more work than simply sending a struct as a function parameter, essentially all these things drive the script language to C#-like language. Most importantly, this has to remain optional for advanced developers, it's best that most AGS users can just start without knowing too much programming.

I thought a bit about the pointer thing, in AGS '*' actually acts as a reference & in C++ and not pointer, so it might be ok, as long as you can simply assign struct instance to struct reference. Another possibility is to define that this operator is optional for parameters, because objects are always passed by reference.

RickJ

Since there is effort to separate editor-compiler-runtime, one has to wonder if it wouldn't be easier and better to just move to an existing high level OO script language such as python, angel script, etc, etc, ...?  We would end up with a full featured language complete with compiler/runtime and wouldn't need to expend any effort on compiler and related issues. 

Calin Leafshade

Yea, i've thought about that. The problem is that you would need to find a way of saving the state of the VM and I'm not sure how you do that with a 3rd party scripting language,

void

I'm not sure what you mean by that. Unless we are not talking about some esoteric scripting language, you can save the state of any VM by saving its cache (ie. stack) and memory contents, doesn't matter if it is AngelScript, PHP or Python.

SpeechCenter

#17
I still don't fully understand what problems are we trying to solve here. Can anyone provide the use cases that are not possible or difficult with today's scripting language? Meaning, not in the language itself, which is obvious, but for game developers, actual use cases.

The big advantage I see with AGS is that it's relatively easy for someone with little programming experience to create a game. I think the goal should be to make it easier for those people, not add more complex language structures or more languages (unless they are necessary or cause things to be obscure today).

Calin Leafshade

#18
I agree that AGS's strength is its simplicity and I think that keeping that simplicity intact is vital.

However, there are a few holes in the scripting language that prevent more experienced coders doing things more elegantly. This is not a problem in itself but it means that we cant make certain kinds of modules for the less experienced to use without jumping through hoops.

Ok I'll list the things that AGS cant currently do that i think it should

Important:

Passing structs as parameters either as a reference or value type. (easily the most important thing that ags lacks)
More flexible dynamic arrays and a way to find an array's length at runtime.
Forward declaration of some kind. Currently its impossible for modules to talk to each other in a bilateral fashion.

Sugar:

For loops,
Switch/Case,
implicit casting,
function overrides

To be honest, even if just the first one was implemented i'd be happy. The rest can be fudged in various ways.

Crimson Wizard

Quote from: SpeechCenter on Sat 09/06/2012 13:49:21
The big advantage I see with AGS is that it's relatively easy for someone with little programming experience to create a game. I think the goal should be to make it easier for those people, not add more complex language structures or more languages (unless they are necessary or cause things to be obscure today).

Quote from: Calin Leafshade on Sun 10/06/2012 12:48:18
I agree that AGS's strength is its simplicity and I think that keeping that simplicity intact is vital.

Just two add my two cents, there's always an option to have both low-level and high-level language features, with latter serving as user-friendly wrappers over low-level functionality.
And, by the way, there's always an option to create GUI wrappers over scripts. I haven't had much experience with AGS 2.72 but I remember there was some sort of "interactions" dialog. I recall some people mentioned it was easier to work with for newbies. Personally, I may also mention such examples (known to myself) as Warcraft 3 and Starcraft 2 scripting module that allowed people to make scripts both by using GUI and by directly writing script texts.

SMF spam blocked by CleanTalk