AGS 3.3.x/3.4.0.0 Developer Discussion

Started by Gurok, Sun 09/02/2014 08:45:13

Previous topic - Next topic

Gurok

I had that working for global variables, but not stack variables. Some wrinkles in addressing that weren't immediately apparent. I'm going to pull it apart and try again, of course.

Is it possible for me to close issue 503? http://www.adventuregamestudio.co.uk/forums/index.php?issue=503.0

I'm going to make a new thread, "AGS 3.3.1 - Test Build" with a changelog and download link tonight.
[img]http://7d4iqnx.gif;rWRLUuw.gi

Crimson Wizard

Quote from: Gurok on Mon 10/03/2014 22:16:17
Is it possible for me to close issue 503? http://www.adventuregamestudio.co.uk/forums/index.php?issue=503.0
I don't think it is correct to close issues in AGS tracker before at least some public release is made. But that's my opinion.

Gurok

Quote from: Crimson Wizard on Mon 10/03/2014 22:56:02
Quote from: Gurok on Mon 10/03/2014 22:16:17
Is it possible for me to close issue 503? http://www.adventuregamestudio.co.uk/forums/index.php?issue=503.0
I don't think it is correct to close issues in AGS tracker before at least some public release is made. But that's my opinion.

Oh right, yes. Sorry. I agree. A bit too hasty by me there.
[img]http://7d4iqnx.gif;rWRLUuw.gi

Gurok

I am thinking of possibly allowing an empty statement, i.e.:
;
As a valid AGS Script statement. How do people feel about this? At the moment, the compiler rejects it.
Pros:
    - More C-like
    - Allows for neat for/while loops that repeatedly call an iteration function
    - A good placeholder when you need to fill in the if() part of an if/else later on
Cons:
    - Allows users to possibly make errors by accidentally terminating a for/while loop with a ;
[img]http://7d4iqnx.gif;rWRLUuw.gi

Radiant

I'm generally in favor of mimicking C-syntax as much as possible. FWIW I occasionally use { } already as an empty statement.

abstauber

Hey Gurok (and devs),
since you're currently working on 3.3.1, would it be too much to request this feature:

Only these two functions are missing to make dialogs completely controllable via keyboard which is what I'd like to do:
Code: ags

    Dialog.SetActiveTopic(int option)
    Dialog.StartTopic(int option)


Currently you can only start a complete dialog by script and the only way to highlight a dialog topic is via mouse-over.
If it's not too much work, I'd be really happy to see this in 3.3.1

Gurok

#46
Quote from: abstauber on Thu 13/03/2014 10:14:11
Only these two functions are missing to make dialogs completely controllable via keyboard which is what I'd like to do:
Code: ags

    Dialog.SetActiveTopic(int option)
    Dialog.StartTopic(int option)


Raise a bug tracker suggestion for these.

I understand Dialog.StartTopic() as I've run into that limitation myself. What would SetActiveTopic be for?

I raised a suggestion for the scripting changes I think I'll be able to do (not closures or function pointers or outlandish stuff like that). In some ways, I think this topic was a bit of a mistake, but it's been good to gather feedback.

I think your second function is doable at some point, abstauber. I don't know about the first.
[img]http://7d4iqnx.gif;rWRLUuw.gi

Crimson Wizard

#47
I think "Active" is the one selected (highlighted).
I am not sure about "Topic" word. Other functions use "Option" (compare with Dialog.GetOptionText, Dialog.GetOptionState etc).

Gurok

Quote from: Crimson Wizard on Thu 13/03/2014 11:12:08
I think "Active" is the one selected (highlighted).
I am not sure about "Topic" word. Other functions use "Option" (compare with Dialog.GetOptionText, Dialog.GetOptionState etc).

Yeah, that's what worries me. As far as I remember, dialogs run without really having the concept of a selection. They only have a mouseover state. Unless he means "choose this choice for the player" like how the 0-9 keys behave currently.
[img]http://7d4iqnx.gif;rWRLUuw.gi

Crimson Wizard

#49
@abstauber, have you tried using DialogOptionsRenderingInfo.ActiveOptionID ? I think it is what will let you set highlighted option with keyboard (or in any other way).
Of course this will only work if you write all the other handlers for custom dialog rendering too.

"StartTopic" (or RunOption, whatever) might be still required though.

abstauber

#50
As far as I remember, the custom dialog GUI only updates its surface when a dialog option is changed or the mouse hovers over an option. So even if I set the active ID, I'd still need to tell the GUI to update.
So simply setting the highlight by a number would be way more convenient.
And yes - dialog Option makes much more sense than topic :)


QuoteRaise a bug tracker suggestion for these.
Will do.
edit: but I can't. Do you need a special role for this?

Gurok

#51
As CW mentioned, dynamic creation of user structs is quite involved.

I haven't coded this yet, but I was thinking something like this might work for passing structs without needing to manage them:

Header

Code: ags
    struct Point
    {
        import static Point *Create(int x, int y);
        import float DistanceTo(Point *target);
        int X;
        int Y;
    };


Module

Code: ags
    static Point *Point::Create(int x, int y)
    {
        Point instance;
     
        instance.X = x;
        instance.Y = y;
     
        return(&instance);
    }
     
    float Point::DistanceTo(Point *target)
    {
        int dx;
        int dy;
     
        dx = this.X - target.X;
        dy = this.Y - target.Y;
     
        return(Maths.Sqrt(IntToFloat(dx * dx + dy * dy)));
    }

     
Example Usage

Code: ags
    float myFunction()
    {
        Point a;
        Point b;
     
        a = *Point.Create(3, 3);
        b = *Point.Create(6, 7);
     
        return(a.DistanceTo(&b)); // 5.0
    }


