Now that the engine has had its source opened up, it seems to me that it might be a good time to start getting an idea of what people most want to see updated in the engine. This means anything that has to do with the run-time component of your game. Design-time requests should go to the Editor Wishlist thread. ;)
There's a few that I would really like to see, but I haven't yet had a chance to look at the engine source at all. That with the fact that we've already been told that there are underlying complications for the ones that I will be suggesting might mean they still will require some time before they can be implemented. In any case, I think it's good for people to have a common place for this that we can post to so we can get an idea of what the most people want.
So:
- Dynamic limits!!
Specifically I'm thinking of things like inventory items and controls per GUI, and room objects. Room hotspots are based on a bitmap still, so that would require even more work, but these other items could presumably be looked at.
Thoughts: For compatibility with existing scripts, we would still need some way for the user to easily get the "highest used amount of XXX". For example, many scripts that I'm aware of use the algorithm for mapping a GUI ID and GUIControl ID to a single array index. That algorithm is dependent on a static number of maximum GUIControls per GUI. If the user could still read the maximum number actually used by any GUI at run-time, then dynamic arrays would be sufficient. This is something that will have to be dealt with for compatibility, and simply for the usability of this algorithm in new scripts.
- Dynamic Arrays..improvements
Dynamic arrays are great, but they're rather limiting as of right now. We can't read back their current size, there are no standard functions for working with them (of course that's somewhat related to no support for type-casting), and we can't have dynamic arrays within a struct. These are improvements that I'd like to see. Also, some sort of constant should probably be defined like AGS_MAX_DYNAMIC_ARRAY_SIZE (the current value is 1000000).
- Pointers to custom types
It's already possible for the engine to create single, static pointers to custom types, as evidenced by member functions and extender methods (which use the 'this' pointer). Opening it up for users to create dynamically typed pointers and assign them values has been a concern for some time though, particularly in preserving the game state for save games. I'd like to propose that we take a look at the existing garbage collection (which works great) and see what can possibly be done to open up the possibility of pointers to user types.
- Object-orientation
It's true that not everyone is a fan of the OO programming model, but the majority of the functions/properties in AGS are object-oriented. I'd like to see what we can do to clean up some of the older properties/functions to bring them into conformity with this OO model, for consistency sake.
- eEventEntersRoomAfterFadein and eEventQuitGame (or game_quit, game_end, etc.)
These two event types have been proposed for inclusion in the EventType enum and to be fired off appropriately by on_event, but they haven't been implemented yet. They would certainly make things a bit simpler for us programmers!
I think that's about it for now. So if you have any ideas, feel free to submit them here, and show your support for the existing ones. Also, any C++ programmers with access to the source should chime in if they've managed to make some way in including any of the suggested items!
P.S. Don't forget to thank CJ for opening up AGS so we can all work together to make it even better!!
Amen, thanks CJ for this awesome opportunity!
I was thinking, regarding the dynamic limits, I think we should really try avoid a solution where those limits are fixed upon compile. I agree that removing the editor limits would be first priority, but for a long-term solution I think it would be worth the effort to make the system stay dynamic at run-time. To be able to create say a character or GUI simply through script would be a godsend for module scripting.
Edit: I'll have to dust off my C++ skills this summer, but among the things I'm gonna try to implement on an experimental basis now that the source is released are two new classes: Scene (a "virtual room" class which allows stuff like split-screen, instant room transition, and allows you to manipulate scene properties without usin the other-room module), and Layer (which are dynamic objects similar to Overlay but can be displayed behind objects, characters and walkbehinds). If it seems viable to implement them in the engine I suppose Layer could serve the purpose that I imagined for dynamic characters/objects in the original post.
Amen, for the last one brother!! I'm not sure whether this whole opening source business is a good thing, but only time will tell, but the lift of dynamic limits sounds amazing.
Quote from: monkey_05_06 on Fri 29/04/2011 12:06:07
eEventEntersRoomAfterFadein and eEventQuitGame (or game_quit, game_end, etc.)
These two event types have been proposed for inclusion in the EventType enum and to be fired off appropriately by on_event, but they haven't been implemented yet. They would certainly make things a bit simpler for us programmers!
Those look pretty easy to implement.
looking at the source the AGS runtime runs run_on_event ([a #define for the event], [data to pass]);
So we just need to add the event number the enum in the source and run that method in the source at the correct times.
I'm not sure if the compiler would need to be open for that to work though.
Also I daren't actually change anything in case I mess something up so ya know :D
Dynamic Control of Areas
An idea that was tossed about a few times and that I have been of proponent of would be the ability to use drawing functions to manipulate WalkableAreas, Regions, etc. from within the script. I think in some cases this could make changing regions in game easier and less jury-rigged than predefining every possible region in the room editor (though in other cases it would probably just make things more complicated, since scripting is a little like working in the dark). It could also make it possible to regularize how you use walkable areas and such, so for instance if you wanted to use WalkableArea 2 for wood floors and WalkableArea 3 for shallow water, and then test for them in a global script and set walking sounds and animations accordingly, you could do this and still be able to change walkable areas at run time without messing up your system. Granted, this could probably be approximated using properties, but it wouldn't be quite as efficient.
The key use, though, would for things like procedurally generated content and times when you want the player to be able to affect the room environment in a dynamic way.
Drawing Functions
Some drawing functions that could be implemented using the script but would end up potentially causing massive slowdown if used frequently might be nice to implement in the engine as well. The two that come to mind off the top of my head would be:
DrawingSurface.ColorFill(int x, int y)
which would work like the bucket tool in most paint programs, changing all adjacent pixels of the same color to DrawingColor.
and the probably more useful,
DrawingSurface.ReplaceColor(int color)
replaces all pixels of color with DrawingColor. Could be useful for imitating some palette functions in 16 bit and 32 bit color games.
Properties
Also editing object/region/character properties in the script, seems to get brought up a lot. I know there are good workarounds and I think Chris said that changing this would actually be non-trivial, but if we have more people working on it.
Pathfinding
And I think it would be good to have access to pathfinding in the script. Things like:
Paths.IsPathViable(int from_x, int from_y, int to_x, int to_y)
returns true if character will be able to reach the desination point, given the walkableAreas and other obstacles recognized by the pathfinder. Otherwise returns false.
Paths.NumberOfWapoints(int from_x, int from_y, int to_x, int to_y)
returns the number of waypoints (places the character will change direction or stop) between the starting position and ending position of the path, including the stopping point in a path that will not reach its destination.
Paths.GetWaypointX(int from_x, int from_y, int to_x, int to_y, int waypoint)
Paths.GetWaypointY(int from_x, int from_y, int to_x, int to_y, int waypoint)
return the x and y coordinates of a given waypoint
There are instances when I would like to know exactly where a character is going to walk beforehand.
Views
A way of getting the number of loops in a view and the number frames in a loop would make VewFrame functions and properties a lot easier to play with without crashing the game.
How did I miss that? Thanks, Monkey.
A) A Macintosh version that's up to date. It would make a huge difference in my engine decisions if I knew I could use AGS and make a game for both PC and Mac.
B) A version that allowed games to play embedded in a web browser.
I thought of a few suggestions, what do you think about these?
1) Merging Calin's alpha plugin into AGS so you no longer need the plugin would be cool!
2) No more problems with alpha channels with the GUI's + buttons (yay!)
3) Have alpha-blending/semi-transparent/translucent sprites working for our text windows
4) Merging Helios' customProperties Helper into AGS so we dont need the plugin
5) Making AGS games work on the IPhone/IPad (quadruple yay!) *dont even know if this is possible
6) Making ViewFrame.Speed not read-only
7) Dynamically drawing over Gui's/Overlays that draw over gui's (?)
Quote from: Lyaer on Fri 29/04/2011 21:24:47Views
A way of getting the number of loops in a view and the number frames in a loop would make VewFrame functions and properties a lot easier to play with without crashing the game.
You mean like:
int viewCount = Game.ViewCount;
int loopCount = Game.GetLoopCountForView(VWALKING);
int frameCount = Game.GetFrameCountForLoop(VWALKING, 0);
Granted, none of those are referenced in the ViewFrame Functions and Properties page in the manual, but the latter two functions are both referenced in the entry for Game.GetViewFrame.
Quote from: General_Knox on Fri 29/04/2011 23:35:09Dynamically drawing over Gui's/Overlays that draw over gui's (?)
I'm not entirely sure that I'm understanding you correctly, but it's possible to create dynamic overlays/GUI background graphics using the DynamicSprite and DrawingSurface functions. What more than that are you looking for with this exactly?
Thanks a million for this great opportunity CJ!
I think a good start would be to 'update' the code, forgive me this word but as Pumaman mentioned himself, some of the code may be old and not compatible with the future changes we're planning to implement.
If we could give the code a refresh, including the suggestions about OO complete rework, without breaking the engine, then we would have a solid basis to work on for any new features.
I'm still trying to compile the source properly, when I do, I'll be glad to share my opinions and ideas.
Quote from: General_Knox
I thought of a few suggestions, what do you think about these?
1) Merging Calin's alpha plugin into AGS so you no longer need the plugin would be cool!
That, or we could go for pixel shaders! I've seen the engine itself already uses them put it would be cool to expand them or even allow users to implement their own shaders.
Quote from: General_Knox
5) Making AGS games work on the IPhone/IPad (quadruple yay!) *dont even know if this is possible
If we switch to Allegro 5 that might actually be possible! However there is still a long way to go I figure.
For now linux and mac are already really feasible. (with still some stuff that is obvious to break, but in many cases not vital like the game explorer and avi support). The games built with AGS can be stored as .ags files and these should potentially be platform independent. :D
Mac support should be a priority since it wouldnt require that much effort (relatively speaking) and the mac platform is much more relevant now than 12 years ago.
I've mentioned a slew of serviceable features before (Hotspot.SetDescription(); writable property, etc) but I think adding anything on top of the engine's accumulated disorder isn't particularly forward thinking or wise.
I propose two very important steps that I think need to be considered.
These obviously precede other development tasks.
The status quo:
a) CJ warns that AGS is a mess. There is one trunk currently (as I am aware) and it's simply not in a state where it would be practical to write new features into the code mix.
b) Backwards compatibility is to be preserved. This also correlates to the above.
The logical steps:
a) Clone the engine into a second branch. Branch 1 = AGS 3.2.1 / Branch 2 = AGS 4.0
b) Tidy the engine from the inside out. Lay foundations for additional branches for other platforms.
The aftermath:
a) Clean code, new AGS (no immediate backwards compatibility support necessary)
b) Gather feature requests from forums and add them to an official developer wiki with a voting/like button beside each feature listing for anyone involved with AGS.
c) Developers with commit rights to SVN were awarded those rights because they were trusted to expand on AGS for the general community. These individuals can of effortlessly refer to the neat dev-wiki to draw a clear priority list for feature implementation.
d) Investigation begins for exploring backwards compatibility possibilities for AGS 4.0.
These are just a few suggestions, but it is abundantly clear to me that we really need to introduce a reasonable level of coordination for I've mentioned a slew serviceable features (Hotspot.SetDescription(); writable property, etc) but I think adding anything on top of the engine's accumulated disorder isn't particularly forward thinking or wise.
I propose two very important steps that I think need to be considered.
These obviously precede other development tasks.
The status quo:
a) CJ warns that AGS is a mess. There is one trunk currently (as I am aware) and it's simply not in a state where it would be practical to write new features into the code mix.
b) Backwards compatibility is to be preserved. This also correlates to the above.
The logical steps:
a) Clone the engine into a second branch. Branch 1 = AGS 3.2.1 / Branch 2 = AGS 4.0
b) Tidy the engine from the inside out. Lay foundations for additional branches for other platforms.
The aftermath:
a) Clean code, new AGS (no immediate backwards compatibility support necessary)
b) Gather feature requests from forums and add them to an official developer wiki with a voting/like button beside each feature listing for anyone involved with AGS.
c) Developers with commit rights to SVN were awarded those rights because they were trusted to expand on AGS for the general community. These individuals can of effortlessly refer to the neat dev-wiki to draw a clear priority list for feature implementation.
d) Investigation begins for exploring backwards compatibility possibilities for AGS 4.0.
These are just a few suggestions, but it is absolutely abundantly clear to me that we need to introduce a reasonable level of coordination to open source movements that concern us . The same checks and balances apply across the world of open-source developments and should largely apply to AGS as well.
I love all the enthusiasm, I'm beside myself with excitement right now, but I force myself for good reason to sit back for a brief moment and ground the impulses of unstructured desire to add more stuff. There are things to do before this becomes a practical reality.
Yes I pretty much agree with that, I had exactly the same thoughts. After I compiled it and I knew that part would be no problem it is time for me to study the code, and only after I understand how it all fits would I start actually coding stuff.
I think we should first ready the code for multiple developers working on it. I also think breaking backward compatibility for a while with a new branch and adding things in gradually is the logical thing to do. I'm in for doing code refactoring and working on a future branch. We should however get organized. How do we do that?
I think since the engine and editor are now open source, the best thing to do is to also open up a new development forum to discuss further implementation options and code structure.
I agree, there are a few things that need to be done before porting or adding features to AGS. For instance:
1) Code needs to be cleaned up more so for better understanding and better porting/implementation.
2) Code needs to be documented and commented better.
3) A plan needs to be discussed as to how to maximize portability of the Engine source.
4) Another plan needs to be in place to discuss what kind of ports will be created and how the engine should function to obtain that portability.
5) A user group of CJ, Steve Mcrea, Elektroshocker and others should be established as to lead and maintain the project.
6) A standard should be set as to how new features will be implemented so that they achieve maximum portability and stability.
Personally, I feel that the main focus for AGS before implementing new features is to clean it up, optimize it and be sure it can run on other operating systems. New gaming features can be added after. After all, the engine can already do anything we need it to. We just now need it to be playable on other systems.
Free access to all room elements from within any room. Objects, Hotspots, Walkable areas, Regions, etc.
Eg: room[2].object[4].Visible = false;
That would definitely be very nice. That way you wouldn't require the needless global variables and such just to turn off an object for another room, or whatever element you're doing.
Of course though, you'd run into problems with room numbers not being in numerical order.
I'm not sure how well it works with the most recent versions, but Steve's OtherRoom module of course provides functions for working with the "room elements" from other rooms.
In any case, it would be nice to implement this at some point I suppose. So, that being said, as far as rooms not being in numerical order, you could have something like this:
readonly static int Game.RoomCount
Returns the actual number of rooms this game uses (regardless of actual room number).
readonly static int Game.RoomID[int index]
For index 0 to (Game.RoomCount - 1) returns the actual room number of the specified room.
Then you could do:
room[Game.RoomID[2]].Objects[4].Visible = false;
Wouldn't it be possible to have two pointers, where:
roomID[301].Object[4].Visible = false;
and
room[1].Object[4].Visible = false;
Could actually point to the same thing?
Well I think you've reversed the meaning from my post (where the RoomID would return the actual room number of the Nth room), but something along the lines of what you've described would be possible if the rooms were actually opened up this way.
Yes, I understood your idea of having roomID[] being the numerical order. I just think roomID[] would make more sense to have it access the rooms in the non numerical order while room[] would act in numerical order just as object[], hotspot[], etc, currently work. It only made sense to me.
Edit: Actually I think I'm the one who's confused. Your method seems to be the better method. I guess I didn't see the Game.roomID
My bad. :P
I think we should move away from global arrays towards an OO pointer system
i.e
Room r = Room.GetRoom(roomID);
Object o = Object.GetObject(roomID, objectID);
You don't necessarily need functions like that in order to implement this in an OO-compliant way. That's what properties and indexers are for (which the MSDN defines as being functions! :P).
So maybe even:
readonly static Room* Game.Rooms[int roomNumber]
Returns the Room identified by ROOMNUMBER. Uses actual room numbers; you can use Game.RoomID to get the room number of a given room sequentially.
Then we could do:
Room *room = Game.Rooms[roomNumber];
Object *obj1 = Game.Rooms[roomNumber].Objects[objectID];
Object *obj2 = room.Objects[objectID];
I know that internally it would be working out the same anyway, but it just looks and feels nicer to me. Of course this (at least as shown for obj1) would also be dependent on getting the compiler error fixed that prevents access of non-static members of static members.
As an interesting side-note, aside from the fact that I'm proposing linking these items into the Game structure statically, this (meaning the static properties and indexers) would even be feasible from the standpoint of a module, so presumably it would be rather easy to implement.
Perhaps looking at the core for portability might be a good way to go. I don't know how much effort it would be to recompile to OSX but it would be nice to have a Mac engine again. The lack of an OSX engine is the only reason I have shied away from using AGS. Otherwise, IMHO, AGS is the best game development kit available. :)
I've been working on developing the demo of my Playlist module, in the style of a fashionable media player :=, and I've come across a couple points that I would like to see about having implemented in the engine if possible.
Currently there is no generic way of accessing the game audio. I would very much like to be able to do this so that I could allow the user to save playlist data to an external file. Since there's no generics for AudioClips though, I can't really do that. So, I'm proposing the following:
readonly static AudioClip* Game.AudioClips[int index]
Returns the AudioClip* indicated by the specified index. Useful if you need to loop through the audio in the game for some reason, such as via a module.
readonly int AudioClip.ID
Returns an integer ID associated with this AudioClip, for use with the Game.AudioClips array.
This would allow me to save the AudioClip.ID to the external file, and when reading it back in, use Game.AudioClips to get an AudioClip* again. Currently I could create a custom ID based on the clips that have been added to a playlist, but I would have no way to read it back as an AudioClip*.
Also, I would find it useful for my purposes if audio files could be loaded dynamically. The basic structure would be very similar to the existing AudioClip structure, with the following additional functions (including the ID property I suggested above):
static DynamicAudio* DynamicAudio.CreateFromFile(String filename, AudioType)
Loads an external audio file FILENAME into memory, and gives it the specified AudioType. AudioFileType is automatically determined by the file type of the loaded file.
IMPORTANT: This command loads an extra audio clip into memory which is not controlled by the normal AGS audio cache and will not be automatically disposed of. Therefore, when you are finished with the image you MUST call Delete on it to free its memory.
IMPORTANT: If the DynamicAudio instance is released from memory (ie. there is no longer a DynamicAudio* variable pointing to it), then the clip will also be removed from memory. Make sure that you keep a global variable pointer to the clip until you are finished with it, and at that point call Delete.
void DynamicAudio.Delete()
Deletes the specified dynamic audio clip from memory. Use this when you are no longer using the clip and it can be safely disposed of.
You do not normally need to audio clips, since the AGS Audio Cache manages loading and deleting audio clips automatically.
However, when an extra audio clip has been loaded into the game, via CreateFromFile, then AGS does not delete it automatically, and you must call this command instead.
NOTE: This command will set the IsAvailable property for the clip to false. You can use this property to make sure that the clip has not been deleted before playing it.
I might actually consider seeing what I could do to offer some of the same functionality via a plugin since I don't have access to the engine source at the moment...anyway, feel free to comment on the suggestions. :=
None of that is possible really since the plugin API has been neglected for quite a while (because it's rarely used i imagine)
The plugin API doesnt expose any of the new audio system (or any of the D3D functions either much to my chagrin)
On the topic of D3D, I'm in the project of reworking/optimising the D3D rendering engine of AGS so I can put a post-processing feature (meaning setting a Backbuffer in D3D mode). Put so far I'm trying to understand all the settings and what calls what.
On an interesting side, implementing Overlays' Transparency was extremely easy, since it was already there, but unused.
I was going to try and do something ridiculous and script some native AGScript functions and register them as a header, but I can't get the C# plugin API to work at all. Even the example code is producing a run-time explosion for me in the engine.
Even if it isn't possible via an engine plugin, this was originally an engine suggestion anyway. :P
However, I came across PlayMP3File which was apparently replaced by AudioClip.Play. That seems like a regression in the capabilities of the engine. The DynamicAudio type I suggested would be a better replacement for the function than AudioClip.Play since the latter can't load external files at run-time.