Page 1 of 7
C# AI Interface, and Proof of concept C# AI
Posted: 17 Oct 2006, 04:21
by hughperkins
To facilitate the creation of AIs for Spring, here is an interface that allows the creation of AIs in C#.
The C# AIs can be recompiled and reloaded on-the-fly, without needing to restart Spring.
Some reasons for using C# to write AIs:
- no stack/heap corruption errors
- it's very fast
- automatic garbage collection
- easy to debug
Features
=====
C++/C# interface
---------------------
- Runs with .Net Framework 1.1
- can dynamically reload CSAI.dll within game by saying ".reloadai"
- complete coverage of IGlobalAI
- good coverage of AICallback
- nearly complete coverage of UnitDef
- can give Commands via GiveOrder
CSAI AI Proof of concept
-----------------------------
- Commander builds a metal extractor and can be ordered to move around
- View available commands by typing ".csai help"
- View discovered metal spots by typing ".csai showmetalspots"
Lastest release:
==========
[snip, please see
http://taspring.clan-sy.com/wiki/AI:CSAI for download link]
Changes this release
====================
C++/C# interface 0.3
- nant build files created
- unitdef file partial generator created in buildtools
- unitdef almost completed
- aicallback partial generator created in buildtools
- aicallback proxy + interface coverage substantially improved
CSAI 0.0008
- nant build file created
- CSAI cache is now in AI/CSAI/cache
- saying ".csai help" displays a list of available commands
- new method RegisterVoiceCommand in CSAI class, to allow other classes to register commands
- saying ".csai showmetalspots" shows the metal spots found by Metal.cs
Posted: 17 Oct 2006, 12:49
by jcnossen
Nice, we're actually going to use C# for scripting in a new rts engine... more about that later. This allows AI coders to get used to C# :)
Unfortunately its not portable.
It also demonstrates nicely how to start the CLR from an unmanaged exe. If someone would make a mono binding using the mono embedding API, we can have portable .NET AIs!.
Posted: 17 Oct 2006, 17:25
by AF
This is extremely useful to me, you just have no idea!
Someone please make a mono binding immediatly!!!!
Posted: 17 Oct 2006, 19:30
by hughperkins
Unfortunately a mono binding is *hard*:
- Swig does not support Directors for C#
http://www.swig.org/Doc1.3/CSharp.html#CSharp . Directors in Swig means callbacks. That means you can monitor stuff going on in the game, but not actually build anything...
- Using P/Invoke directly is *hard*. See
http://www.gotmono.com/docs/embeding/embeddc.html One could presumably write some wrapper functions to make life easier, basically rewriting Swig for C# in the process
Posted: 17 Oct 2006, 21:35
by jcnossen
Actually the CVS version supports it already, I'm using it for the new osrts engine (see news post)
http://www.osrts.info/~jcnossen/swig-bin.zip
But the problem with that is that you still need to put the starting app in a DLL, because SWIG will generate P/Invoke bindings for it.
The mono embedding docs are very limited. You'd need to call mono_runtime_invoke with a function that returns delegates, which you can convert to a function pointer (So you get fast callbacks into the managed code).
A while ago I spend some time on automatically generating a assembly with C++ types on runtime, so you could embed mono easily in a C++ app, but it's really hard. At some point my code actually started to hit internal mono asserts, so I quit. Creating a binding without all the funky automated linking code is quite possible though, just a lot of work.
Posted: 17 Oct 2006, 23:15
by hughperkins
> Actually the CVS version supports it already, I'm using it for the new osrts engine (see news post)
Hmmm, interesting. That's good news, if only for ogre3d.
> But the problem with that is that you still need to put the starting app in a DLL, because SWIG will generate P/Invoke bindings for it.
Hmmm, after trying a small prototype I see what you mean. Do you think there's any way of working around that?
> The mono embedding docs are very limited. You'd need to call mono_runtime_invoke with a function that returns delegates, which you can convert to a function pointer (So you get fast callbacks into the managed code).
Ok. Do you have any small prototypes/examples of doing that?
Question: do you happen to have a copy of the mono library that can be linked against msvc? As far as I can tell Mono only ships with a mono runtime library built with gcc?
Posted: 18 Oct 2006, 01:58
by jcnossen
Code: Select all
gpointer
mono_delegate_to_ftnptr (MonoDelegate *delegate);
MonoDelegate*
mono_ftnptr_to_delegate (MonoClass *klass, gpointer ftn);
In marshal.h... problem is that that is an internal header. There is a lot of really cool stuff hidden in mono, but it's undocumented and hard to get working. Many of the internal functions are quite mature I think, but the mono developers are not really eager to expose things.
I don't really know if there is any program other than the mono utils itself that use the interface anyway.
What I think needs to be done, is using mono_runtime_invoke to call a function that returns some callback delegate. Then you cast the returned MonoObject to MonoDelegate, and run mono_delegate_to_ftnptr().
I have some messy mono test code lying around, maybe I'll try it myself soon when I have time (Just the delegate callback, not a full binding

)
http://www.osrts.info/~jcnossen/monovclib.zip Here is my .lib, I don't remember how i made, but it was quite some work. I think I used impdef.exe(added in zip) at some point, as well as other stuff that I can't find anymore.
Hmmm, after trying a small prototype I see what you mean. Do you think there's any way of working around that?
Not that I know, maybe you could modify the output of SWIG to generate
[MethodImpl(MethodImplOptions.InternalCall)] instead of [DllImport(lib, EntryPoint)]
and let it generate code to register the C++ methods to mono using mono_add_internal_call
Posted: 18 Oct 2006, 05:50
by PauloMorfeo
jcnossen wrote:... There is a lot of really cool stuff hidden in mono, but it's undocumented and hard to get working. Many of the internal functions are quite mature I think, but the mono developers are not really eager to expose things.
...
Where have i seen that before?
gough*spring*cough

