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

Monsieur OUXX

This is a side discussion. (and when I say "side", I mean "as far as Pluto")
Most will have no idea what it's about, and others will wonder why one would even bother with such things.

But here it is : Since we mentionned it, how about we actually DO write down the specifications for all "exchanges" in point-n-click software? You could call this a "point n click standard" or a "point n click protocol" or whatever you like.

Some have seen that the idea was raised in another thread.
Such specifications would include :
- abstract, universal terms to designate anything that is involved in point-n-click (what's an "inventory", what's a "character", etc.)
- a way to organize all this

Long things short: Something like web standards, but instead for Point n click games.

I'll try to make it a little more concrete: Do you ever ask yourselves silly questions like the ones below?
- "in a point n click, should we expect the main character to have one inventory? Several? Possibly one inventory per character? etc." (think "Maniac Mansion")
- "should a character wearing a custom skin still be the same character (with custom, temporary graphical properties) or should we use the trick of switching characters?" (think "Nelly Cootalot wearing a mustache". Is it still Nelly?)
- "is an object in an inventory virtually the same thing as the object on the floor before it's picked up, but just drawn differently when displayed in the inventory?" (think "Kyrandia's droppable objects")
- In an inventory, should countable objects (such as coins) be managed natively?
- etc.


If these questions should ever be asked, it's now! Because we are at an important time of AGS' history. These specs could be the underlying work to the implementation of AGS 4.x or 5.x (see the proposed roadmap in thread "the future of AGS")These specs could answer questions like: what should be hard-coded? What should be dynamic? What would be the limits?
More importantly, they would then help maintaining migration tools through versions of AGS (even if a feature wasn't implemented in version X, version Y can still import the game files because the feature was already described in them -- yet let empty).
Another thing is that it would enable interoperability (things could be exported as XML).



There are no limits.
I hope I'm being clear in my explanations.


PS: Another concrete example that pops to mind would be the AGS awards: Imagine if there was a "standard" for point n click characters' graphical resources. Then it would make the programmer's life easier, he'd only have to focus on handling the characters, their moves, and what they're saying, without having to worry about loops, sprites, views, etc. If someone decided to code a feature to allow clients to upload their own skins onto the server, the organizer of the awards wouldn't have to do all the job of debugging all the skins one by one, validate them, etc. Then again that's just a random example.




 

Wyz

Wow, Monsieur OUXX, really you've described a few things that were on my head the past few days. Boring story (or not since this is an OCD and nerd only zone): a few years ago I created a specification language for myself with as goal to abstract all sort of games to find an universal models for games in general. This project has since been superseded by other projects, all not very interesting but Point and Clicks was one of the game genres I've looked at. It was actually not that hard to do it for point & clicks since it is really a well defined genre and AGS and I'm sure all other tools to create such games have structures that resemble any generalisation closely.

Still, it might be useful to make a specification for AGS, and I was already planning to do this. Maybe we can bundle our efforts. I don't mind writing it in other specification languages then my weird own one. I've worked with Z and UML in the past, but UML might be a bit too visual, and Z too formal, heck whatever works. :D

Migration tools will be really helpful to the community, also making resources that will remain useful for different editor versions and engines. Let me hear what your ideas are.

And about the awards, yes that would have made my life a lot easier, especially since things like views are pretty much static.
Life is like an adventure without the pixel hunts.

Ali

Quote from: Monsieur OUXX on Tue 17/01/2012 17:53:13
- "should a character wearing a custom skin still be the same character (with custom, temporary graphical properties) or should we use the trick of switching characters?" (think "Nelly Cootalot wearing a mustache". Is it still Nelly?)
- "is an object in an inventory virtually the same thing as the object on the floor before it's picked up, but just drawn differently when displayed in the inventory?" (think "Kyrandia's droppable objects")

I can't answer the philosophical question, or engage in the techie discussions, but I can confirm that Nelly with a moustache is still Nelly.

I think the second one is quite interesting. The idea of objects having continuity between the real world and the inventory makes a lot of sense (The Elder Scrolls games work like that I think..?)

It also makes me wonder about creating a game where players can sneak into the inventories of other characters (in the form of minds or memories?) and rearrange things. Getting more than a bit off topic, so I will stop.

Monsieur OUXX

#3
Wyz's post is a relief. I thought people would throw rocks at me for this.
Wyz, you pinpointed my concern here: The scope. The goal wouldn't be to describe a universal language for any type of games (that would be an unlimited scope) but instead only for point n click games (but letting enough doors open for people who'd like to extend their gameplays).

I'd like the opinion of someone involved in the technical development of the AGS editor. Would that help or would that be an obstacle? (then again, here we're only talking about future versions of AGS, not the current one!)

Does anyone have recommendations to make regarding which language should be used to formalize such specs? I'll always have a preference for UML, but there aren't so many free UML editors around (well there are plenty, but most of them omit most of actual UML!)


PS: Ali, how did you add the mustache on Nelly? By changing views, or by drawing it over manually at each frame?
 

Snarky

I don't really see the value of a general specification or protocol for adventure game data, because adventure games aren't identical; they work differently and have different needs. So to all of your concrete examples, I think the answer is "it depends".

