Trying out MonoAGS (AGS 5 candidate) : journal

Started by Monsieur OUXX, Wed 02/05/2018 14:56:42

Previous topic - Next topic

cat

I'm sure I just missed some documentation somewhere but I can't find it.
I created a new solution and added my game projects as well as Api, Engine and Engine.Desktop projects from the git submodule. But I get an error that autofac is missing. I don't have the packages folder that I have in my other checkout. What do I have to do to get it? It is not checked in, so there has to be some other package management.

tzachs

How did you create your game project?
Did you create a project with visual studio or copy the project from the demo game?
The thing is, the demo game is using an older project format which has some issue where packages from dependencies are not properly copied to your folder.
I already converted the demo game to the new format in one of the dev branches which should resolve the issue, I haven't pushed it to master yet.
So if you copied the project from the demo game, this might be the same issue. You can work around it by either converting your project to the new format, or directing the engine project to compile to the same directory as your game, or manually copy the dll to your binaries folder.
If, however, you created the project using recent visual studio, then I'm not sure what's going on, and I'll need to investigate further (so if you're ok with sending me your project I can take a look).

Monsieur OUXX

Quote from: cat on Thu 10/05/2018 20:47:35
I'm sure I just missed some documentation somewhere but I can't find it.
I created a new solution and added my game projects as well as Api, Engine and Engine.Desktop projects from the git submodule. But I get an error that autofac is missing. I don't have the packages folder that I have in my other checkout. What do I have to do to get it? It is not checked in, so there has to be some other package management.

Because some of the projects have evolved since then and you need to add references to Autofacs and System.ValueTuple (and possibly Guilabs.Undo). These are not mentionned in the docs.
However they are not simple Assemblies/DLLs. They are NuGet packages, so to add them you need to right-click on "References" in Visual Studio, and select "Manage NuGet Packages" (please indicate if this option is not present). Then in the new panel that opens you need to select the "browse" tab, and in the search box type "Autofacs". Once you find the reseult, click on "Install". Do it again for the two other packages.

If you find that they are already installed, then you need to force Visual Studio to re-download them (because it doesn't like sources and packages to be moved around). The simplest way is to delete the ".nuget" folder from your project (not in Visual Studio, on the actual hard drive).
 

Monsieur OUXX

#83
Everything present in the quote below has been resolved by now.
Spoiler

About my issue with loading a resource.
Let's start the simplest way possible : what method should I call to open a single file present on the hard drive? I'm not talking about good old File.Open, Im' talking in the context of MonoAGS (where there's the resources system inbetween me and the files, and I don't know if I'm on a desktop or on an Android device).
Point me to that one single instruction.

Is it simply Game.Factory.Resources.LoadResource(path) ? But then how does the engine know if it's a resource on disk or an embedded resource? Can it be both in one game or is it resoved from the path or...?
EDIT: OK I see it : it's in ResourceLoadder.cs::LoadResource. Any resource that returns null from any resource pack is ignored. So it's definitely the path that tells a "proper" resource from an invalid resource. Could you give an example of path that allows to load from an embedded resource?
EDIT 2 : OK, by using breakpoints I found one : "DemoQuest.Desktop.Assets.Fonts.pf_ronda_seven.ttf". So that's an embedded resource. I don't know how they work. I see the resource in the Solution Explorer at DemoQuest.Assets.Fonts.pf_ronda_seven.ttf (no ".Desktop"). So at runtime the path is updated with the current system running the game. Oh well. I'll deal with that later.
[close]
EDIT 4 : This is actually still extremely confusing to me, because to load the font you call game.Factory.Fonts.InstallFonts("../../Assets/Fonts/pf_ronda_seven.ttf") (which is a physical path in the file system) but then with my breakpoint I see that it's the EmbeddedResourcesPack that ends up doing the job, using the embedded path I mentionned (DemoQuest.Desktop.Assets.Fonts.pf_ronda_seven.ttf). What's the point then?
 

Crimson Wizard

#84
Quote from: Monsieur OUXX on Thu 10/05/2018 22:52:43
Let's start the simplest way possible : what method should I call to open a single file present on the hard drive? I'm not talking about good old File.Open, Im' talking in the context of MonoAGS (where there's the resources system inbetween me and the files, and I don't know if I'm on a desktop or on an Android device).
Point me to that one single instruction.

Is it simply Game.Factory.Resources.LoadResource(path)

Yes.

Quote from: Monsieur OUXX on Thu 10/05/2018 22:52:43
? But then how does the engine know if it's a resource on disk or an embedded resource? Can it be both in one game or is it resoved from the path or...?