Posted: 18 Oct 2006, 07:12
by hughperkins
> Here is my .lib, I don't remember how i made, but it was quite some work. I think I used impdef.exe(added in zip) at some point, as well as other stuff that I can't find anymore.
Ok great! That links ok with a prototype. When the compiled prototype runs, it searches for mono-1.dll. Renaming mono.dll to mono-1.dll, and adding Mono-1.1.8\bin to the path gets rids of this message, then it says:
Code: Select all
The assembly mscorlib.dll was not found or could not be loaded.
It should have been installed in the `H:\dev\test\testcallcsmono\lib\mono\1.0\mscorlib.dll' directory.
There is a file mscorlib.dll in the mono\1.0 directory. Creating a directory mono\1.0\mscorlib.dll and moving the dll into this subdirectory doesnt change anything.
Any ideas?
Posted: 18 Oct 2006, 11:13
by jcnossen
You must supply the directories with mono_set_dirs, look in
http://www.mono-project.com/Embedding_Mono
I'll post some of my app when I have time (Project deadline tomorrow :/)
Posted: 19 Oct 2006, 01:53
by jcnossen
Where have i seen that before?
gough*spring*cough
Such as?
Posted: 19 Oct 2006, 05:05
by PauloMorfeo
jcnossen wrote:
Where have i seen that before?
gough*spring*cough
Such as?
Well, need i explain? People have been complaining that many of the new stuff in Spring's code they don't know about ever since the begining with SJ.
Anyway, i can give an example i found out while in a search yesterday:
http://taspring.clan-sy.com/phpbb/viewtopic.php?t=6631
It would be usefull to have a person to keep scrolling around the source and make a bridge with the source and the moders.
Maybe even,
- Coders code
- The Bind Maker keeps giving news on what is new
- The Literary write a few wikis
- The Moders have all the information they need
The "Bind Maker" isn't really needed to be a very coding person, just needs to understand some coding and just be there.
Posted: 19 Oct 2006, 08:32
by hughperkins
New release of CSharpAI
Changes this release
====================
C++/C# interface:
- can recompile CSAI.dll at any time, and reload it in-game by saying ".reloadai"
- class-naming tidied up a little
- additional available properties added to IUnitDef
- additional available functions added to IAICallback
- C# interfaces used by C++ code abstracted to new dll CSAIInterfaces.dll, to allow CSAI.dll dynamic reloading
- Shutdown method added to C# CSAI class, to allow cleanup of file handles, threads etc prior to reloading
C# AI:
- Metal class added to detect Metal points
- Metal class uses a cache to speed initialization
All:
- Build-files split between three sub-directories:
- CSAIInterfaces: builds CSAIInterfaces.dll, contains C# interfaces used by CSAILoader.dll
- CSAI: builds CSAI.dll, the C# AI
- CSAILoader: builds CSAILoader.dll, the C++/C# proxy, loaded by Spring as a bot
Posted: 19 Oct 2006, 14:12
by AF
You've ported the AAI metal algorithm despite it not being the most upto date version available, and that it was modified specifically for AAI.
Porting the NTai or KAI version wouldbe much much better as they're more upto date..
Posted: 19 Oct 2006, 17:31
by hughperkins
Historical accident: on the day I tried the AIs, AAI worked and NTAI was incompatible with the 0.73b. Also, the AAI source is directly available within the standard Spring distribution.
Posted: 20 Oct 2006, 13:31
by hughperkins
New release available
Changelist:
C++/C# interface 0.3
- nant build files created
- unitdef file partial generator created in buildtools
- unitdef coverage almost complete
- aicallback partial generator created in buildtools
- aicallback proxy + interface coverage substantially improved
CSAI 0.0008
- nant build file created
- CSAI cache is now in AI/CSAI/cache
- saying ".csai help" displays a list of available commands
- new method RegisterVoiceCommand in CSAI class, to allow other classes to register commands
- saying ".csai showmetalspots" shows the metal spots found by Metal.cs
Posted: 20 Oct 2006, 16:19
by hughperkins
(Note that the existence of code generators should make it realistically possible to bind with Mono)
Posted: 25 Oct 2006, 15:04
by hughperkins
AF wrote:You've ported the AAI metal algorithm despite it not being the most upto date version available, and that it was modified specifically for AAI.
Porting the NTai or KAI version wouldbe much much better as they're more upto date..
AF, where can I find this algorithm? I just came across an issue with the AAI algo and perhaps the new version solves it? The issue is that if you have distinct metal spots, the extractor will not be placed on the metal spot itself, but displaced towards the topleft by a distance corresponding to extractorradius.
Edit: never mind, found a tweak to correct this.
Posted: 25 Oct 2006, 15:16
by rattle
I thought that was intended...
Posted: 26 Oct 2006, 01:38
by AF
look at the KAI code in the svn, specifically KAI 0.2. You'll need to remove one or two functions that require KAI code though that're todo with upgrades.