(I could see a use for it if we were creating a new adventure game engine to run networked games, like the AGS Awards ceremony, or to run in a browser, where there'd be a lot of data passed back and forth and you'd want a nice format to represent all of it. But that's not really what AGS is for.)

What I do think is worth considering is whether the built-in datastructures and abstractions in AGS are optimal (allowing for easy creation of a variety of game mechanics), or whether they should be simplified, extended or reorganized somehow.

Someone (ProgZmax?) has talked about how it would be convenient to allow objects to move between rooms, allowing them to be used in situations where you need a character or a GUI currently. I would further propose to use the principle of inheritance, so that an object extends hotspot, and character extends object. And yes, I don't think we need a separate data type for inventory objects.

The built-in cursor system is confusing, and I think it would simplify things to drop hard-coded cursors completely and make them all user-defined (with the empty game/Sierra game templates creating the appropriate number of defaults).

I also think the creation process for characters and (particularly) animated objects is confusing, and involves a lot of duplication of work. In my opinion the concept of "views" should be reconsidered, possibly distinguishing between animation sequences and character views (and allowing more flexibility in which views to provide; including possibly composing views by combining separate sprites/animation sequences), and probably offering some way to auto-generate views/animation sequences from a series of sprites (e.g. in the character/object creation dialogs).

GUIs, overlays, dynamic sprites, rawdraw methods... Ideally these would just be layers that you could draw on and compose freely, above and below elements in your game scene. (But this might not be efficient implementation-wise, so some compromise between functionality and performance may be called for.)

It would also be nice if mixed resolutions (e.g. backgrounds, characters etc. running in 320x240, but fonts running in whatever resolution the game is scaled to, as faked in the Blackwell games) and sub-pixel positioning were built into the engine, but that's not really an issue of the game logic, more just the display logic.

Monsieur OUXX

#5
@Snarky: Your answer is confusing.

You start by stating that we don't need general specifications.

Yet, you then describe exactly what we're actually talking about. These are not technical specifications, this is not about data storage, etc.
This is indeed about optimal abstractions.

You've described a few concrete applications that fits perfectly:
- "Shoud objects belong to a room, or be cross-rooms entities?"
- "Shouldn't cursors' representations be detached from the actions associated with them? Shouldn't actions be user-defined?"
- "Shouldn't 'animation sequences' be a different concept from 'views'?"
This is abstract, but clearly has an impact on the final implementation.
That's the sort of things we'd like to define.

But then you switch again to technical implementations (inheritance, etc.). I have nothing against that, of course.


 

Monsieur OUXX

One of my concerns is that I don't like the word "Object".
It refers to so many things:
- It's a term used in Object-Oriented Programming, which would have a specific meaning when dealing with the programming of the Editor
- It could refer to that abstract "Object" underlying hotspots, inventory objects, etc. (described in Snarky's post)
- It refers both to something on the ground and something inside the inventory, etc.

That's one of the things that confused me when I started learning AGS. I was confusing objects and inventory items.
 

Snarky

Quote from: Monsieur OUXX on Wed 18/01/2012 11:01:17
@Snarky: Your answer is confusing.

You start by stating that we don't need general specifications.

Yet, you then describe exactly what we're actually talking about. These are not technical specifications, this is not about data storage, etc.
This is indeed about optimal abstractions.

...

But then you switch again to technical implementations (inheritance, etc.). I have nothing against that, of course.

Strange, I saw the bit about inheritance as being closest to what you were talking about, since it goes directly to the UML object model. I think it does have an effect on the abstraction, since it would imply that a character is an object, and an object/character is a hotspot.

I think where I differ is that I see these questions mainly as pragmatic decisions about what changes to AGS are worth making in order to make it easier to use, not some attempt to define what the "right" data model is, or to say "this is what a character is, always, in every game". So to take your list of examples, I would pose them differently:

- Is the current way inventories work in AGS fine (making things as easy as possible for the typical-case user while giving those who want something non-standard convenient configuration/work-around options)? Or can we think of a different way to do it that has a better balance of being easy to learn and use, flexible, and not excessively difficult to program/maintain?
- Is there a need for better support for character variations? If so, what kind of AGS feature can we think of that would offer an improvement?
- The distinction between inventory items and room objects is confusing to newbies, arguably leads to extra work in order to implement common scenarios, and makes Kyrandia-style inventory management hard/impossible to implement. Is there some compelling reason why they have to be different things?
- [I wouldn't ask the question about inventory item counts at all, since I don't see an issue that needs to be addressed there.]

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.

Quote from: Monsieur OUXX on Wed 18/01/2012 11:16:50
One of my concerns is that I don't like the word "Object".

I object to that!

Nah, you're right. It's really confusing. Blame the OO guys for taking a perfectly good term for physical things and using it for abstract units of computer code.

Assuming we combine inventory items and objects, what would you want to call that? An item? Entity? Thing? Prop? Article? Element? Thingy?

Wyz

Yes this is not about creating a specification language rather using one. You can actually convert any generalisation to any language given that the language has a few properties, and it can be proven to be consistent. But there I'm already wandering off topic. :D

Abstraction is a trip into the meta world where any entity stand for an (almost) infinite group of things all described by their trades. I also dislike the word object, I call them entities instead.

I'll make a glossary for other terms I might use in the future (my definition):
Atoms: the smallest units in the specification, they are indivisible.
Value: a certain atom or a composition of other values. (there is no way of doing this without recursion ;))
Set: a list of unique unordered values
Universe: all possible values within the specification
Domain: a selection of possible values
Type: a named domain. (it might in cases be useful not to bother describing what is in the set)
Variable: a named 'space' that can hold a value
Typed: variable same but this time it has a type as domain.
Structure: a recipe for an entity, built from variables. Note that a structure itself is also a type.
Entity: a value with as domain one of the structures.

Well I sort have to agree with the UML editors out there, I had a nice one once but it wasn't free. I guess I'll just use ad hoc specification in the meanwhile.

On to the interesting parts:
After having the types of entities defined I feel the need to give them roles. A thing is something that can be lodged in the background, be something that moves around in the room, or something that is carried around in the pocket of a character. Currently they are defined as: hotspots, objects and inventory items, but what strikes me is the fact that the interactions with this thing remains very similar. I think it is safe to assume they are the same entity but have a different role. The role of the thing entity does change parts of the interactivity: As a hotspot they are unable to move, as an object they have a different appearance then when they are contained in the inventory. It might be possible that in different rooms the appearance of a thing is different, or according to where in the room the thing is placed. Also when using the 'look' verb on things that are contained in the inventory might result in different dialogue, since when it is in your pocket you can inspect it closer. Yet it remains the same thing, a pencil will still be a pencil when you pick it up from the perspective of the user (maybe not for the computer developer but that is the wrong perspective).
There is something I like to add to that: A thing might  next to a role also have a state (which also can have a different appearance). This is something that always gives me major headaches when I build games. Let me begin with a simple example:
You have 'a piece of wire' and you bend it so it becomes a 'lock pick'. Stops 'a piece of wire' existing and starts 'lock pick' existing, or do we still see it as the same thing?
I like to think the latter, but here comes a more difficult one:

We have 'a Y shaped stick' and 'a piece of rubber' and we make 'a catapult'. So now we merge two objects into a new one. How the hell to we do that? I think most of the time we will make 'a piece of rubber' and 'a Y shaped stick' stop existing and let the catapult start existing. Ok that is a solution but completely inconsistent with how I handle the previous problem.

There arises a new thing I like to discuss. Let's say we want to make sure our game doesn't have deadlocks, there are beautiful algorithms to do that but we must have to notion that combining the two things give rise of a new thing. With what we have now no system could ever explain how a player could ever get a catapult. But if we do allow the notion to be made somewhere, we actually could. :D

Oh wow there is still lots of stuff I'd like to talk about but this post is already becoming very long, so I'll come back to it later.

edit: Oh shoot, sorry Snarky my timing was most unfortunate
Life is like an adventure without the pixel hunts.

Monsieur OUXX

#9
Wyz: I'm a bit repelled by the first half of your post -- now you're going too far into abstraction: It's a very cold, mathematical approach! And you're using new words to redefine concepts that already exist in most formalization languages (and in extenso in programming languages). We're talking point and click here.

On the other hand you're asking all the correct questions in the second part of your post, about a "thing".

Snarky: On your question about inventories:
- I took the example of Maniac Mansion, because you can switch between 3 characters, and each of them has an inventory.
- You could also imagine several inventories per character (for example, the inventory could be reset to a predefined inventory after a cutscene (when the storyline moves on), or in debug mode -- that would simplify debugging) -- but that's far-fetched.


 

Snarky

Yeah, you can certainly imagine situations where it's useful to have multiple inventories. For example, you could have one inventory for physical items, and another for spells, or clues, or conversation topics, or a diary, or a to-do list. Many games have done that. Resonance has three separate inventories (items, short-term memories and long-term memories - though I'm not sure whether the latter is actually implemented as an inventory) for each of four different playable characters!

Inventories are really just a special case of a particular kind of character state that is useful for many adventure games. I don't think we can (or should) define how it "should" be done, just think of what features AGS can offer that are as useful/usable as possible for as many users as possible.

