adventuregamestudio / ags

AGS editor and engine source code
Other
675 stars 159 forks source link

Port AGS to Mono #442

Open CisBetter opened 6 years ago

CisBetter commented 6 years ago

The AGS Engine has been ported to GNU and Mac OS many years ago. However, the editor remains highly dependent on Windows.

All of my tries to run it on a Unix like system using WINE were useless as it would always crash with SIG SEGV. Many programs that were formerly windows-only are now successfully being ported to Mono. Hence, I believe porting AGS to Mono could do the Non-Windows AGS community a great favour.

If for some reason I got things wrong, and Mono is not capable of powering the AGS Editor, I hope there is a way to run AGS in WINE as I cannot afford 64 GB to create another Windows Virtual Machine.

Furthermore, this is something to be considered when updating and refactoring AGS as described in #403. If the engine and editor (or other parts of AGS) are to be rewritten I'd strongly suggest not to use Microsoft's .NET Framework. Other GUI toolkits (like GTK+) that are entirely free software look very promising as well (and are cross platform).

ericoporto commented 6 years ago

I use AGS on Ubuntu under Wine, I use it in a Wine Prefix created with PlayOnLinux, go in Install Components and install dotnet20 for AGS 3.4.0 or dotnet40 for AGS 3.4.1 and above.

If I recall this correctly the problem is AGS.Native.dll, and not the graphical toolkit (on the Mono issue).

ghost commented 6 years ago

If I recall this correctly the problem is AGS.Native.dll

Yes, this was mentioned as the main stopping issue all the time this suggestion came up in the past. Although tbh I personally never looked in how this works in Mono, but people said that it won't be able to use mixed C++/CLI libraries. Assuming that is still true, the primary task is to rewrite functionality of AGS.Native.dll into C# code.

Few parts were ported already, but quite some code still remains in there.

CisBetter commented 6 years ago

@ericoporto Indeed, after installing PlayOnLinux and creating a new virtual disk with dotnet20 and dotnet40 (the installer was complaining that .NET 2.0 was not found) I was able to install and run AGS. As of now, the AGS Editor is working and after trying multiple times to run a game it would eventually compile and run.

morganwillcock commented 6 years ago

I believe there is some kind of race condition you may encounter, where game files are still being written while the engine tries to open them (if you are running a game from within the Editor). It seems fine in the latest pre-release version (I think the issue was fixed indirectly by cleaning up a couple of other things), and that is probably no less reliable then the latest 'stable' version.

With regard to porting the Editor, I think there are quite a lot of workflow and resource management issues where just a file structure on disk or an external paint program would be preferable to the Editor's tools. It would probably be easiest to concentrate on the data formats and the game compiler, and then getting an Editor working on other platforms is a lot more realistic.

You may also want to investigate MonoAGS, which currently has no editor, but you can build something directly in Visual Studio.

Bengrs commented 6 years ago

Hi!

people said that it won't be able to use mixed C++/CLI libraries

True, Mono will not be able to run C++/CLI libraries with native code, unless the library was targeting CLR.

Stackoverflow topic about this The Microsoft KB linked in the topic

Microsoft recommands porting C++ to C#, but it could be useful while AGS.Native is ported.

I'm not a C/C++ developer, but I can give it a try.

ghost commented 6 years ago