The idea is that the user of IResourceLoader does not know, and should not bother about where the resource actually comes from.
Resource loader will look into several places until it finds the resource you asked.

It is up to game developer to configure possible places to look, and their priority.
This is how it's done in DemoGame:
Code: sharp

game.Factory.Resources.ResourcePacks.Add(new ResourcePack(new FileSystemResourcePack(AGSGame.Device.FileSystem), 0));
game.Factory.Resources.ResourcePacks.Add(new ResourcePack(new EmbeddedResourcesPack(AGSGame.Device.Assemblies.EntryAssembly), 1));


This is also like AGS currently works: it first looks for a file in the directory, and then for a file embedded in the game package.

Quote from: Monsieur OUXX on Thu 10/05/2018 22:52:43
EDIT 4 : This is actually still extremely confusing to me, because to load the font you call game.Factory.Fonts.InstallFonts("../../Assets/Fonts/pf_ronda_seven.ttf") (which is a physical path in the file system) but then with my breakpoint I see that it's the EmbeddedResourcesPack that ends up doing the job, using the embedded path I mentionned (DemoQuest.Desktop.Assets.Fonts.pf_ronda_seven.ttf). What's the point then?

This is not the physical path. It is a virtual path in a virtual filesystem. This may be __used__ as a path on disk, relative to game.exe, or as a path inside a ZIP archive. The path may be also converted someway into another form, if particular implementation of resource loading requires it.

Monsieur OUXX

#85
Can you explain how the virtual file system works?
Basic questions:
- is the root folder the execution folder?
- is this file system before or after the resource was loaded? (in other words : is it a path to target a resource, or a path invented after the resource was loaded, made to give us a clue of where it was found?) OK this one is obvious, it's the path before loading, since it's the one you provide to Installfont.
- can you give a correspondance of a path for an embedded resource and this virtual file system? OK, InstallFont anwsers that question too : It turns the virtual path "../../whatnot" into an embedded resource path. I'm still not clear about the correspondance between the very real (and changing) execution folder (which requires to add "../.." to go back to the solution's root folder) and the resources root folder.
 

Crimson Wizard

#86
Oh, ok, you struck out couple questions. The last one is -

Quote from: Monsieur OUXX on Thu 10/05/2018 23:34:25
- is the root folder the execution folder?

Either location of exe, or "current working directory", and TBH that's kind of annoying. I believe there should be a way to configure this.

I had to invent a trick, because path may be different depending on whether you run the game from Visual Studio or from explorer.
What I do is that I pass a part of path as a command line argument when debugging the game, as "../../Assets/". And in game code I assign this argument to a variable called "_baseAssetFolder", which I use to construct resource paths.

By default _baseAssetFolder is just "Assets/", so that you could put Assets folder to same directory where exe is, and run it normally.

My best hopes are that in the end this is what resource loader's implementation will be doing on its own. So that we would have to type just "Images/room.png" instead of "../../Assets/Images/room.png".

cat

#87
Quote from: tzachs on Thu 10/05/2018 21:16:13
How did you create your game project?
I created a new empty solution with VS. I then added a new empty game project and a game.Desktop project from visual studio. I created a local git repo for it and included a git submodule of MonoAGS. Then I added AGS.Api, AGS.Engine and AGSEngine.Desktop to the solution using VS.
When I build the solution, I get the following message:
QuoteSeverity   Code   Description   Project   File   Line   Suppression State
Error   CS0246   The type or namespace name 'Autofac' could not be found (are you missing a using directive or an assembly reference?)   AGS.Engine.Desktop   D:\Daten\MonoAGS\Games\CorneliusCat\MonoAGS\Source\Engine\AGS.Engine.Desktop\AGSEngineDesktop.cs   4   Active
AGSEngine.Desktop has a reference to Autofac, while AGSEngine has Autofac as nuget dependency.

Quote from: Monsieur OUXX on Thu 10/05/2018 22:49:04
Because some of the projects have evolved since then and you need to add references to Autofacs and System.ValueTuple (and possibly Guilabs.Undo). These are not mentionned in the docs.
However they are not simple Assemblies/DLLs. They are NuGet packages, so to add them you need to right-click on "References" in Visual Studio, and select "Manage NuGet Packages" (please indicate if this option is not present). Then in the new panel that opens you need to select the "browse" tab, and in the search box type "Autofacs". Once you find the reseult, click on "Install". Do it again for the two other packages.

If you find that they are already installed, then you need to force Visual Studio to re-download them (because it doesn't like sources and packages to be moved around). The simplest way is to delete the ".nuget" folder from your project (not in Visual Studio, on the actual hard drive).
I assumed that this is nuget related. But didn't know how to tackle it. I now did as you suggested (the broken autofac reference was then replaced by a working one and there is now a newly created packages folder in my solution) and I can compile now.

The question is: Why did I have to do this in my new solution with the git submodule but not in the original checkout of MonoAGS? Because there I magically have the packages folder already and the references work.

Edit: I realised that re-installing autofac did not cause any pending changes in the repo, i.e. just the packages folder was created. When I do a clean checkout, is there a command I can run on nuget to automatically retrieve all missing packages? I think this is the actual step that was missing.
Edit: re-installing autofac did actually cause a change to the submodule, which I of course don't want.

Monsieur OUXX

#88
Quote from: cat on Fri 11/05/2018 09:10:43
The question is: Why did I have to do this in my new solution with the git submodule but not in the original checkout of MonoAGS?
To put it simply: NuGet is black magic ;) Sometimes the packages are considered "up to date", sometimes they need to be "restored" (9 times out of 10 : when you moved a solution or when it's your first build in a newly-downloaded repo). A bit like in the old days when you needed to Clean your VS solution from time to time, for mysterious reasons. (Well I'm sure it's not that mysterious for people who know things, but I'm sadly not one of those).

If I'm not mistaken, NuGet packages are excluded from the commits. That's one of the reasons why they're successful these days. That's by design, so that your commits don't mixup your actual code and the random changes in third-party binary libraries.

So, you ask "how to restore them"? There are some command line instructions that you can perform from the NuGet Console (Tools--> Nuget Packge manager--> Package Manager Console), but then again as I've said before, normally deleting the .nuget folder forces a clean restore. The .nuget folder is just a storage folder where VS puts the packages.
https://docs.microsoft.com/en-us/nuget/consume-packages/package-restore

 

Monsieur OUXX

#89
Quote from: Crimson Wizard on Thu 10/05/2018 23:42:40
You wouldn't have any tips by any chance on how to extend the ResourceLoader to, let's say, detect the list of subfolders

I'm getting a headache trying to do extend some classes functionalities without modifying directly MonoAGS's code. The reason is that tzachs used "private" everywhere instead of "protected"! Is there a specific reason? I thought that nowadays, "protected" was more common than the very punishing "private".
Because of that, I cannot derive any class from the engine's classes. Or if I do, I have to rewrite all the helper methods exactly as they are in the parent class instead of just calling them.
PS: if you read closely all the good practices about "protected" vs "private", people say "member variables should always be private, not protected"... but then they say "it's ok if accessors are protected". So I'd say : make everything but member variables protected.
 

cat

I really don't know what happened to my VS installation. First I had problems with the SDK not installed, and now there is something wrong with nuget. In the options I have Allow NuGet to download missing packages and Automatically check for missing packages during build in Visual Studio checked but it is simply not done during build.

Monsieur OUXX

Quote from: cat on Fri 11/05/2018 10:43:48
I really don't know what happened to my VS installation. First I had problems with the SDK not installed, and now there is something wrong with nuget. In the options I have Allow NuGet to download missing packages and Automatically check for missing packages during build in Visual Studio checked but it is simply not done during build.

Have you deleted .nuget? I know I've said it several times but you've never confirmed that you tried. Sometimes it's not about the package being missing, it's about VS not expecting that specific file (with stuff like the encryption key jumping into the issue). So you need to delete it and force VS to re-download it.
 

cat

#92
.nuget is a checked-in folder of MonoAGS, in my solution I don't even have one. I'm not sure how deleting it would help, besides, the config in there has nothing to do with autofac. I don't have a local .nuget file/folder in my project.

For testing purposes I checked out a clean copy of CW's MonoAGSGames repo and tried to build it. I get the same problem here.

Edit: Another thing I tried: I checked out another clean copy of the original MonoAGS solution. This I can build and run without problems ???

Monsieur OUXX

Quote from: cat on Fri 11/05/2018 12:36:19
.nuget is a checked-in folder of MonoAGS, in my solution I don't even have one. I'm not sure how deleting it would help, besides, the config in there has nothing to do with autofac. I don't have a local .nuget file/folder in my project.

For testing purposes I checked out a clean copy of CW's MonoAGSGames repo and tried to build it. I get the same problem here.