What might be worth thinking about, OTOH, would be breaking the hard-coded link between inventories as a data structure and inventory windows as an interface element, so that you could lay out arbitrary data the way you can lay out inventories, and also so you could lay out inventories with more flexibility. This would require making the GUI API much more powerful, though (something approaching a simple windowing/widget toolkit).

So the actionable questions, IMO, are:

Is there a way to make the AGS inventory system simpler and quicker to use? (Including replacing it by more generic per-character state.)
Is there a need for better support for multiple inventories per character, or are the existing workarounds acceptable?
If there is a need for multiple inventory support, is there a way to add it that doesn't complicate things for regular single-inventory games?
Should the elements/methods for displaying the inventory be hardcoded, offered as a template/module, or left to the user?

Similarly, to Wyz's scenario, I'd say: let's not worry too much about it. Sometimes it might be most convenient to represent manipulating one item into another item by editing the existing data structure (i.e. updating the item name, graphic, and interaction responses); other times it will be easier to just remove it and replace it by a different inventory item. I'd argue that we should just give the game makers the necessary APIs, and let them do it whichever way comes more naturally to them (though it's probably cleaner and less error-prone to use separate items for each state, so that might be the recommended way).




Personally, I would ideally (in some dream-AGS) want to see all the special adventure game logic moved into discrete script modules, instead of being hardcoded into the engine. So the same way you can load up a LucasArts/Sierra/Verb-coin template now, you could switch out the default "single-inventory" module with one to handle multiple inventories per character. Or you could change how conversations work, or what a walkcycle is, or create new event types.

RickJ

Just s a couple of thoughts:

Game Specification Language
If this concept was expanded to included a directory structure containing all the resources, sprites, backgrounds, sounds, etc, their  import properties/instructions and the scripts that comprise the game, the AGS editor then be able to read/write this file.  The file could then be input to stand-alone compilers to port any given game to different game engine back-ends. 

I believe this is similar to what Clavaron did with XAGE.  It's also a way to work around the license incompatibilities between AGS and SummVM;  there could simply be an AGS-ScummVM compiler and shazamo AGS games are able to run on ScummVM.  Conceivably this could be done with older AGS games even without the source code?

With regard to format,  the obvious first choice to come to mind is XML.  Fell free to opine as to it's merits and/or alternatives.


Game Entity
I like the above discussions about "things' and "game entities" and agree with much of it.  I believe all Game Entities or Entities ought to have some common characteristics:

Resources
Entities ought to be able to "own" resources such as sprites, sounds, music, etc.  Two or more entities can own the same resources.  If an entity is exported it's resources are also exported (this would also apply to it's other constituents as well).  If an entity is imported all of it's constituents are also imported.  From a user perspective it may look like the game contains multiple copies of the same resource but this does not have to be the case.  The game files themselves would contain only one copy and multiple references as is the case now.

Views
Animation is perhaps  a better word? Entities could have 0 or more views or animations consisting of an arbitrary number of loops.  Different views could be set active by the script code. If a character entered the water the swimming view could be activated.  Perhaps multiple views could be simultaneously set active to change clothes or hair-do for example.  This suggests some sort of organizational hierarchy (i.e. folders, groups, or something).  The concept of view should be general enough to include the playing sounds, music, and other resources synchronized to animation or without animation at all.   In light of this perhaps a word like "Composition" may be a better choice? 

Collections
The way to handle inventory is perhaps to just let inventory items be Entities and then allow Entities to contain collections of other entities.  So if a character has a gun, then the gun can have bullets.  If a character has chewed bubble gum and a paper clip in the inventory and then makes a key with those items he will end up with a key in his inventory but no bubble gum and paper clip.  Why?  Because the key now has the gum and paper clip.  I suppose a generalized solution would allow entities to have multiple collections.   You could then of course, as suggested earlier, have GUI components for displaying collections.

Scripts
Entities ought to have the ability to contain scripts.  It could be something like modules are now in AGS and could work in exactly the same way.  The would have the ability to respond to and/or capture events.

Events
Otherwise know as player interactions.  Currently interactions are only defined in for rooms.  Why should not other entities also have the ability to respond to such events/interactions.  In addition it would be nice if there were the ability to handle user defined events where one script could post an event (possibly with data value) which would trigger interaction functions in other scripts.

Dialogs
Dialogs are held between one or more entities.  Participants can be explicitly identified within the dialog or identified when the dialog is initiated, sort of like passing parameters.   Dialogs are owned by entities.  If a room owns the dialog it can only be initiated when the participants are in that room.  If a character owns a dialog then the dialog can be initiated in any room where the participants are present.  The owning entity does not necessarily have to be a participant.

Dialogs usually result in the player learning something or the game changing state (or both).   Perhaps the latter consequence should be enshrined in a standard way.  What if entities were able to have a collection of "Facts"?  Each fact could be a string or unique id# and have a count and %confidence level.  There could be a dialog command called reveal (reveal "fact string" [%confidence]).  If confidence level not supplied then revealing entity's default confidence level is used.  The entity(s) to whom the fact is revealed adds the fact to it's knowledge base it it doesn't exist.  The count is then incremented and then used to calculated a weighted average of the confidence level.  The game programmer can then use these properties however he wishes.  "Conversation" is perhaps a better word than dialog?



Monsieur OUXX

#12
Quote from: RickJ on Wed 18/01/2012 23:33:51
Views
Animation is perhaps  a better word? Entities could have 0 or more views or animations consisting of an arbitrary number of loops.  The concept of view should be general enough to include the playing sounds, music, and other resources synchronized to animation or without animation at all.   In light of this perhaps a word like "Composition" may be a better choice?  

Quote from: RickJ on Wed 18/01/2012 23:33:51
I also think the creation process for characters and (particularly) animated objects is confusing, and involves a lot of duplication of work. In my opinion the concept of "views" should be reconsidered, possibly distinguishing between animation sequences and character views (and allowing more flexibility in which views to provide; including possibly composing views by combining separate sprites/animation sequences), and probably offering some way to auto-generate views/animation sequences from a series of sprites (e.g. in the character/object creation dialogs).

These comments are both essential.

the way I see it, is that animations in general should be very close to Flash's "Movie Clips" concepts :
- An animation should be:
  - a succession of frames
  - each frame can have a different "length" (possibly defined using key frames)
  - There should be a mechanism to customize the loops (repeat once, repeat always, backwards, intertweened, etc.). the way I see it, the "loop" is attached to the animation but not synonymous to it
  - Maybe we should incorporate the tweens natively here
  - An animation can be composed of any number of other "embedded" animations => This is the very delicate part IMO: Should this all be real-time, or pre-rendered? Should there be a flag to let AGS know?
  - I think we could decide to put the sounds and other resources in the animation!

- A view should just be a "label" put on any arbitrary animation, to give it the required status to be used to render a character, or an inventory item, or even any game entity, in a given state. That way, you could see all views in a separate folder, but they're just animations, really.

=======

On a different note: Shouldn't an AGS game be defined as an abstract entity, possibly defined inside another game? (in programming terms: Like an inner class, defined in another class). That would virtually allow to define and run a game inside another game.

That would natively allow mini-games in AGS games. One could import mini-games from other AGS developers into their own games (think "Bernard playing Maniac Mansion in Day of the Tentacle" or "playing arcade games in Toonstruck")