@Bengrs I did not research the topic through, but this paragraph from Stackoverflow page immediately brought my attention:

  1. run with mono on any system if the C++/CLI app is pure managed (but then, why use such an ugly language and not C#?)

  2. run with mono on windows in the other cases (C++/CLI apps are in general non-portable and include native code, so they can run only on windows and are uninteresting for the major objective of mono which is to run managed programs on Linux)

Do you mean that there is a specific /clr option that may help in this situation? Note: AGS.Native is already built with common /clr switch.

morganwillcock commented 5 years ago

To test this out, I:

After this I could build and start the Editor (but you can't do much without the native proxy). I think mono's WinForm implementation is no longer developed, but mostly working, and the editor panels and tree all looked normal.

Presumably replacing AGS.Native would mean duplicating some engine functionality with C# Allegro bindings?

ghost commented 5 years ago

Presumably replacing AGS.Native would mean duplicating some engine functionality with C# Allegro bindings?

Imho better find out how Allegro is used in that library code. Bitmap drawing obviously may be remade in .NET, same goes for TTF fonts. Hmm, frankly I cannot immediately tell what else is used from Allegro, if anything.

From the top of my head, the biggest parts that need to be reimplemented are: room management and GUI rendering.

ghost commented 5 years ago

There is one important thing that I must mention. In the past I did a big refactoring of the room loading code in the native library, but that wip version I was working on was never merged into master for some reasons. It may still be found in the branch called "experimental".

I was copying bits from there, but then forgot or could not find spare time. I may actually try restoring it for AGS 4 in the nearest time.

But that's not even the main point, another thing is that monkey0506 was working on porting that code to .NET several years ago. Unfortunately that work also was never complete nor merged. Until recently it was kept in the "multi_room_edit" branch, but I just noticed that it is not present anymore in our repository. It still may be found in forked repos, for example in yours (@morganwillcock ), and probably I may have that code locally.

Perhaps either of these may be used for the reference when porting room code to .NET.

morganwillcock commented 5 years ago

Thanks. I've got a copy of monkey's RoomLoader.cs, so I'll take a look at that first.

ericoporto commented 5 years ago

ClearGame.zip

diff

About debugging in Wine, I created a simple game with empty project and did a binary diff of the game in the _Debug folder and the one in Compiled/Windows and, there is a big portion of binary code missing in the _Debug version, that I guess come from the room - and from the string there, maybe fonts also?

BuildTargetWindows.cs is very different from BuildTargetDebug.cs. I noticed the comment on line 94

// Copy files from Compiled/Data to Compiled/Windows, because this is currently where game will be looking them up

Does it mean the debug can use content from regular build (from f7) to make it faster or something else? I found curious because CopyAuxiliaryGameFiles looks into data folder, but it does so using GetAuxiliaryGameFile which discards .ags files.

ghost commented 5 years ago

Does it mean the debug can use content from regular build (from f7) to make it faster

Yes. AGS engine allows to read game data both from package and from files on disk.

If I remember correctly, during test run the "current working directory" should be the project source root, so this is how it finds rooms and fonts.

Also when Editor runs the game in test mode it executes with "--runfromide" command followed by 3 path arguments: edited argument order

this is how it finds rest of data.

ericoporto commented 5 years ago

screenshot from 2019-02-23 08-16-31

Note: the path isn't important, on a normal successful run with the same game under Wine, using the build on Compiled/Windows I get

$ wine ClearGame.exe 
Adventure Game Studio v3.4 Interpreter
Copyright (c) 1999-2011 Chris Jones and 2011-2019 others
ACI version 3.4.3.1

Installing exception handler
Initializing allegro
Initializing game data
Located game data file: z:/home/erico/DOCU~OWL/CLEA~AJP/Compiled/Windows/CLEA~3NH.EXE
Opened game data file: game28.dta
Game data version: 49
Compiled with: 3.4.3.1
...

(three dots is just me saying there is a lot after)

And if I just throw the Linux build of the engine on _Debug/, along with the debug build of the game in the folder, and run, the same result as before

$ ./_Debug/ags  --runfromide ./AudioCache/ ./Speech/ ./Compiled/Windows/
Adventure Game Studio v3.5 Interpreter
Copyright (c) 1999-2011 Chris Jones and 2011-2019 others
ACI version 3.5.0.5

Initializing allegro
Initializing game data
Located game data file: /home/erico/Documents/ClearGame/_Debug/ClearGame.exe
Opened game data file: game28.dta
Game data version: 0
Compiled with: 
Loading game failed with error:
Not an AGS main game file or unsupported format..

The game files may be incomplete, corrupt or from unsupported version of AGS.

Anyway, what I found curious is that the error message is saying that either files are incomplete, corrupt, or from unsupported version of AGS. So Game data version is set to 0 (kGameVersion_Undefined) on the _Debug build and 49 on the Compiled/Windows. It doesn't get to fail there, because it's failing before with kMGFErr_SignatureFailed. Anyway, I just wanted to say that the initial thought of race conditions when running the engine from the editor wouldn't apply if this also happens through posthumous execution from command line. :grimacing:

morganwillcock commented 5 years ago

From a quick look at how the arguments are used, I think that the order is wrong? It looks to be game directory, then audio, then voice.

else if (stricmp(argv[ee], "--runfromide") == 0 && (argc > ee + 3))
{
    usetup.install_dir = argv[ee + 1];
    usetup.install_audio_dir = argv[ee + 2];
    usetup.install_voice_dir = argv[ee + 3];
    ee += 3;
}
ghost commented 5 years ago

Right, I did not realize you need exact order of the arguments, I just mentioned which arguments they are from my memory.

So Game data version is set to 0 (kGameVersion_Undefined) on the _Debug build and 49 on the Compiled/Windows. It doesn't get to fail there, because it's failing before with kMGFErr_SignatureFailed

This looks like a minor bug, it prints this data (version etc) even if the signature was wrong, but it should not because it did not read them yet. I think this mistake was introduced recently.

I am not sure what "game28.dta" did it open in Debug folder though, considering it did not contain actual game. Might need to investigate that.

ericoporto commented 5 years ago

From a quick look at how the arguments are used, I think that the order is wrong? It looks to be game directory, then audio, then voice.

Ok, I ran in correct order and got the same error.

$ wine ./_Debug/ClearGame.exe --runfromide ./Compiled/Windows/ ./AudioCache/ ./Speech/
Adventure Game Studio v3.4 Interpreter
Copyright (c) 1999-2011 Chris Jones and 2011-2019 others
ACI version 3.4.3.1

Installing exception handler
Initializing allegro
Initializing game data
Located game data file: z:/home/erico/DOCU~OWL/CLEA~AJP/_Debug/CLEA~3NH.EXE
Opened game data file: game28.dta
Game data version: 0
Compiled with: 

I am not sure what "game28.dta" did it open in Debug folder though, considering it did not contain actual game.

The _Debug folder had the ClearGame.exe built on debug...

Might need to investigate that.

This is really not important, I just, had the curiosity to check for this, but I can build the game fine when not debugging!

ghost commented 5 years ago

This is really not important, I just, had the curiosity to check for this, but I can build the game fine when not debugging!

Well, my perfectionism kicks in here. But I was not able to reproduce this behavior, even if I pass wrong parameters the game loads up normally or complains about not finding resources (fonts etc).

ericoporto commented 4 years ago

ags_api_port_analysis_complete.xlsx | ags_api_port_mono5.xlsx

The complete analysis above paints a more complete picture of System.Windows calls that are used with WinForms that would need to be switched or to a WinForms port or some other UI base.

Back to the port to mono topic, I managed to run AGS Editor solution on the recent .NET Portability Analyzer, to see how the project would fare in .NET Core 3.0 + Extensions and Mono 5.0 and it did not do bad. Note that .NET 5 is coming and it will also be cross platform. GUI parts are not coming so soon though, but theoretically you would at least be able to work with a big part of the code, and load and build sections of the Editor in an IDE like Rider.

I think a big effort is in getting all the native things wrapped in some cross platform way. I found some references online on this but I don't know enough on how to navigate MS Docs to see if there's an known way.

http://web.archive.org/web/20191030013343/https://www.olegtarasov.me/call-native-lib-from-net-core/ http://web.archive.org/web/20180525112920/http://developer.rhino3d.com/guides/rhinocommon/wrapping-native-libraries/

If there are parts of the code is using C++/CLI then it won't be possible to do it for the forseeable future.

ivan-mogilko commented 1 month ago

This issue is practically dead. I might suggest picking out subtasks necessary to moving towards a cross-platform IDE (whether it's on Mono, or another framework).

One such subtask, or rather a collection of tasks, is standalone game building tools: #2316 Another side of the problem are any operations that must remain in the IDE but are still part of the native code currently. IIRC these are primarily use of sprite cache in previews, and previews themselves (fonts, gui etc). There could be a "master ticket" written for these as well.

ericoporto commented 1 month ago

There was #1092 to separate ags-types from Winforms because at the time I was trying to make a command line tool that would load a Game.agf file.

ivan-mogilko commented 1 month ago

I suppose it may make sense to make a "master ticket" which explains a vision of the Editor, and links other tickets as subtasks. This may be useful as a reference, and in case we need to explain a goal to somebody.

E.g. a ticket called "Editor: improve code portability", which would mention these subtasks (which may have their own collections of tasks in them), for example: