This is aimed at explaining once and for all what I mean every time I try to express some concerns regarding what I sometimes call "vector abilities", sometimes "3D geometry", sometimes "subpixel transformations", etc.
Ah, great explanation, thanks!
Yes, it's a valid concern against OpenGL which I was not really aware of. I'll need to study it more.
By game production pipeline I meant that the work of the project leader, game designer, artists and scripter don't overlap.
Here is how they sometimes overlap in AGS :
- Every time you add a sprite or a room, it modifies game.agf or some other central set of files. Conflicts cannot be resolved easily.
So that's another reason for me to switch to dotnet core, their csproj supports globbing patterns so you don't have to specify specific files that are included in the project (it's possible that mono supports the new csproj too now, btw, not sure). Besides the csproj there's nothing else so there would be no conflict here.
- If a sprite changes on the file system, you have to reimport it --> you have addressed that. (by the way, make sure that room backgrounds are not managed separately -- AGS keeps them in a black box, unlike sprites)
Room background is not separate. All assets are treated the same (at least when developing): files in the file system.
- if you add or remove a sound, it creates its corresponding name in the script. It breaks compilation if you remove the sound. (the sound artist's work conflicts with the scripter's work)
Hmmmm, that's a touchy subject. I understand your concern, but on the other hand named assets are also important for intellisense and avoiding typos. It's currently not a problem but it might be when I develop the editor- I'll think about how to address that when I get there.
About the GUI : I strongly recommend that you use a thirs-party library, and that you don't implement GUIs yourself! Home-made GUIs are the plague of many game frameworks. There's always a moment when scripters want to extend the behaviour or aspect of a GUI control, and then they can't because they can't hook on the controler events or graphical containers, or can't make sense of the rendering flow. And then you will have to carry that weight. Have you ought about GTK?
Yes, I thought about GTK# among others. I have two problems with that:
1. I want to be able to have the GUIs as part of the world, meaning I need to control when and where to render it with OpenGL. So that pretty much rules out all GUI libraries that are not OpenGL based. The best GUI framework I found for OpenGL is
nanogui, which I still consider my fallback plan if my current plan doesn't work as I want. The problem with that is nanogui's c# binding looks abandoned which means that I'll need to maintain the binding myself, plus get a deep understanding of nanogui workings and I tend to believe that the weight this will carry on me is not smaller then have my own framework in place. And also, this doesn't solve my second problem...
2. So, what Crimson Wizard said here:
Now, at any point in time you add CanBeOnGUI behavior, and boom, character becomes a GUI element, while retaining everything else, walks among the buttons and talks to labels.
I'll basically lose this ability for GUIs if I follow that route. The fact that GUIs in the engine are treated the same as all other objects and can be manipulated the same, I feel that's a great power for the engine to have.
Therefore, be careful with "anonymous" fields used by Protobufs/Protocontract.
Just to be clear here, protobuf is just used for the saved games file format, that's it.
I suggest even more than previously the use of automatic solution generation, since I saw that you have one .sln file per target platform.
mmm, no? I only have one sln file. Are you talking perhaps about the csproj files? I have a csproj file per platform, not a sln file per platform. I'll have to read about cmake for c# more, I'm kind of hesitant because I didn't see any c# project actually using it yet (but maybe it's because it's new, based on your link). There's a known solution for the multiple projects per platform in the c# world:
Protobuild- it's used by both MonoGame and Xage, so I'm more inclined to use it. However I'm still not convinced that the added dependency (be it protobuild or cmake or something else) and the cost that goes with it is worth the multiple projects "pain", maybe it's because I haven't experienced that pain yet, currently I kind of like that clean separation between projects. Also protobuild does not currently support dotnet core as far as I know- I did want to play with it at some point to gain a better understanding of the benefits, but I don't consider this a priority. If another contributor will come and want to add something like that, I'll probably not going to stop her/him though (except for the dotnet core issue...).
- I'm kinda worried that there are platform-dependent wrappers for every core feature, such as drawing, input, etc. Isn't that managed by OpenTK? Or is it only some "transparent" wrapping meant for some basic C# trick (make advantage of interfaces or whatnot)?
For graphics rendering, OpenTK supplies OpenGL bindings and OpenGL ES bindings. Those are not the same unfortunately. So I have 2 implementations of "IGraphicsBackend", the OpenGL one is used by desktop (Windows, Mac and Linux), and the OpenGLES one is used by Android & IOS. And I'll probably need yet another implementation when I add UWP (xbox and windows store) which will either be DirectX or Angle. For input, OpenTK handles it cross-platform for desktops but not for mobile: I use the xamarin APIs which are native representations of the android and ios APIs, but they are not the same. I might switch in the future if I find something.
For bitmap and text rendering, I also currently have 3 implementations (desktop, android and ios) but I want to switch to
SkiaSharp which is completely cross platform (and also gives a lot of other benefits like hardware accelerated text rendering). Currently stuck on
this, btw: if somebody knows/figures out how to solve this, let me know.
- I would suggest taking the opportunity of this engine rewrite to put some distance between the absolute core point n' click engine (rooms, inventories, etc.) and the things that might be custom. Two examples from the top of my head : the hard-coded fade-in/fade out as seen in RoomEvents.cs, and the player's behaviour on Verb events as seen in Player/Approach. I'm not saying you should kill all that, I'm just suggesting that you imagine what could be this "less hard-coded layer of code", and that you move those things there after creating the required event hooks in the core.
Yes, I'm discussing solutions with Crimson Wizard. However... rooms are not adventure game specific? Room = Scene, and every game engine on the planet (I think) have this concept. The "OnBeforeFadeIn/OnAfterFadeIn" events for moving in/out between scenes is also generic and not adventure game specific.
- event hooks! event hooks everywhere! E.g. OnNewItemInInventory
MonoAGS has event hooks a-plenty. All lists that are marked as "IAGSBindingList" have an "OnListChanged" event which gives all the items that were added/removed from that list. Good call on the inventory items though, as I didn't change it from "IList" to "IAGSBindingList" yet, will fix.
Also, all components implement "INotifyPropertyChanged", which you can subscribe to and get events whenever any property in the component changes (this is how the inspector refreshes itself to show you whenever something changes in the game).
- Have you considered an importer for an existing AGS 3.4 project?
I suspect it's going to be crazy amount of work. If somebody else wants to work on it, that would be great. I'm not going to, though, not in the foreseeable future.
- You have re-implemented all the usual classes such as lists, dictionaries, events, trees (you're literally using C#!), point, rectangle (you're literally using OpenTK!), etc. I won't complain because everyone does it (ScummVM, etc.), but... what is it with you people?
lol, yeah, it looks bad...
My core engine library targets dotnet standard which means I can target both dotnet framework, mono or dotnet core.
OpenTK is still not officially supported with dotnet core (it's in progress), meaning that the core engine can't reference OpenTK, only the desktop engine project can reference it. So I had to copy a bunch of their classes to make it work. Once they support dotnet core I'll be able to remove those.
For drawing bitmaps, I used stuff from System.Drawing which is also not part of the dotnet standard so I had to take dotnet framework code. Once I switch to SkiaSharp I'll be able to remove those.
And finally, my binding list is not taken from c#, it's my implementation that's there for adding those hooks you mentioned earlier which don't exist in the original list implementation. And tree is also my implementation,
there's no tree data structure in c#.
@tzachs, a question for you : why did you put emphass on functional languages in the docs? did you have some advantage on mind regarding the making of a game with your engine?
I don't think I did? I just listed F# as potentially the best candidate if you want to code your game using something not c#, because I know it's a dotnet implementation that is actively supported by Microsoft, and I'm not sure how actively maintained and complete other dotnet implementations are (everything else afaik is developed by the community and not sponsored by major players, I might be wrong about that).
- One big big concern: the IDE as it is now, and even if you intgrate an "editor" as an in-game GUI, the game development workflow would be to run and debug the game from within Visual Studio. Even if it's a free Visual Studio, we can't redistribute it, which means that we must tell the users to download two separate things: 1) MonoAGS, and 2) Visual Studio. For me that's a no go. Any solution would be better than that -- like swapping to SharpDevelop or MonoDevelop. An answer that comes to mind is : "no, you misunderstood, first you compile the game in visual studio but then you can distribute the unfinished game to develop it 'from within itself', as some sort of standalone Editor" --> that doesn't sound like a good solution, because then you can't change (and recompile) any custom script inside it as long as it travels outside of visual Studio.
Ok, so I guess it's time to talk about my plans for the editor (important note - everything here is subject to change and might not actually happen).
First, regarding your concern: I'm hoping to distribute the editor in several flavors: the standalone version will come bundled with the dotnet cli but without any IDE. Like persn said, you'd be able to use pretty much any ide you want (you can program in notepad if that's what you want) with that. That's pretty much the equivalent for unity.
Other flavors would be as IDE add-ins, and I'm planning to target Visual Studio and MonoDevelop (hopefully all flavors will share as much code as possible between them), though that's probably not going to happen for the first version (version 0.1 coming sometimes this decade to your home). The MonoDevelop addin can be packaged together with MonoDevelop and distributed. For the visual studio flavor, yeah, you'll want to download VS first and then download the AGS extension.
Regarding what you said earlier about hard-coded verbs: the plan is for the editor to have somewhere a place to edit your list of verbs (or you'll use a game template which has the verbs pre-set). The editor will auto-generate a "Verbs.cs" file with your verbs, and the core engine itself will not have knowledge about specific verbs.
You'll also be able to edit your outfits and choose which animations are part of that outfit, those animation names will also be auto-generated to a cs file.
As for the animation editor, I plan to have a basic layout like AGS has with individual frames and live preview, but also will have a "switch to timeline" button: this will place your frames on the timeline, and you'll be able to add tweening for properties (shown on separate tracks in addition to the frames), and possibly set various blendings. And one last thing for the animation editor would be to allow for composition animations -> show the entire object tree so that you'll be able to have separate animations for the head and body (for example) and see how they work together.
For the room/scene designer, I plan the canvas to have a similar interface that InkScape has for moving/rotating/scaling objects (with grid lines/snapping for alignments etc) and for editing areas something similar to InkScape vector tools as well. In the tree view of the scene you'll be able to show/hide/lock/unlock layers or individual objects, and selecting an object will show the inspector (called "Properties Window" in AGS but the same principle, pretty much exists in all editors). From the inspector you'll be able to set values and add/remove components. You should be able to switch between "playing the room" to "editing the room" immediately (I hope), or maybe even editing while playing. You'll be able to see and edit the GUIs from the scene designer (they might not "belong" to the scene, but it's just that more convenient to see how the game will actually look from the editor). When adding a new object to the canvas you'll be able to select from various presets (object, character, button, etc): each preset is basically an entity with a specific set of components and defaults. The presets that are available for you to use will be dictated by the game template you choose, or you'll be able to create your own presets (or import from modules, etc). This is kind-of similar to prefabs in unity (but not as powerful- will probably extend this to be as powerful eventually). For each of those presets a friendly interface will be auto-generated for your coding pleasure (so you'll be able to write "character.Walk" instead of "character.GetComponent<IWalkComponent>().Walk").
For events/interactions- my observation here is that for most adventure games, most of the interactions are basically the player character says something in response for looking/interacting with an object in the room. Really, I don't think I'm exaggerating if I say that's 75% of interactions in a typical game is just that. That's why, I want first to make this as painless as possible. If you type on a object/verb combo line in the editor, it would automatically translate into player.Say(..whatever you typed..). Otherwise you'll have either the current AGS option of going straight to code, or you'll have the option to open the interaction editor. The interaction editor might be similar in some ways to what Blade Coder has. At least for the first phase, I'm not planning to have graphs with nodes a-la articy/draft, but a list of interactions with if/else branching as indented, we'll see how it goes and maybe I'll re-evaluate. The functions in the interaction editor (like the properties from the inspector, btw) will have help links directly in the editor (it will be extracted directly from the api documentation for built in functions/properties, and extracted from code attributes for external modules). You should be able to run code from the interaction editor and to run saved editor interactions from the code. Also, the interactions themselves will not be hidden, code will be generated for you so this can also be seen as a learning tool. And finally, I plan to have async/await support directly in the interaction editor. Hard to explain without a picture, but basically if you add a "Walk", for example, it will add an "await" with "walk" on the same line, but then you'll be able to drag the "await" section to its own line and put other actions between the "walk" and the "await" so you can have the character walk in parallel to other things going on in this cutscene.
Another interaction related feature I want to have is a "matrix" window. This aims to be a productivity enhancer for writing interactions in bulks and also to solve the problem of a lot of games (that drives me crazy) where the developer forgets to code all of the interactions. The matrix window will have all interactable objects + inventory items as both rows and columns. Each cell is an interaction that has to be filled. You'll have a nice "you're 64% there!" label showing you how much of the interactions are done. And you'll be able to click on each cell to edit the interaction (with any of the methods I talked about for interactions), you'll also be able to mark specific cells as "default" (which will activate that whatever "I can't do that" default interaction you configured) or as "bug: not supposed to happen" (which will also activate the default interaction but might do something else like crashing you if you debug, or send an email from a tester or whatever you set it to do on "bug"). You'll have some controls for filtering the matrix to specific rooms/only inventory/etc if it's getting too big and/or you want to focus on something specific. And finally, you'll have a "start marathon" button which will rotate between "unfilled cells" with easy shortcut keys to pass to the next interaction.
As for speech, this is also a big pain-point for me with current AGS. I still want to support the current workflow, but also have a speech control window (maybe somewhat similar to the speech center plugin), and you won't be forced to number your speech lines in the code yourself, the string itself will be the id and map to a numbered filename (or filenames for multiple localilizations), though you'll be able to override with a number for specific lines (like if you have multiple lines with the same string but need to be said differently). You'll be able to write director notes in the speech window for specific lines, and create nice looking scripts for voice actors. Also, there will be a "start marathon" button here too, you'll select a character and it will run over all of the script lines for that character and open the speech line editor. From the speech line editor you'll be able to record the voice and do basic editing. When recording you'll have keyboard shortcuts to stop this take and start a new take, and a shortcut to move to the next line. For editing you'll be able to trim beginning/end of takes, change volume/pitch/reverb. You'll be able to delete takes, and keep multiple takes (for repeating sentence where you might want some variation in how a character says a line). I still painfully remember the amount of time it took to get the independently recorded lines from the voice actor, open a big-ass audio software where all I want to do basically is select the good takes, and then do some trimming and volume adjustments, then manually exporting to files, figure out the correct filename and then needing to test it in the game to see that I completely screwed it up... This whole process took ages. Hopefully doing it all in-editor will save huge amounts of time.
Another interesting possibility here that I want to explore, is being able to open the speech line editor directly as you're playing the game. So, for editing, the game developer will be able to edit lines while playing the game which gives better context. For recording, if the voice actor is recording remotely, the game developer might prepare a few saves where the character speaks, and either instruct the voice actor what to do to get to her/his lines, or even code to directly cut to the dialogs. If the voice actor is recording with the developer in a studio, then hopefully the game developer could bring her/his laptop and hook it up to recording hardware, and switch to the saves/coded dialogs while showing the monitor to the voice actor. The goal here is that the context of the actions will be much clearer to the voice actor as the dialogs are played.
I'm going to skip various other things the editor needs (editing settings, deployments, fonts, cursors, and I maybe forgot lot of important points), but one last point I want to touch on is customizability.
There are obvious customizations you can expect, like authoring your own components and being able to edit their properties in the designer.
But more than that, as the editor will be using the same framework as the engine, it will use the same mechanisms for customizations the engine uses: meaning, almost everything should be able to be replaced if you want. You'll be able to code your own inspector if you so choose and replace the existing inspector (and then share it as a module for other developers), etc.
Overall I would like to congratulate you for how compact is your code.
Also, kudos for using async/await.
Thanks
