Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Programming a Programming Computer Game – .Net Run Time Type Creator

DZone's Guide to

Programming a Programming Computer Game – .Net Run Time Type Creator

·
Free Resource
A while ago me and a friend had an idea for a computer game. You would control a collection of bacteria all which needed to feed and would die of old age given enough time. They could also reproduce in order of keep their population going and fight enemy bacteria population controlled by an other player. The aim of the game was from your bacteria to out compete the other players bacteria on the map. So far so unoriginal, our new idea was that rather than controlling the creatures through say using a mouse and keyboard to give them orders you would instead controls them by writing the code for how they behaved. It would be a real time competitive programming game.

The game interface would be a map with a text panel on the right where the user would enter code that the creatures would execute to make their decisions. There were commands for where to move, what to eat, when to breed, etc. This was also a really nice space from which to play with algorithms like neural nets, evolutionary algorithms, clustering, A*, etc. We played around with it a bit and had a fair amount of fun, but we eventually realized that even for us who had built it, the game was too complicated for anyone to actually play. At least not in real time. So we abandoned it as a fun experiment.
But I recently saw  this post on stack overflow that reminded me of that game. So I thought I would share some of the code for how to do in application code compilation in .Net. Hopefully it will be of use to some people and maybe even if I get enough interest I may try and clean up the rest of the code and release it as an open source project. Because despite being painfully complicated, when it did work it was fun, at least for uber nerds like us.

RunTimeTypeCreator

Here is the one and only method in the lib method:
 public static T CreateType(string source,
IEnumerable<string> assemblies,
out List compilationErrors)
where T : class

It will attempt to create an instance of the type T from the source passed in. The source will be compiled with references to all the assemblies in the assemblies parameter. So for example you could do this with it.

namespace RunTimeTypeCreator.Tests 
{ 
public class RunTimeTypeCreatorTests 
{ 
public static bool TestVariable = false; 
public void Example() 
{ 
const string source = @" 
using RunTimeTypeCreator.Tests; 
public class TestTypeClass : RunTimeTypeCreatorTests.ITestType 
{ 
public bool Success { get { return RunTimeTypeCreatorTests.TestVariable; } } 
}"; 
List<string> compilationErrors; 
var type = RunTimeTypeCreator.CreateType<ITestType>(source, 
new[] { "RunTimeTypeCreator.Tests.dll" }, //the name of this assembly
out compilationErrors); 
TestVariable = false; 
//will print false 
Console.WriteLine(type.Success) 
TestVariable = true; 
//will print true 
Console.WriteLine(type.Success) 
} 
public interface ITestType 
{ 
bool Success { get; } 
} 
} 
} 

Which is kind a cool I think. Here's a quick run through of how it works, this just shows the code minus bits of validation and error reporting, so if you want the full thing I would recommend getting it from github

var csc = new CSharpCodeProvider(); 
var parameters = new CompilerParameters 
{ 
//we don't want a physical executable in this case 
GenerateExecutable = false, 
//this is what allows it to access variables in our domain 
GenerateInMemory = true 
}; 
//add all the assmeblies we care about 
foreach (var assembly in assemblies) 
parameters.ReferencedAssemblies.Add(assembly); 
//compile away, will load the class into memory 
var result = csc.CompileAssemblyFromSource(parameters, source); 

//we compiled succesfully so now just use reflection to get the type we want 
var types = result.CompiledAssembly.GetTypes() 
.Where(x => typeof(T).IsAssignableFrom(x)).ToList(); 
var parameterlessConstructor = types.First().GetConstructor(new Type[] { }); 

//create the type and return 
return (T)Activator.CreateInstance(types.First());

Full code is available here on github. I also had some other code around validating what the user was doing, Making sure they weren't trying to access the file system, open ports or creating memory leaks/recursive loops. I'll try and clean this up and post it at a future date.

Topics:
.net ,game development

Published at DZone with permission of Daniel Slater. See the original article here.

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}