Too complicated?
[img]http://7d4iqnx.gif;rWRLUuw.gi

Crimson Wizard

Quote from: Gurok on Tue 17/06/2014 23:55:50
Code: ags
    static Point *Point::Create(int x, int y)
    {
        Point instance;
        <...>
        return(&instance);
    }
    }

This looks like a very bad idea. You are going to return an address to object, allocated on stack. Besides, there's no '&' as "take address" and '*' as "dereference" operators in AGS... and for a reason: AGS was made as a Java/C#-like language, and you are suggesting to "downgrade" it to C-like language.
I still believe that managed user structs is an only proper way to go.


And, yes, I am back... I was away, then busy, then ill :-X. Now trying to finish unfinished business...

Calin Leafshade

I agree with CW. This is, at best, a hacky stopgap.

The pointer syntax in AGS is a weird anachronism as it is and shouldn't be expanded.

I think it would be better to move towards true object references.

AGS does have a way to add arbitrary structs to the object pool via the plugin interface. Is it a huge deal to simply expose this to the script env?

Crimson Wizard

#54
Just few thoughts (I'd need to refresh memories about script interpreter before I can be more specific).

To have a managed user struct you need an object that will describe it. Possibly, it only needs two properties: size of struct (in bytes) and pointer to data (array of bytes).
Then, you need a manager class that would handle such objects to integrate new type into AGS (manager class and object class could be the same).
Then, it's only a matter of making two additions:
- "new" keyword which would allocate object of desired size on heap and assign to reference; one may look into how script strings and dynamic arrays are created.
- if proved necessary, extend "access member" operation to ensure that it works well with the new type.

BTW, I think, dynamic array type may be a good example to how managed object and manager classes should work, principally.

Gurok

Quote from: Crimson Wizard on Wed 18/06/2014 12:25:25
Quote from: Gurok on Tue 17/06/2014 23:55:50
Code: ags
    static Point *Point::Create(int x, int y)
    {
        Point instance;
        <...>
        return(&instance);
    }
    }

This looks like a very bad idea. You are going to return an address to object, allocated on stack. Besides, there's no '&' as "take address" and '*' as "dereference" operators in AGS... and for a reason: AGS was made as a Java/C#-like language, and you are suggesting to "downgrade" it to C-like language.

Yes, I know the object's allocated in stack memory, but it *kind of* would have worked for unmanaged structs as long as there were never pointers to them.

Anyway, yeah, looking into getting the "new" keyword working properly now. I've been messing around with things for about a day now and I feel /slightly/ more informed. There's a surprising amount that's already built. If you declare a struct as managed, you can have pointers to it and it compiles. You just can't do anything useful with it. So you're right. The "new" keyword is like the missing puzzle piece. Thanks!
[img]http://7d4iqnx.gif;rWRLUuw.gi

Calin Leafshade

If you can make that work then you'll have gone a long way towards "fixing" AGS Script.

Crimson Wizard

#57
@Gurok
I made this patch (applied on develop-3.3.1): http://www.mediafire.com/download/g2wnuyfqzodn89l/0001-Script-managed-user-object-support.patch
It adds user object support to the engine. Unless I miss something, this is about all what is required for the Engine.
The compiler needs:
1) support for creating managed user objects, e.g. via "new" keyword. I made new "SCMD_NEWUSEROBJECT" command for that (takes one argument - the size of struct in bytes).
2) "legalize" usage of user pointers (MyStruct *p) so that they could be used in similar way as built-in classes (Character*, etc).
The access to object contents is performed same way as you do for internal variables in built-in structs (legacy scripting).
I don't know compiler well, but you seem to be able to get around it.

Let's try this...

EDIT: found a bug, reuploaded patch... (same link).

EDIT2: reuploaded second time :tongue:.
I did not realized that the command should take 2 parameters: register number (to save new pointer) and struct size.

Crimson Wizard

#58
It. Works.

Final patch for Engine: http://www.mediafire.com/download/g2wnuyfqzodn89l/0001-Script-managed-user-object-support.patch

Test patch for compiler (breaks managed arrays, but this is for test): http://www.mediafire.com/download/0safjx7itsh118l/0001-Compiler-TEST-creating-user-object.patch


Proof :D:
Spoiler

Script:

Result:

[close]




monkey should be happy. No more Lua, mwh-mwhahah. (kidding)


TODO:
1) proper compiler patch (I really hope Gurok will make one, I made this test rather intuitively).
2) support for array of user objects.
3) test all possible cases.

Gurok

#59
Whoa

One more TODO... I was going to change the compiler to allow structs to have functions with the same name, e.g.

Code: ags
managed struct MyStruct
{
  import function MyStruct(int a, int b);
}


It's a simple patch, replace "(towrite != in_struct_declr)) {" in cs_parser.cpp with "(towrite != in_struct_declr || sym.stype[last_time] == SYM_VARTYPE)) {"

And the "MyStruct" function would act as a constructor, e.g. x = new MyStruct(3, 4);

Then it's just a matter of parsing a function call after each new statement is parsed.

I'll have a look at your new Editor patch before I start on a proper branch, CW. This is so cool.

If you've seen the part where it parses an array, I think that's the right place to put the managed struct stuff too. It's just a matter of having an if() statement like...

If the symbol following the var symbol is not "["
  ... managed struct creation code ...
else
  ... dynamic array creation code ...
end if

Anyway, really exciting! Awesome work, CW.

EDIT: Saved games (serialisation/deserialisation) would be one of the first things I'd like to test. Anyway, I'll get to work on this, sorry! :D
[img]http://7d4iqnx.gif;rWRLUuw.gi

SMF spam blocked by CleanTalk