Related to "the future of AGS" -- but only for OCD and nerds

Started by Monsieur OUXX, Tue 17/01/2012 17:53:13

Previous topic - Next topic

RickJ

Quote
Can you decribe a use case? I can't visualize it. Maybe if there were some events associated to characters, like, let's say "has started speaking".
The way I visualize it the character script would be just like a module.  It would catch all the character's events if so scripted.  Currently this stuff is just appended to the global script.  Beyond this use,  any kind of  NPC  autonomous behavior could be scripted in this way.   

It would be the same for other entities as well.  Door would know how to open and close themselves for example.  The would handle their own events and so could be copy and pasted into the same or different rooms. 

Quote
I even think removing the header script would be justifiable
Quote
I wouldn't agree and think it's still needed.

monkey0506

I like the idea of characters (and other "entities") being able to have their own script, but I don't think that the character events (or any other events) should be required to exist within any specific script. This is a huge flaw in the way that the compiler works currently, that it expects events to be in a certain place.

We should really make forward declaration of functions a priority IMO. Especially given the fact that you can provide one event handler for multiple events, you should be able to reference that handler without having to worry about whether it's been fully defined yet. The linker essentially has the capability, we just would need to expand on it.

By the way, the compiler was never open-sourced, was it?

RickJ

Quote
I like the idea of characters (and other "entities") being able to have their own script, but I don't think that the character events (or any other events) should be required to exist within any specific script.
I didn't mean to imply any requirement as you describe.  I was thinking in terms of the way modules currently work where for example they can handle mouse click and then pass it on to to other scripts or not.  So presumably  there would be some kind of priority in handling order.  Consider for Game contains Room and  Room contains Character.  Character events would first be handled by the Character script, then Room script, then Game script.   Each of those scripts would have an opportunity to have a handler and to capture the event so that it was not passed on.

Quote
We should really make forward declaration of functions a priority IMO.
I agree this would be nice to have but I wouldn't want to give up lighting fast compiles to achieve it.  So as long as the typical incremental compile-test iteration was adversely affected I would be for it.

Ryan Timothy B

Quote from: Monsieur OUXX on Sat 21/01/2012 14:01:54
Quote from: Ryan Timothy on Fri 20/01/2012 21:17:22
It would be nice if characters had the option to have their own script as well.
Can you decribe a use case? I can't visualize it. Maybe if there were some events associated to characters, like, let's say "has started speaking".
Basically because everything is being grouped into the Global Script. It's a gigantic mess.

This would make it possible to export a character/GUI/Inventory Item. One person could be creating the characters and their responses and default actions, animations, sprites, etc all on their end. Then they simply export all that work as a single Object and is easily imported into the group project. It could be done with Inventory items, GUI's, etc.

Quote
Quote from: Ryan Timothy on Fri 20/01/2012 21:17:22
Would we really need a Global Script?(...) Basically all we would need is a Game script.

I won't say yes or no, it's just vocabulary, isn't it?
Not at all. If every entity had their own script, just like Visual Studio does with each Form and such, what would be the need of a Global Script other than a few game events and such? And then the name would be misleading. It should therefor be called the GameScript or TestGame.Script or whatever.

Quote
Quote from: Ryan Timothy on Fri 20/01/2012 21:17:22
I even think removing the header script would be justifiable

Why not. What is the opinion of scripters here? Doesn't it make a module more readable if you put all the comments, function description, parameters decription, etc. in the header?
What's the honest purpose of a header script? So you can Import/Export things? The only reason we need that is because there is no Public expression. I see zero reason for having them. You need to document your module script, do it in the top of the module script itself.


Here's a quick mockup of what I mean with a script for each element:


Notice how some things are actually left out? Like inventory and such? Well why have the inventory tab if the game doesn't even have inventory items? You should right click on the game group, Add inventory item, and from then on you have an Inventory branch where you can add Inventory items to the main game.

Everything should be nonvisible like Sprites, GUI's, Conversations, etc. And the reason for that should be to the game should be completely customizable. Where you can add an Animation or Sprite set for each character, or whatever you wish.

