C# AI Interface, and Proof of concept C# AI - Page 5

C# AI Interface, and Proof of concept C# AI

Here is where ideas can be collected for the skirmish AI in development

Moderators: hoijui, Moderators

bamb
Posts: 350
Joined: 04 Apr 2006, 14:20

Post by bamb »

Does C# have operator overloading?

That's one of the sucky things that Java is missing...
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Post by AF »

I believe so
User avatar
Licho
Zero-K Developer
Posts: 3803
Joined: 19 May 2006, 19:13

Post by Licho »

Yes but unlike in C++, methods must be static.
User avatar
hughperkins
AI Developer
Posts: 836
Joined: 17 Oct 2006, 04:14

Post by hughperkins »

Operators work well in C#. You no longer have to consider side-effects to the "this" object. Creating an operator- automatically lets you do both "a = b - c;" ("operator-" in C++) and "a -= c;" (operator-= in C++).
User avatar
hughperkins
AI Developer
Posts: 836
Joined: 17 Oct 2006, 04:14

Post by hughperkins »

Added notes on Mono binding creation to Wiki at:

http://taspring.clan-sy.com/wiki/GlobalAI_Mono_Bindings

Could make a good project for anyone who is interested in Mono, C++ inter-language bindings or writing a GlobalAI in Mono.
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Post by AF »

The onus is on you to crate them since you know more, and you maintain the C# interface.

Other than that there is me and jelmer, of which I don't know nearly enough to start, and jelmer has OSRTS and upspring.
User avatar
hughperkins
AI Developer
Posts: 836
Joined: 17 Oct 2006, 04:14

Post by hughperkins »

I don't know nearly enough to start
There's a pretty complete bunch of prototypes within the downloads on the page, partly from me partly from jelmer. What's missing is bringing the prototypes together to create the generator.

The place to start is the MonoEmbeddedTest from jelmer. See jelmer's post earlier in this thread. This demonstrates:
*calling a static function in C# from C++
*calling a static C++ function from C#
*returning a pointer to a static function in C# to C++
*calling the pointed-to C# function from C++
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Post by AF »

Theres nothing stopping you doing it especially since it would make CSAI corssplatform.

I on the other hand have my own projects to be busy with, and I'm not going to commit to a C# project untill I can be sure it's crossplatform.

Besides I cant compile any of the mono stuff and I havent a clue how I'd test any of it, its all something I dont wanna touch or think about right now
User avatar
hughperkins
AI Developer
Posts: 836
Joined: 17 Oct 2006, 04:14

Post by hughperkins »

Jelmer,

Do you happen to know if it's possible to load debug information when running Mono embedded? It's really worth having line numbers in exception reports, and the effect on performance is trivial.
User avatar
hughperkins
AI Developer
Posts: 836
Joined: 17 Oct 2006, 04:14

Post by hughperkins »

Ok, hours of pain later... it's like this:

Code: Select all

	domain = mono_jit_init ("AILauncher");
	if (!domain)
		throw std::runtime_error ("Couldn't create mono JIT runtime.");

        mono_debug_init(MONO_DEBUG_FORMAT_MONO);
        mono_debug_init_1( domain );
    
	// load the managed dll
	assembly = mono_domain_assembly_open (domain, dll);
	if (!assembly) 
		throw std::runtime_error("failed to load " + std::string(dll));

        mono_debug_init_2( assembly );
	image = mono_assembly_get_image(assembly);
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Post by AF »

I thought jelmer offered to make a mono binding once the C interface was done?
User avatar
jcnossen
Former Engine Dev
Posts: 2440
Joined: 05 Jun 2005, 19:13

Post by jcnossen »

I think I did, though I forgot where. However Hugh probably can do it much faster than I can, he already knows how his generator code works as well as the required mono stuff. If he really refuses I'll try though ;)
User avatar
hughperkins
AI Developer
Posts: 836
Joined: 17 Oct 2006, 04:14

Post by hughperkins »

There's a nearly complete Mono bindings at AI/Global/CSAI/MonoLoader

This includes a wrapper layer to provide CSAI compatibility. If you thought that unwrapped ABIC looks ugly, take a look at unwrapped Mono layer:

Code: Select all

ABICInterface.IAICallback_SendTextMsg( aicallback, "Unit created: " + ABICInterface.UnitDef_get_name( unitdef ), 0 );
With wrapper layer this becomes:

Code: Select all

aicallback.SendTextMsg(  "Unit created: " + unitdef.name, 0 );
What's missing is essentially anything involving arrays.
User avatar
MadRat
Posts: 532
Joined: 24 Oct 2006, 13:45

Post by MadRat »

I thought arrays in C-anything, strictly speaking, was a bad thing.
User avatar
jcnossen
Former Engine Dev
Posts: 2440
Joined: 05 Jun 2005, 19:13

Post by jcnossen »

Eh, no.

:shock:
What's missing is essentially anything involving arrays.
Isn't there a set of mono_array_* functions in the mono headers?
User avatar
hughperkins
AI Developer
Posts: 836
Joined: 17 Oct 2006, 04:14

Post by hughperkins »

