C# AI Interface, and Proof of concept C# AI
Moderators: hoijui, Moderators
- hughperkins
- AI Developer
- Posts: 836
- Joined: 17 Oct 2006, 04:14
C# AI Interface, and Proof of concept C# AI
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
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
Last edited by hughperkins on 24 Oct 2006, 22:38, edited 7 times in total.
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!.
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!.
- hughperkins
- AI Developer
- Posts: 836
- Joined: 17 Oct 2006, 04:14
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
- 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
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.
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.
- hughperkins
- AI Developer
- Posts: 836
- Joined: 17 Oct 2006, 04:14
> 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?
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?
Code: Select all
gpointer
mono_delegate_to_ftnptr (MonoDelegate *delegate);
MonoDelegate*
mono_ftnptr_to_delegate (MonoClass *klass, gpointer ftn);
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.
Not that I know, maybe you could modify the output of SWIG to generateHmmm, after trying a small prototype I see what you mean. Do you think there's any way of working around that?
[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
- PauloMorfeo
- Posts: 2004
- Joined: 15 Dec 2004, 20:53
- hughperkins
- AI Developer
- Posts: 836
- Joined: 17 Oct 2006, 04:14
> 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:
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?
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.
Any ideas?
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 :/)
I'll post some of my app when I have time (Project deadline tomorrow :/)
- PauloMorfeo
- Posts: 2004
- Joined: 15 Dec 2004, 20:53
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.jcnossen wrote:Such as?Where have i seen that before?
gough*spring*cough
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.
- hughperkins
- AI Developer
- Posts: 836
- Joined: 17 Oct 2006, 04:14
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
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
Last edited by hughperkins on 22 Oct 2006, 19:42, edited 1 time in total.
- hughperkins
- AI Developer
- Posts: 836
- Joined: 17 Oct 2006, 04:14
- hughperkins
- AI Developer
- Posts: 836
- Joined: 17 Oct 2006, 04:14
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
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
- hughperkins
- AI Developer
- Posts: 836
- Joined: 17 Oct 2006, 04:14
- hughperkins
- AI Developer
- Posts: 836
- Joined: 17 Oct 2006, 04:14
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.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..
Edit: never mind, found a tweak to correct this.
Last edited by hughperkins on 25 Oct 2006, 15:21, edited 1 time in total.