If you don't have the folder it means that the NuGet packages are not there. Have you tried following the steps I described earlier about how to include Autofac and two other packages from the VS interface?
 

cat

#94
I can install Autofac from the nuget manager, but this causes a change in the MonoAGS repository.

Also, could you explain what the difference is between dependencies (as seen in the solution explorer for AGS.Engine) and references (as seen for AGS.Engine.Desktop)?

I'm sorry for so many dumb questions, I haven't been working with C# for a few years now and obviously I'm not up-do-date anymore.

Edit: It might be something related to paths i.e. where the packages folder is created. One of the changes I see in the diff when I install the nuget package is related to the location of the packages folder.

Monsieur OUXX

Quote from: cat on Fri 11/05/2018 12:50:55
I can install Autofac from the nuget manager, but this causes a change in the MonoAGS repository.

Is it a big deal? Are you planning on not only commiting your changes in the engine itself, but pushing them too?
If you just want to change things in the Demo Game, then really create your separate repository (I think it's what you've done).

Quote from: cat on Fri 11/05/2018 12:50:55
Also, could you explain what the difference is between dependencies (as seen in the solution explorer for AGS.Engine) and references (as seen for AGS.Engine.Desktop)?
Conceptually it's different but from your end-user perspective it's pretty much the same thing. From memory, if you right-click it takes you to the same "add reference" dialog anyways.
 

cat

I just edited while you posted. I'm investigating paths now.

It's not about big deal, it's just weird and shouldn't be like that. After a clean checkout during rebuild all resources should be fetched and the solution built.

I have a separate repository for my game and MonoAGS as submodule. In contrast to CW I plan to have a separate repo for each game and not one for them all.

Crimson Wizard

#97
Quote from: Monsieur OUXX on Fri 11/05/2018 09:44:09
You wouldn't have any tips by any chance on how to extend the ResourceLoader to, let's say, detect the list of subfolders

I'm getting a headache trying to do extend some classes functionalities without modifying directly MonoAGS's code. The reason is that tzachs used "private" everywhere instead of "protected"! Is there a specific reason? I thought that nowadays, "protected" was more common than the very punishing "private".
Because of that, I cannot derive any class from the engine's classes. Or if I do, I have to rewrite all the helper methods exactly as they are in the parent class instead of just calling them.

No, I was not investigating that code much.
Question about possible inheritance is something that tzachs should answer, as an author.
Extending game objects is supposed to be done rather using custom components, but idk about other utility classes.

PS. Whan you say "extend ResourceLoader" do you mean actually Loader, or ResourcePack implementation?
Thing is that, if you create your own modification based on one of manager classes, such as ResourceLoader, you will have a hard time keeping in sync with the engine in future, or it will be difficult for users of your library to use it in their games.
If you think that these changes could be useful, maybe suggest them to the engine code? Or, perhaps, think of some interface that engine could use, and you implement.

Monsieur OUXX

Quote from: Crimson Wizard on Fri 11/05/2018 14:20:32
do you mean actually Loader, or ResourcePack implementation?
Well it would actually have to be both : ResourcePack has to be implemnted in as many flavors as there are potential file systems, but then it's really ResourceLoader that you use to start the loading (and it chooses between its resource packs behind the scene, but you're not supposed to really care about that).

Quote from: Crimson Wizard on Fri 11/05/2018 14:20:32
Also, if you think that these changes could be useful, maybe suggest them to the engine code?
Yes, but for now I'd rather priviledge a workflow where I'm 100% in control of what I'm doing, with dirty hacks here and there (quick iterative method). I also want to be as little intrusive as possible. Once I have something that works I can initiate a conversation with tzachs to draw his attention to useful bits of my utility code, and let him pick what he likes. Then I can add it to MonoAGS myself.
 

Crimson Wizard

#99
Quote from: Crimson Wizard on Fri 11/05/2018 14:20:32
Yes, but for now I'd rather priviledge a workflow where I'm 100% in control of what I'm doing, with dirty hacks here and there (quick iterative method). I also want to be as little intrusive as possible. Once I have something that works I can initiate a conversation with tzachs to draw his attention to useful bits of my utility code, and let him pick what he likes. Then I can add it to MonoAGS myself.

Well, what I wanted to say, you could just edit these classes in your copy of MonoAGS code instead of trying to derive from them. Or edit them enough to be able to derive child classes. You may do that in a separate branch (of monoags repository), then keep syncing master branch with tzachs and merging to your custom one (or doing rebase) until you are ready to suggest these changes.

SMF spam blocked by CleanTalk