jcnossen wrote:Isn't there a set of mono_array_* functions in the mono headers?
Yeah, heavily documented just like the rest of Mono embedding ;-)
User avatar
hughperkins
AI Developer
Posts: 836
Joined: 17 Oct 2006, 04:14

Post by hughperkins »

Mono embedding is a huge time sink. There is zero documentation. If you can find out how to do arrays I'll add them in.

Edit: finally pursuaded the Mono devs to part with the information. Working on adding array functions now.
User avatar
hughperkins
AI Developer
Posts: 836
Joined: 17 Oct 2006, 04:14

Post by hughperkins »

CSAI-compatible MonoLoader committed to SVN (r2670).

AI/Global/CSAI/MonoLoader

Note: maximum one MonoLoader AI per game.

Just for info, a lot of pain went into building this loader, Mono Embedding is non-trivial and undocumented.

Edit: how to build this:

On Windows:

First build GlobalAIInterfaces, which powers the generators:

Either, use Visual C# Express 2005:
*Open rts/ExternalAI/GlobalAIInterfaces with Visual C# Express 2005
*Build

Or, use batch file:
*change into rts/ExternalAI/GlobalAIInterfaces
*edit generate.bat with paths to mono or .Net and to Spring source and application
*run generate.bat

Next build MonoLoader:

*change into AI/Global/CSAI/MonoLoader
*edit build.bat with the path of spring, spring source, mono and mingw
*run build.bat

For an example AI, you can use CSAI2, which is in progress but does run. To build CSAI2, either:

*Either: open AI/Global/CSAI/CSAI2/CSAI2 with Visual C# 2005 Express and build
*Or: use nant. Just change into AI/Global/CSAI/CSAI2/CSAI2 and run "nant", with nant in the path

Edit: to run this, you'll need to copy some mono dlls into the spring directory. The files to copy are:

from mono/bin into TASpring directory:
iconv.dll
libglib-2.0-0.dll
mono.dll
intl.dll
libgmodule-2.0-0.dll
libgthread-2.0-0.dll

lib/mono/1.0 into TASpring/lib/mono/1.0:
mscorlib.dll
mscorlib.dll.mdb

lib/mono/2.0 into TASpring/lib/mono/2.0:
mscorlib.dll
mscorlib.dll.mdb

everything in lib/mono/gac/System into TASpring/lib/mono/gac/System
everything in lib/mono/gac/System.Xml into TASpring/lib/mono/gac/System.Xml
(if you dont have the last ones you get wierd unexplained crashes.)

edit: Dev notes for MonoLoader maintainers

*delegates can be passed from C# to C as IntPtrs
*make sure to store the IntPtr as an object instance before giving it to C, so it doesnt get gc'd
*make sure to put a gc lock on the C# object, from within C, to prevent it being gc'd
*strings are passed as MonoStrings, except when calling from C into Mono via a delegate function
*function pointers use the default platform calling convention, which is __stdcall on Windows and __cdecl on Linux

It doesnt seem possible to load multiple assemblies with the same class inside in Mono. It crashes the runtime. THis means that .reloadai implemented as for .Net wont work.

We could use AppDomains for this, but its lagtastic. Just modify the comments on lines 457 and 458 of CSAICInterface.cs to convince yourself of this. (you'll need to uncomment the compilation and deployment of MonoLoaderProxy.dll in the build.bat file for this to work).

Probably the only possible solution is to unload the Mono runtime and reload the entire runtime and assemblies. Untested.

Note that it's not currently possible to run multiple CSAIs within MonoLoader without using separate AppDomains. This is because CSAI uses Singleton pattern throughout, which means that in Mono, there's only one instance shared between all AIs.

Edit: just for info, note that each of these dev points, including the one-liners, was learnt following several hours of crashes and testing ;-)
Kloot
Spring Developer
Posts: 1867
Joined: 08 Oct 2006, 16:58

Post by Kloot »

@Hugh: would it be possible to also create wrapper interface headers for IGlobalAI.h, IAICheats.h, IAIGroup.h, Weapon.h and WeaponDefHandler.h (from Sim/Weapons), and StdAfx.h (from System/)? I'm porting a C++ AI to use ABIC++ but it depends on those six files (update: actually only on IGlobalAI.h, IAICheats.h, WeaponDefHandler.h and StdAfx.h) and since they're neither covered by ABIC on the Spring side nor by ABIC++ on the AI side, I can't proceed :)
User avatar
hughperkins
AI Developer
Posts: 836
Joined: 17 Oct 2006, 04:14

Post by hughperkins »

Kloot wrote:@Hugh: would it be possible to also create wrapper interface headers for IGlobalAI.h, IAICheats.h, IAIGroup.h, Weapon.h and WeaponDefHandler.h (from Sim/Weapons), and StdAfx.h (from System/)? I'm porting a C++ AI to use ABIC++ but it depends on those six files (update: actually only on IGlobalAI.h, IAICheats.h, WeaponDefHandler.h and StdAfx.h) and since they're neither covered by ABIC on the Spring side nor by ABIC++ on the AI side, I can't proceed :)
That's a lot of classes. If you could somehow make it so only asking for a single one at a time will help you, it would make it less intimidating ;-)

If you want, I can teach you how the interfaces work, and you could take over their maintenance?
Post Reply

Return to “AI”