Technical solutions are off-topic, but just so that you see it's possible:
- AGS could run another instance of AGS, then render it onto a Surface that would then be stretched down and drawn into the current AGS game.
- Or you could force AGS scripters to write their game object as inherited from a global "Game" object, so that it's easily imported into another script just by copying the sources (a bit the way applets work)
- etc.



 

Ryan Timothy B

QuoteOr you could force AGS scripters to write their game object as inherited from a global "Game" object, so that it's easily imported into another script just by copying the sources (a bit the way applets work)
Do you mean someone could create a Game object in an AGS application, containing things like: Views, Loops, Frames, Sprites, Dialogs, GUI's, Rooms etc etc (whatever these existing objects get turned into).

So if I were to delete that Game object, all the inner items are deleted. So a game object could simply be a game within the game. Like a super advanced module that contains everything the module would need?

Also exporting or importing would also contain all these items. That would make things super easy for team projects. Especially for things like a mini-game like you mentioned.

Because if that's what you meant, I have a chill running down my neck. ;)

Monsieur OUXX

Quote from: Ryan Timothy on Thu 19/01/2012 16:49:36
Do you mean someone could create a Game object in an AGS application

I'm not saying someone *could*, and I'm not suggesting a way to implement it.
I'm just saying we should anticipate it, at least formally, because it's a possible use case.
 

Wyz

Quote from: Monsieur OUXX on Wed 18/01/2012 15:18:57
Wyz: I'm a bit repelled by the first half of your post
Yeah, don't sweat it, that was the OCD part of me. It is not really all that useful so just skip it. :P

Quote from: Snarky on Wed 18/01/2012 16:41:20
Similarly, to Wyz's scenario, I'd say: let's not worry too much about it.
It is not so much worrying as it is philosophizing. I love to do that, very much.
I kind of share you view to stuff things in modules rather then hardcode stuff. But yeah, it should still remain a tool for building point & clicks so I guess some of it will remain.

Quote from: RickJ on Wed 18/01/2012 23:33:51
Just s a couple of thoughts:
Very nice, that made me think. The generalization of game specification would be really awesome, not easy to specify but definitely worth the while. I like your break down of the entities. The resources are like the atoms the game is build from, if feels really natural to me.
I also like how you defined script as part of the resources, would really well with functional programming languages actually. Events? yes please! This is something I miss the most right now actually. I like for modules to be able to raise events when they have data ready. That would make it more natural for both the plugin developer and user.

Also you might have just come with a solution for the 'merging of things' issue I described. You simply add it as a collection of things to a container thing and have conditionals for what resource is should show. That is beautiful. :D

Quote from: Monsieur OUXX on Thu 19/01/2012 10:48:45
On a different note: Shouldn't an AGS game be defined as an abstract entity, possibly defined inside another game? (in programming terms: Like an inner class, defined in another class). That would virtually allow to define and run a game inside another game.
That would definitely be useful like mini games. If you'd combine that with the kind of game specification format RickJ described you could import games in your own like modules. Very nice!
Well in my original specification there would be only one game entity and it will remain until the game has been won, but this option would be more flexible.
Life is like an adventure without the pixel hunts.

RickJ

Wyz, thanks for the compliment.  Here are some more thoughts.

Game-in-game
The game itself could be an entity and so could have a collection of other games.

Entity (more)
First of all just to be clear.  Entity is pretty much the same as an OO Object/Class or Thing.  Entity is being used for the purpose of this discussion so as to eliminate confusion between language elements, AGS room objects, and Wyz's Things.  

There would be different types of entities of course.  There could be restrictions and requirements for each type.  On such restriction, for example, could be what types of entity collections a particular entity type could have.

As TimothyRyan was saying if an entity is exported then all of it's resources would go with it  Importing an entity then would include all of the needed resources.  There would also be a possibility of importing entities at runtime.  For example, if someone wanted to have an episodic game where episodes are created and released over a period of time.   One could easily imagine an in-game catalog and download system for such a game.  

Game Specification Language
Quote
If this concept was expanded to included a directory structure containing all the resources, sprites, backgrounds, sounds, etc, their  import properties/instructions and the scripts that comprise the game, the AGS editor then be able to read/write this file.  The file could then be input to stand-alone compilers to port any given game to different game engine back-ends.  
Please let me know what you think about having a genar;lized/defined editor output like this.  It think this may be a way to work/cooperate with ScummVM without all the licensing hoopla.  

[edit]
Related thread on ScummVM forum
http://forums.scummvm.org/viewtopic.php?p=71107#71107

Ryan Timothy B

#17
Quote from: Monsieur OUXX on Fri 20/01/2012 14:05:32
Quote from: Ryan Timothy on Thu 19/01/2012 16:49:36
Do you mean someone could create a Game object in an AGS application

I'm not saying someone *could*, and I'm not suggesting a way to implement it.
I'm just saying we should anticipate it, at least formally, because it's a possible use case.

Well of course. That's why I said could. ;)

Anyway, even the possibility of a character class/object? containing these sprites or animation views as well. It would be nice if characters had the option to have their own script as well. They should, shouldn't they? It only makes sense to me. Organization and such.

I even think removing the header script would be justifiable. Having the public keyword on classes is all we would really need. GlobalScript.DoFunction();

Would we really need a Global Script? GUI's shouldn't share the global script. Character's shouldn't. What other need other than repeatedly execute and always, plus on event and other functions. Basically all we would need is a Game script.

Alan v.Drake

Since you've linked that thread, I think it would be dutyful to quote what sev wrote today:

Quote
As of the AGS development, anyone is welcome to come with an engine ported to our framework and according to our standards. Current AGS source code is a mess and has to be refactored heavily. This will lead to two incompatible codebases and if AGS community will continue developing original AGS engine, it will turn into an endless race for the compatibility.

Thus it was told that a feasible approach would be to port 2.x branxh which will definitely not be developed anymore. So far the sources weren't published and such discussions are pointless.

And of course, once the engine is ported to ScummVM and if the community decide to develop the engine on top of our codebase, we're fine with that, however in this case development will be ruled by ScummVM's 6 months release cycle.

I personally hope that AGS 2.x sources will be published because there is number of developers interested in tackling it, and even there is an idea to turn it into a GSoC project if we be accepted this year.


Eugene




Monsieur OUXX

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".

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?

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?
 

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.
 

Wyz

Instead of having a set of behaviours you could also infer this from other states. Let's say we keep track of the location the character is in, we could have conditionals for each script section. So if a event occurs it will check for each script assigned to that script if the condition holds, if it does it will be executed, if not it will be skipped.

Let's say we have a NPC that moves along with the player character. We could have something like this (very much in pseudo code):
Code: ags

void give_lotion()
{
  player.Say("Hey, could you do my back?");
  // ...
}

(...)

npc1.AddEvent('give', give_lotion, player.location == 'beach' && player.holding == 'lotion')



That way the whole inheritance principle will still work, yet it will imho be easier to maintain. You would have to deal with the order of scripts, and one script might stop the remaining scripts to be executes (stop propagating). You can even allow closures on script, an example (again very much pseudo code):

Let's say we have a npc that hates everything:
Code: ags

void hate(String thing)
{
  npc2.Say(String.Format("I hate %s!", thing))
}