Kinda like this where Sprites and Animation are within the Character object - but there is still the global game sprites:


Now I know this could make things more complicated, but it's the only logical way to be able to export characters and such and actually have their scripts, sprites, animations, etc all be able to stay with them. Mainly only for team projects, but could help with organization. I'm just not sure how the sprite numbers should operate. Perhaps something like  cEgo.Sprite[10]   and that would access sprite 10 from within the sprite set for cEgo  and not sprite 10 from the global game sprites.

Like I said, this wouldn't be mandatory to group Animations and Sprites for each element, only if you wanted to as a designer or in cases of a team project.


(the whole point of this thread is to suggest ideas that would perhaps better AGS - even if it's technically difficult to overcome)

Calin Leafshade

#24
The problem with that design is that it has no inheritence and would encourage code duplication.

Say you want multiple characters to do the same thing how does that work without duplicating code?

EDIT: There are ways to do that by simply going for a OOP model all the way. The problem with that is that it becomes more complicated for the end user because it becomes less thematically relevant to group certain things together. Unless I suppose you grouped everything that inhereited from Character together which would work i suppose.

If it were up to me and I didnt have to consider less tech savvy users i would OOP it all the way and essentially just define the Character class in the engine and then allow me to make subclasses of character which contain all the events like this:

Code: ags


class Roger : Character
{

  Roger() //ctor
  {
     OnClick += Roger_OnClick; //event += methodgroup
  }

  Roger_OnClick()
  {
     Game.Display("Hi I am Roger!"); // Game being passed in the ctor via the game

  }

}



Ryan Timothy B

#25
You could add a master script for all Characters. I don't know exactly how it'll work with the events tab, it just seems like a damn good idea overall.

Edit: Also as you've noticed in my visual example, I didn't include the ID on the Animations, GUIs, Characters or Rooms. They should never have been a hard-coded thing in AGS in the first place. It results in tons of magic numbers like  player.ChangeRoom(2);

What the hell is room 2? How does anyone remember what Room 2 is without actually going to the object tree and looking it up. It should all be using the programming name, not the ID. The ID should be used with scripting, whenever it's actually needed.

Also on a side note, I don't think the game should require a player character. So to change the room you simply just use: Game.ChangeRoom(rDesert);  or something along those lines -- but also having Player.ChangeRoom(Room)  as well. It makes it easier for cutscenes where the player is still in the other room, or in any situation where you may not even have a player character but are forced to because of AGS.

Ryan Timothy B

Quote from: Snarky on Wed 18/01/2012 14:16:01
Maybe if you could explain to me why, for example, we need to decide whether characters should have no/one/multiple inventories, instead of just leaving that choice up to each game creator, I'd see the point of trying to make a universal adventure game specification.

I reread this thread again and have noticed you all asking about inventories. The current way inventories work is that every character is defaulted to a single inventory (or is it that every item has a List of which characters carry it). Whichever way it runs, it basically leaves you with one inventory per character mandatory.

Instead how about adding the inventory to the character like so WHEN you actually need it (tweaking my above visuals to describe):


So basically you aren't adding the inventory item to the character, you're adding the inventory item to the Inventory.

So a code example would be:

cEgo.Inventory.AddItem(iBook);
or
cEgo.Spells.AddItem(iFire);


Am I totally off base here, or are these ideas actually useful? lol

Alan v.Drake

I'd like to see enums members as collections instead of having them all thrown messily together alphabetically. AGS is really confusing in this regard.

- Alan

ddq

That way looks like a big improvement, RT. Much more flexible and clear. Only drawback I see is the longer form of the code, which some might find obtuse. I personally find it much, much, much better than just having a bunch of inventory manipulation functions for characters.

Also, I hope that the devs will consider fixing structs up a bit, namely adding the ability to have other structs and arrays (and arrays of other structs) as attributes. Not all that important for adventure games, but a big simplification for, oh I don't know, RPGs and space sims.

Ryan Timothy B

#29
I actually noticed a large problem with custom inventories (some character with none, or some with one or multiple). You wouldn't be able to call the Inventory by the character and its ID.

Code: ags

character[i].Inventory.AddItem(iWhatever);

Wouldn't compile because "Inventory" or "Spells" etc doesn't belong to all Characters. It belongs to individual characters.

It would basically limit how inventory is handled across multiple characters. But for the general adventure game, I don't see any issues with it as long as you're calling the character by its programming name.
I'll need to think some more on this..

Edit: The only real option would be to have the custom inventories work for all characters and not individual characters. That way is much less pleasing. :(

monkey0506

Ryan, as for your inventory suggestion it might be feasible to implement associative arrays in AGS. I believe the compiler is actually the only thing that currently would specifically not allow us to do so. Then you could do something along the lines of:

Code: ags
character[i].Inventory["Spells"].AddItem(iFire);


Calin: I'm kind of up in the air myself about adding delegates to AGS as they seem to increase the technical level of the language...but I suppose so long as the basic code could still be generated (namely, keep the Events pane like VS has, and automatically add the specified event to the appropriate delegate. And it would certainly improve certain aspects for the more tech-savvy users...so yeah, that could work.

Alan v. Drake: When you say you'd like to see enums together as a "collection", do you mean like the C# style enums:

Code: ags
enum Color
{
  Red,
  Green,
  Blue
};

// ....
Color c = Color.Red;


Where you actually use the name of the enum and the enumerated value together? I was looking for a way to implement that in C++ several months ago, and only recently found out that it was officially adopted into the C++11 standard. I highly recommend we make AGS enums work more like this. It just feels...cleaner...than having a million different enumerated values popping up in autocomplete.

Ryan Timothy B

I believe he was referring to how AGS sorts the enums alphabetically instead of numerical order.
Where the auto-complete should show it as: Red, Green, Blue  in the numerical order of the enum, instead of  Blue, Green, Red  which is what AGS does (if I remember correctly) throwing the auto-complete list out of whack.

Calin Leafshade

I would rather it be in the C# form (Color.Red) but that is somewhat off topic

Alan v.Drake

Quote from: monkey_05_06 on Sun 22/01/2012 01:24:21
Where you actually use the name of the enum and the enumerated value together?

Yes!

Quote from: Ryan Timothy on Sun 22/01/2012 02:07:18
I believe he was referring to how AGS sorts the enums alphabetically instead of numerical order.

No, alphabetical order is ok, I just dislike having all the different kinds mashed up together.

- Alan

Monsieur OUXX

Quote from: Calin Leafshade on Sat 21/01/2012 19:40:46
The problem with that design is that it has no inheritence and would encourage code duplication.
Say you want multiple characters to do the same thing how does that work without duplicating code?
There are ways to do that by simply going for a OOP model all the way.
Quote from: Ryan Timothy on Sat 21/01/2012 19:40:46
You could add a master script for all Characters

You could even make it graphic, with a "Listeners" (or "Behaviours") branch  in the treeview, that you could then attach to any character or even other stuff, the same way you attach Views to stuff.
Those listeners/behaviours could contain any number of event handling/scripts -- if the events don't match the object the listener is attached to, then they're simply ignored.

Those listeners/behaviours could be edited either with a simple graphic tool (like in Blender Game Engine) or with a script -- Same kind of duality you have in most IDE's when it comes to designing UI's (graphically or through code), except here it's meant to manage generic events and state machines.

Also, you could have a listener/behaviour inherit from another or several ones, hence solving the redundancy issues.

 

Monsieur OUXX

#35
Quote from: Ryan Timothy on Sat 21/01/2012 22:24:34


I don't understand why you stepped back in our overall ambitions, here. You represented Inventories as part of a character, whereas I think inventories should be designed separately from characters, just like views.

An "inventories" branch should exist, grouping one or many inventories.

Then in any of the Characters properties (let's say "cEgo"), you could assign the "starts with inventories" value to the inventory/inventories you like, just the same way you do with the "starts in room" property (except it could have multiple values).

This would immediately be consistent with the "character.Inventory["Spells"]" or "cEgo.Inventory["Spells"]" syntax, but through the Editor.
 

Monsieur OUXX

#36
In the mockup below I didn't represent the ".Designer" and ".Script" subdivision, but I love that idea, and that would be how you decide if you want to open the graphic editor for the behaviour, or its script view instead.



 

Ryan Timothy B

#37
Quote from: Monsieur OUXX on Tue 24/01/2012 11:17:17
I don't understand why you stepped back in our overall ambitions, here. You represented Inventories as part of a character, whereas I think inventories should be designed separately from characters, just like views.r "cEgo.Inventory["Spells"]" syntax, but through the Editor.
I was only trying to think of how you'd give or check if a character has an inventory item. Generally the only character that holds inventory in a game is the player character, but not always the case.

But if your 'All Inventories' worked for all characters, it would still need to act in the same fashion.  cEgo.Inventory.HasItem(iWhatever);


Edit: Also has anyone used another engine that manages lots of sprites? I've never really been a fan of the magic numbering we use for sprites. You literally have to check up what that sprite is every time you're checking older code.  Would an OO system be more user friendly?  Sprites.Folder1.Sprite9? Or perhaps the option for either or.

Edit again: Or whenever you've punched in something that requires a sprite number, eg: Game.SpriteHeight[   once you punch in that bracket an autocomplete comes up with the sprites icon on it. If you click the sprites icon it takes you to the sprites collection and you choose the sprite to use. Then perhaps whenever you hover your mouse over that sprite number (or perhaps the whole Game.SpriteHeight[number]  -- as long as it's a constant variable or sprite number) a graphical image of that sprite pops up above your mouse for quick reference.

RickJ

@Monsieur OUXX:  Inheriting behavior is an interesting idea.  What do you think about dynamically inheriting behavior based on context?  For example if a character is at the beach he may want to talk about the ocean, fishing and ships but if he were somewhere else he may want to talk about entirely different things.   Contextual behaviors are not limited to dialog; if the character was on the beach he would walk, if he were in the ocean he would swim.   A politician character may not take bribe money in a public place but he may do so in a dark alley (i.e. responds to exactly same event  differently depending on location).   Behavior is not limited to characters right?

Just wondering in light of the above comments; is inheriting behavior different than OO class inheritance?

@Ryan Timothy:
Quote
Also has anyone used another engine that manages lots of sprites? I've never really been a fan of the magic numbering we use for sprites. You literally have to check up what that sprite is every time you're checking older code.  Would an OO system be more user friendly?  Sprites.Folder1.Sprite9?
It's sort of what I had in mind earlier in the thread.  Each entity could own it's own resources (sprites, sounds, etc) so you could have something like cEgo.Sprite.FolderWalk.Left1


Monsieur OUXX

Quote from: RickJ on Thu 26/01/2012 02:57:46
@Monsieur OUXX:  Inheriting behavior is an interesting idea.  What do you think about dynamically inheriting behavior based on context? 

Just wondering in light of the above comments; is inheriting behavior different than OO class inheritance?

We're saying the same thing :
1) You're right, the scripter/designer should be able to swap behaviours depending on the context.
That's why describing a set of scripts as a "behaviour", and turning it into a simple "brick" is, IMO, a cool idea.
You can set the default behaviour when you design your game, using the Editor, but if you need advanced stuff (like swapping the behaviour in the course of the game), you can swap it with another behaviour using the script:
  cEgo.behaviour = behaviours["BehaviourAtTheBeach"];
You can imagine that both "BehaviourAtTheBeach" and "BehaviourWhenSwimming" inherit "BehaviourForMyMainCharacter". Maximum script re-use!

2) Inherited behaviours is exactly the same as OO inheritance, except that we give it a name, and we make it a visible object, easily editable in the Editor. This way, we also make it a concept understandable by non-programmers.
 

SMF spam blocked by CleanTalk