npc1.AddEvent('give', hate(player.holding), true)


Just some ideas :D
Life is like an adventure without the pixel hunts.

Monsieur OUXX

#41
@Wyz:
I'm not sure which of those mechanisms is the correct interpretation of what you described :

1. You call "AddEvent" once and for all for a given object (e.g. "npc1"), and then the script given in parameter (e.g. "give_lotion") will be executed every time the event (e.g. "give") is fired. That means the engine computes the objects list that are supposed to react to "give".
2. You call "AddEvent" manually every time you need the event to be caught and propagated -- pretty much like a more elegant and a more practical funciton call.

===

If the correct interpretation is 1, then :

What you're describing is pretty much the concept of Listener, which is actually present in most OOPs, and especially in Flash's Actionscript or Flex (again!).
You introduced a concept of propagation condition, that would itself rely on what we could call "context".

I'm not a fan of the context being defined beforehand (in the listener's instanciation), because that means the condition (e.g. "player.location == 'beach' && player.holding == 'lotion'") will need to be stored somewhere, and then parsed and interpreted at runtime. Technically that brings the engine to a whole new level! Ouch!

I'm more in favor of something simple like it is currently done in AGS :
- The engine detects when an event is fired -- either internally (e.g. "the animation finished"), or because the scripter fired it manually (e.g. "myLoop.StopPlay"), or because of user action (e.g. "click")
- It fires the corresponding function

What I suggest our engine brings is:
a. The ability to define with more accuracy (and dynamically) all the places in which the event can be intercepted (in the global "onClick function" or in any "Behaviours" the scripter wishes to define). This can be done with something similar to what you described, a listener ( npc1.AddEvent("give", give_lotion) ).
b. The conditions are then checked internally to the fired function (e.g inside of "give_lotion: "if player.location == beach"). That's where I differ from your solution: This way we stick to regular scripting and get rid of the need for conditions parsed at runtime.
c. Still within the function, we decide if the event should be propagated to the underlying event handler (e.g. "parentBehaviour.propagateEvent()" ). This would be similar to the way constructors can be overridden or "extended" in some OOP languages like Java (The well-known "super()" function).

===

Yesterday I had that thought that Behaviours could be extended to Rooms (we could keep the concept, except we could rename them "ambiance" or "context"). A "room behaviour" or "context" or "ambiance" would be used as some sort of dynamic template that could store the room's music or anything else that wyou'd like to be shared between several rooms.
Examples:
- The musical atmosphere (relaxed? action scene? a monster appears and the music goes crazy?)
- the characters' reactions (instead of defining them inside global Behaviours and then attaching them to the character at runtime with a line of script, you define attach those behaviours to the room: the "beach behaviour" will be attached to all the "beach" rooms permanently, instead of being attached to the character some of the time).
- The room's shader (night shader, etc.)

This concept of "Room behaviour" (that may contain Character events) brings the need of having a way to define Behaviours precedence (if the same event is defined int he Character's Behaviour(s) and in the Room's Behaviour(s), which one has the priority?)

===

Here is apseudo-code that would summarize ALL the concepts I've dealt with above and in previous posts.
I want to stress that ALL of this script can be translated into easily-readable and editable Editor items (see my previous mockup)

Code: ags

behaviour EveryCharactersBehaviour {  	//if you attach this behaviour to something
										//else than a Character, the event "FinishedWalking"
										///will probably never be fired
	onevent FinishedWalking(character) {
		character.Say("I just finished walking");
	}
	
	onevent ... {	//another event
		...
	}
}

behaviour MainCharacterBehaviour extends EveryCharactersBehaviour { //inherits my generic (yet custom) Characters behaviour
	onevent FinishedWalking(character) {
		super(); 	//you tell the script to also run the inherited behaviour!
					//Therefore, The character will say "I just finished walking"
		character.Say("...And I'm the hero!"); //only cEgo will say that after finishing walking
	}

behaviour NPCBehaviour extends EveryCharactersBehaviour { //inherits my generic (yet custom) Characters behaviour
	onevent FinishedWalking(character)	overrides BeachRoomBehaviour, CityRoomBehaviour {
		//the line above tells the engine that if the same event ("FinishedWalking")
		//is also defined in the listed room behaviours (BeachRoomBehaviour, CityRoomBehaviour),
		//then ONLY THIS FinishedWalking will be run. Otherwise it ALSO fire the FinishedWalking
		//of the room behaviours. If the room behaviours contain "overrides NPCBehaviour", then
		//ONLY THEIR FinishedWalking will be run
		
		
		//"super()" is never called, so the character will NOT say "I just finished walking"
		
		character.Say("...And I'm an NPC!"); //only the NPCs will say that after finishing walking
		
		//the line below shows how you check some conditions INSIDE the event's function
		//rather than defining them beforehand like in Wyz's model
		if (character.walkarea == "sand") { character.Say("...And I'm standing on the sand!"); }
	}

behaviour EveryRoomBehaviour {
	onevent FinishedWalking(character) {
		character.Say("this room looks pretty generic to me!");
	}
}
	
behaviour BeachRoomBehaviour extends EveryRoomBehaviour{
	onevent FinishedWalking(character) {
		//"super()" is never called, so the character will NOT say "this room looks pretty generic to me!"
		character.Say("If I were an NPC, you'd never hear me say that!"); //because BeachRoomBehaviour is overridden in NPCBehaviour
	}
}

behaviour CityRoomBehaviour extends EveryRoomBehaviour{
	onevent FinishedWalking(character) {
		super(); //super() is  called, so the character will say "this room looks pretty generic to me!"
		
		character.Say("...except it's clearly in a city!"); //an NPC will  not say that because CityRoomBehaviour is overridden in NPCBehaviour
	}
}

behaviour UnderWaterRoomBehaviour extends EveryRoomBehaviour{
	onevent FinishedWalking(character) {
		super(); //super() is  called, so the character will say "this room looks pretty generic to me!"
		
		character.Say("...Blblbbllb"); //EVERY Character will say that because UnderWaterRoomBehaviour is NOT overridden in NPCBehaviour and MainCharacterBehaviour
		
		//the line below shows how you check some conditions INSIDE the event's function
		//rather than defining them beforehand like in Wyz's model.
		//this oxygen check will happen in every underwater room
		if (character.oxygenLeft < 0) { character.Say("Oh no I'm dead!"); }
	}
}


...

//ALL THE SCRIPT BELOW CAN BE DONE EITHER DYNAMICALLY IN THE SCRIPT, OR BEFOREHAND IN THE EDITOR:
cEgo.attachBehaviour("MainCharacterBehaviour");
npc1.attachBehaviour("NPCBehaviour");

rooms["MyCityRoom"].attachBehaviour("CityRoomBehaviour");
rooms["myBeachRoom1"].attachBehaviour("BeachRoomBehaviour");
rooms["myBeachRoom2"].attachBehaviour("BeachRoomBehaviour");

rooms["myUnderWaterRoom1"].attachBehaviour("UnderWaterRoomBehaviour");
rooms["myUnderWaterRoom2"].attachBehaviour("UnderWaterRoomBehaviour");

...



Another idea:

Code: ags

//IN THE COURSE OF THE GAME

//Oh noes! The main character has become a zombie/OSD!
//note that I open the possibility of having a "replaceBehaviour" rather than "attachBehaviour".
// "attacheBehaviour" would allow to pile up different behaviours while "replaceBehaviour"
// swaps them.
// Having both "attach" and "replace" would allow to add "aggregation" mechanisms to the "inheritance" mechanisms.
// These are two diferent and complementary approcahes : Search in Google "inheritance versus aggregation"

cEgo.replaceBehaviour("NPCBehaviour");




Another other idea ;)
I'm not dropping the events handling at "event level" rather than "behaviour level", like Wyz suggested. I just didn't detail it.
Both could be complementary.

Code: ags

npc1.AddEvent('give', give_lotion);

 

RickJ

I like the way script modules deal with events and believe it's similar to listeners.  For example, one or more module scripts and the global script can have mouse event handlers.   Event handlers are executed in the same order as the scripts appear in the AGS editor.  Any of the event handlers may prevent further propagation by executing the ClaimEvent() function.  

Now lets suppose we expanded upon this concept.  Imagine that rooms, objects, characters, guis, etc are all sub-classes of entity where each entity can have it's own script and script modules.  A character for example would have a character script and optional modules similar to the way AGS game script is now organized.

Code: ags

gMyGame
     rSomeRoom
          oSomeObject
          hThisHotspot
          cNpcCharacter
     rSomeOtherRoom


Now suppose it were possible to organize entities in a hierarchical structure as shown above and that the player talks to cNpcCharacter.    The TalkTo event handler in cNpcCharacter is executed first.  If the event handler executes ClaimEvent()  then it is not prograted any further.  If there is no handler defined in cNpcCharacter or it it's handler does  not ClaimEvent() then the event is propagated  to rSomeRoom's event handler.  The event is finally proprogated to the gMygame event handler.

Now here is the cool thing about this.  Suppose cNpcCharacter moves to rSomeOtherRoom.  Now if the player talks to cNpcCharacter the event handlers are executed in this order cNpcCharacter, rSomeOtherRoom, gMyGame rather than cNpcCharacter, rSomeRoom, gMyGame.  The context is autoimatically and dynamically changed at runtime.

I think this also covers agregated and inherited functionality discussed above.

[edit]
spelling

Monsieur OUXX

On the one hand I like how your model gives a formal framework for the precedence of events handling (which event is handled first?). That was the part I was thinking my model wasn't making explicit enough.

On the other hand, I really hate everything else about it (it's not personal, read below  :D)
- it's very static (how do you swap the order at runtime if needed?)
- it's like a whole new hierarchy of stuff, transversal to the existing script and objects hierarchy (where do you define this? in a separate text file?) How does it blend with the rest of the Editor/scripts?
- it generates a lot of code duplication, see the example below :

(if I want the room's event handling to have the priority in Room1, Room2 and Room4 but not in Room3 and Room5...Now imagine if you interleave all the event handling of your initial post into the example below -- the number of required lines goes exponential!)
Code: ags

gMyGame
     rRoom1
          cNpcCharacter
     rRoom2
          cNpcCharacter
     rRoom3
          
     rRoom4
          cNpcCharacter
     rRoom5
        



I'm totally OK to be proven wrong on all this.
 

Wyz

Your posts have made me think about event handling and I'm not sure what I would think is best so instead let me respond to some other aspects.

I think we are generally on the same page about the events but it is down to how the pie gets cut.
I've spotted three ways of how event propagation is handled now:
  • Explicit, by calling the next event from the first one fired (M. OUXX)
  • Implied, user specified (me)
  • Implied by the structure (hierarchy) (RickJ)

    well I think those mentioned are all somewhat quirky in ways, we might be able to do this better. Let's recall how AGS does this currently: every event can be mapped to a function, if it is not mapped there is a single fallback event that gets fired. This behaviour is very useful for adventure games, but we might be able to generalize it a bit more.
    Let's assume we have one big set that contains all possible events in a game called Events. We can immediately name subsets like: player events, room events, screen events, sound events. We can divide it some more: npc1 events, 'lotion' events. We can divide it differently: 'give' events, 'talkto' events, 'interact' events. This said let's see how an user would like to map these events.

    Say a user would like for each character he tries to give the lotion this person would respond the same.
    Code: ags
    
    function default_give_lotion()
    {
      this.Say("Get lost freak!")
    }
    

    However there is one person, np1, who takes the lotion. (see give_lotion)
    So what would be convenient? There are two ways that immediately pop up in my head:

    1) Let each event map only one function, that way you can first map 'default_give_lotion' to the Events subset 'give' and afterwards you replace np1's 'give' event with 'give_lotion'.

    2) We allow every event to have an ordered list of functions, the first one will be executed regardless. When this one finishes the next will be called, unless the first one asks for a propagation stop 'ClaimEvent', etc.
    Now we simply add 'default_give_lotion' to the 'give' events, and 'give_lotion' to np1's 'give' event.
    Next we let 'give_lotion' call 'ClaimEvent'.
    The only think that is left to do is make sure the order is right. Either we directly order the event list or something a bit more genius: you can actually order the functions themselves by simply letting the users say: 'this function is more important then that one'. It works really intuitive if you'd ask me, but I might be wrong so discuss!  :D

    Well, I only named two methods however there are infinite possible methods, but this gives you something to think about. :)
Life is like an adventure without the pixel hunts.

RickJ

@Monsieur OUXX:  No, no, no you you are missing the cool part of this.  The structure is static at design time and changes dynamically at runtime.   So the following only means that rSomeRoom has cNpcCharacter when the game is first started.  
Code: ags

gMyGame
     rSomeRoom
          oSomeObject
          hThisHotspot
          cNpcCharacter
     rSomeOtherRoom


However, when cNpcCharacter moves to rSomeOtherRoom we can then say that rSomeRoom no longer has cNpcCharacter and that now rSomeOtherRomm has cNpcCharacter like this.
Code: ags

gMyGame
     rSomeRoom
          oSomeObject
          hThisHotspot
     rSomeOtherRoom
          cNpcCharacter


Now consider what happens when there is an inventory item, iSomeItem, and the player character in rSomeRoom.  We can say that rSomeRoom has iSomeItem and cPlayerCharacter like this.
Code: ags

gMyGame
     rSomeRoom
          iSomeItem
          oSomeObject
          hThisHotspot
          cPlayerCharacter
     rSomeOtherRoom
          cNpcCharacter


Now suppose the player clicks PickUp on iSomeItem.  The event handlers are executed in the order iSomeItem, rSomeRoom, gMygame.  Further lets suppose one of the handlers moves iSomeItem from rSomeRoom to cPlayerCharacter.  So now we would have the following structure.  
Code: ags

gMyGame
     rSomeRoom
          oSomeObject
          hThisHotspot
          cPlayerCharacter
               iSomeItem
     rSomeOtherRoom
          cNpcCharacter


Now clicking on iSomeItem would execute event handlers in the order iSomeItem, cPlayerCharacter, rSomeRoom, gMyGame.  

If cPlayerCharacter moves to rSomeOtherRoom the rSomeOtherRoom would have cPlayerCharacter which would have iSomeItem like this.
Code: ags

gMyGame
     rSomeRoom
          oSomeObject
          hThisHotspot
     rSomeOtherRoom
          cNpcCharacter
          cPlayerCharacter
               iSomeItem


Now event handlers execute in the order iSomeItem, cPlayerCharacter, rSomeOtherRoom, gMyGame.   And if the player dropped the item in the current room then we would have the followoing and event handlers would execute in the order iSomeItem, rSomeOtherRoom, gMyGame
Code: ags

gMyGame
     rSomeRoom
          oSomeObject
          hThisHotspot
          cPlayerCharacter
               iSomeItem
     rSomeOtherRoom
          cNpcCharacter
          cPlayerCharacter
          iSomeItem


@Wyz:  I agree with you that the three of us are trying to achieve the same ends but and are struggling to find a simple and elegant means.  After reading your comments and thinking through the above example some more things or quirks come to mind.  

When you were talking about categorizing events it occurred to me that  one event could have a number of interpretations.  For example, a LookAt cursor click on iSomeItem could be interpreted as "LookAt iSomeItem", "LookAt any item", "LookAt anything", "Mouse Click", "?".    It seems to me none of us have addressed or even mentioned this situation.  I think generally what happens now is that we get a generic LookAt event and then in the event handler we can lookup what is under the cursor and then use a giant if-else thing to decode the event to whatever degree of specificity  is required.  It would be nice if we could come up with something better.

I haven't given this a lot of thought but to move the discussion along perhaps I can pickup from what Wyz said about classifications.  
Quote
Let's assume we have one big set that contains all possible events in a game called Events. We can immediately name subsets like: player events, room events, screen events, sound events. We can divide it some more: npc1 events, 'lotion' events. We can divide it differently: 'give' events, 'talkto' events, 'interact' events. This said let's see how an user would like to map these event
.  

Perhaps it's all in how we name events?  Suppose events were named in a hierarchical manner, from general to specific.  So to answer my own question we would have the following possible interpretations of a mouse click on iSomeItem

  • Mouse
  • Mouse.LookAt
  • Mouse.LookAt.Item
  • Mouse.LookAt.Item.iSomeItem

    Event handler functions could be declared something like the following. All of these would respond to a the LookAt iSomeItem event.  The handle keyword informs the compiler that these are event handlers so that it can use the function name to connect the function to the actual events.  This would negate the need for all that pointy and clicky stuff and would mean that events could be added or removed simply by cutting or pasting  snippets of script code.  The pointy and clicky stuff could be retained but would only be a wizardly thing that pastes an appropriate template into the script.

    Code: ags
    
    handle Mouse(button id, entity type, entity id) {
    }
    
    handle Mouse.LookAt(entity type, entity id) {
    }
    
    handle Mouse.LookAt.iSomeItem(ntity type, entity id) {
    }
    


    There was one other issue I had with my first examples and I am not sure of the correct answer.  In the case of events such as LookAt, PickUp, etc that are actions being performed by the player character, I wonder if the player character's script should have first crack at handling the events?   If the answer is yes then when there is a LookAt iSomeItem when player character has iSomeItem the event will be propagated to cPlayerCharacter twice.  What to do about that?  

    [edit]
    Monsieur OUXX I hate you for making this interesting thread and I hate Ryan Timothy for making all the pretty pictures!  Damm you guys!  :'(  ;D   No, just kidding of course.  

    Here is a document I made over the last few days and thought you (MX, RT, WZX, et al) may enjoy looking at.  I'm sorry for PDF but that was the easiest way to get a web viewable document from my version of Visio.

    http://img28.imageshack.us/img28/9957/entityconcept.pdf

Monsieur OUXX

#46
Bumping

-- so that everybody can enjoy (and discuss) the PDF produced by RickyJ (at the end of his previous post).

EDIT:
WOW! I HAD NO IDEA THERE WAS SO MUCH MATERIAL PRODUCED, AND SEXY WITH THAT! (I opened the file only after mentionning it)
RickJ, I hope to be able to comment on that ASAP.
 

Ryan Timothy B

I have no idea where to begin with commenting on Rick's PDF of ideas but it's pretty close to how I would like to see the future AGS. I hope to comment more on it some other day when I have more time.


But for now I have been thinking of scripting and how to allow more advanced players to get under the hood.

For example, where Character.Say is a standard function with AGS, you could actually create your own Character.Say function that overrides the default AGS function like so:
Code: ags

public override void Say(this Character c)
{
  //whatever we now want Say to be instead
}


The only tricky part is how to decide which script is the master script that gets the override. That's assuming you had 2 modules with an override Say function.

What would also be nice is being able to have a partial function for other purposes.
Code: ags

public partial void Say(this Character c)
{
  ACharacterHasSaidSomethingThisManyTimes++;
}

etc..

Alan v.Drake

#48
Quote from: Ryan Timothy on Wed 08/02/2012 05:16:06
I have no idea where to begin with commenting on Rick's PDF of ideas but it's pretty close to how I would like to see the future AGS. I hope to comment more on it some other day when I have more time.


But for now I have been thinking of scripting and how to allow more advanced players to get under the hood.

For example, where Character.Say is a standard function with AGS, you could actually create your own Character.Say function that overrides the default AGS function like so:
Code: ags

public override void Say(this Character c)
{
  //whatever we now want Say to be instead
}


The only tricky part is how to decide which script is the master script that gets the override. That's assuming you had 2 modules with an override Say function.

What would also be nice is being able to have a partial function for other purposes.
Code: ags

public partial void Say(this Character c)
{
  ACharacterHasSaidSomethingThisManyTimes++;
}

etc..

I strongly support overrides,there are many cases when we'd need to redefine the default behaviour of functions like Say or Think and it would keep the code clean and compatible.


- Alan

monkey0506

Currently AGS doesn't allow any form of function overloading. Once a function is declared with a specific name within a specific scope then no other functions can take that name, and if the function in question is in the global scope (and declared first) then it's even impossible for scoped/member functions to take on that name. That would be a huge step forward for the engine if we could do this.

However, overloads and overrides would both rely on the compiler, unless you're going to just dynamically regenerate the function names...a bit of regex magic and that could work, but it would be more of a workaround than a fix.

Monsieur OUXX

Quote from: monkey_05_06 on Wed 08/02/2012 16:04:19
Currently AGS doesn't allow any form of function overloading.
overloads and overrides would both rely on the compiler. a bit of regex magic and that could work

It's not about AGS can or can't do, it's more about how things should be shaped (not even the UI nor the script, but just the concepts).
 

Ryan Timothy B

#51
Edit: Rewrote my post and added some more

Script Extension:
If we were to have scripts for each element like Characters, GUIs, Rooms, Inventory Items. We would need a way to access the Public script functions and elements but only ones that are Public.
So I was thinking a "Script" extension for each Class would be most logical.

For instance accessing room script elements:
rBeach.Script.doFunction();
rBeach.Script.thisIsAStruct.count++;

And obviously objects and such should be accessible even if you're not in that room:
rBeach.oDesk.doExtenderFunction();
rBeach.hPainting.doExtenderFunction();

Then for Characters:
cJoe.Script.JoeHasTalkedToBilly = true;
cJoe.Script.doFunction();


Inventory:
That "Display multiple icons for multiple items" shouldn't be the end all option. It should be item specific. If I had the item Coins, I wouldn't want multiple coins in my inventory. But if I had the item Mug, I may want it to show every mug I have, just like in Monkey Island.

One possiblity is to have inventory items like a Class. So if you had 3 Mugs, they all have their own copy of the variables and such from within the script. So iMug[0].Script.Health  would be different from iMug[5].Script.Health  (Health being an Integer variable)

So that could be one way you manage inventory items better. Where an inventory item 'could' have a repeatedly execute always, if needed. Then you could count down the Health of each Mug as the Grog in it eats away at it. Changing the graphic of the Mug item.


Obviously the Script extender wouldn't be accessible to the ID class. Character[1].Script  wouldn't be allowed. Since accessing the functions and elements for a character would only need to be done for that individual object only.
You'd just use the main script for each element type to make an extender function, or struct, or whatever that would work for all objects.

Ryan Timothy B

Actually the same could apply for characters and their master script. Since all character share the master script but also have the ability to have individual scripts, the master script could act as the additional Class for each character.

So you could then assign Variables and such to all characters in the master script.

cJoe.Script.TalkedThisManyTimes  !=  cBob.Script.TalkedThisManyTimes

That's one way to sorta add to the Character Class. Either that, or you could just allow Partial to work with the Character Class.

Crimson Wizard

Don't know where to put this... while there are lots of discussions regarding theory of making adventure games, it does not look like there's any discussion held regarding making game framework anymore.
Just wanted to share little thoughts I had in the past, hopefully adding my "2 cents" to this thread.

Localization viewed as generic asset substitution

There was time when I thought localization is all about translating text resources, and the program simply needs a dictionary that would find a string by some key - either numeric ID or other string (usually - text in original language). But it appeared to be not true: sometimes you need to change other resources too, such as sounds (if there's a voice recorded) or images (if it contains text). Also, when translating UI texts you may meet a need to change layout of elements inside window, because translation does not fit well in the original one.
If one will go further, he will naturally come to a thought, that every asset in the game may be viewed as a target for localization. The question is only in what is defined an "asset". If the hypothetical "framework" we are observing has literally everything inheriting some basic type and its properties, then everything is an asset, which may contain other assets, forming a tree like structure. Imagine now, that you can create localization as a set of rules which replace only certain assets in this tree.

What does it give to us? Obvious thing is replacing strings and speech audio clips. But there are special cases when replacing string by string does not solve a problem. What if there's a joke that sounds well in one language and does not in another? Game developer / translator may find a substitution that requires slightly different staging: two lines instead of one, adding certain animation to emphasize the meaning, and so forth. In most difficult case devs could be unable to find proper translation, and if the joke is not an important part of a story would not it be simplier to cut the joke from certain localization completely? In such case we may need to deal with game script. Now, what if the script is an asset, and a part of the script (the function, event handler) that plays a joke is an sub-asset of the script: the localization rules may replace the part of the script or completely disable it.

Considering further, is the localization the only reason why we may want to change something in the game? Of course, there may be a need to change controls and GUI depending on platform you run the game on. Or difficulty setting, disabling certain puzzles.
Finally we come to concept that localization itself is just a sub-type of the generic asset substitution: a set of rules that define how game resources are replaced by some switch or a combination of switches.
Instead of writing zillions of conditions in the script, for example, such as "if language is Spanish, then replace the image on the wall" or "in case of legal German localization remove the blood from animation", it is better to have some kind of "configuration" rule for the game.
In the tree of assets we could have another layer per every configuration, possibly inheriting each other, that add, remove or replace assets in the parent layer they inherit.


Monsieur OUXX

Quote from: Crimson Wizard on Fri 28/02/2014 12:17:18
it is better to have some kind of "configuration" rule for the game. In the tree of assets we could have another layer per every configuration, possibly inheriting each other, that add, remove or replace assets in the parent layer they inherit.

I understand perfectly what you mean. Did you just come up with that, or do you think this theory has been explained and studied somewhere else before? That might typically be the kind of thing that has a name, and also has some implementations somewhere out there provided you know its name.
 

Crimson Wizard

Quote from: Monsieur OUXX on Fri 28/02/2014 23:09:37
Quote from: Crimson Wizard on Fri 28/02/2014 12:17:18
it is better to have some kind of "configuration" rule for the game. In the tree of assets we could have another layer per every configuration, possibly inheriting each other, that add, remove or replace assets in the parent layer they inherit.

I understand perfectly what you mean. Did you just come up with that, or do you think this theory has been explained and studied somewhere else before? That might typically be the kind of thing that has a name, and also has some implementations somewhere out there provided you know its name.
I can't say the idea is totally mine, you can find this kind of mechanism all around, perhaps not precisely as I depicted here. The virtual functions in class hierarchy, the build configurations which apply extra options on top of "default" ones, etc. The name? hmm... don't know. "Subtyping" and "inheritance" maybe.

Snarky

No offense intended, but in line with my general skepticism towards making everything virtual and abstract and so on, I'm not convinced this asset localization concept is a good idea:

Yes, you could do that, but translation and voice packs already take care of most of the cases; it's pretty easy to write code to switch out some graphics (of which there will probably only be a few that need modifying anyway); and if you're going into modifying animations and things like that, you're going to have to delve into the existing code anyway, so is this really any easier than just putting in a simple branching check?

And even if it does make the job easier (let's say that it cuts down the time to package a translated edition of a full-length game, after all the assets and translation files have been prepared, from six hours to two hours), is the intersection of people who need to produce sophisticated localizations of their games and those who are interested in using AGS as their engine significant? Or are you talking about putting all this effort into a feature that will maybe save a couple of people a few hours of work a handful of times?

The cost â€" beyond just the effort of implementation â€" is adding a layer of complexity in the editor and engine, and introducing this whole notion of abstract assets that can be instantiated by different actual assets in each variation, which is an irrelevant consideration for 99% percent of people using AGS. Meanwhile (and I know I keep going on about this), Unicode support is a pressing need for which there isn't a good workaround, and the lack of it is actually stopping people from producing games in other languages. If we want to address localization, that's the  one feature that really matters.

But of course, this is just my opinion.

Crimson Wizard

#57
Sorry, I did not mean to suggest this for AGS in its current state, I was speaking about hypothetical system. I also did not mean that's a pressing issue.
That was a talk about hypothetical design made from scratch.

Generalization requires to spend much more time on planning, but saves much more time during actual development (and further extension).

Snarky

Ah, in that context it makes more sense, sure. What I seem to remember reading some other game engines do, is that they have all their assets stored in a directory hierarchy on the disk, and then for alternate game versions they just have a copy of that directory hierarchy, with files that override the original if present.

So for example, if my default assets are stored in "My AGS Game/assets", and a particular sprite is "My AGS Game/assets/graphics/rm_street1/sign.png", then its German replacement might be "My AGS Game/alt_versions/German/assets/graphics/rm_street1/sign.png". You could potentially do the same thing with a whole GUI. Any asset not found in the current alternate path would use the default. You wouldn't really need to worry about it in the IDE itself.

As for relatively small changes within a larger script (like adjusting an animation), I still think the most straightforward thing is to just put in a branching path in the code.

SMF spam blocked by CleanTalk