BattletechModders / ModTek

Mod system for HBS's PC game BattleTech.
GNU Lesser General Public License v2.1
119 stars 34 forks source link

Dynamic C# code loading #8

Closed CptMoore closed 6 years ago

CptMoore commented 6 years ago

being able to load .cs files without having to precompile them allows for the following use cases:

  1. mods can be developed without VS (still need dnSpy though) I still want .cs projects to be compatible with .dll project structure wise (so one can leverage from VS and resharper tooling)
  2. mods can expose certain code that mod users can modify without much VS or even coding experience. so basically an advanced configuration file.

I'm right now finishing up a new mod for BTML called DynTechMod that should allow .cs based mods. I'm also splitting up my VisualHardpointLimits mod into versious submods based on the .cs idea.

Once I'm finished we can discuss how to integrate that into ModTek of even if.

mpstark commented 6 years ago

An interesting idea -- I would be concerned about a couple things:

CptMoore commented 6 years ago

Assembly compatibility with BattleTech's included assemblies -- Unity and Mono are not one-to-one with .net

That is no issue, when compiling one can just reference the unity/mono assemblies. doing that already in my prototype.

Feature-creep into ModTek's already fairly large feature-set

Feature creep is a none issue, it would just precompile a dll before loading (from a code view and a modders view, just one additional feature/step). There is an issue with release size and maintenance.

Alternatives would be to modify ModTek to just optionally integrate such a solution, but that would even further confuse the users installation procedures.

Extending BattleTech's already giant load times

Solved since one just compiles an assembly to disk and does not recompile unless sources change.

Encouraging users to edit code files that they don't understand

Well that's a risk with all modding, but cooler would be if users start learning stuff step by step, this can really help with that.

So my current list of issues:

I also evaluated other ways of scripting:

CptMoore commented 6 years ago

Size of the Mono-Compiler Suite zipped is 17 MB, windows only

CptMoore commented 6 years ago

I have a working prototyp

BTML mod that dynamically compiles other mods https://github.com/CptMoore/DynTechMod

DynTechMod mod that uses dynamic compilation: https://github.com/CptMoore/VisualHardpointLimits

Right now the example mod is directly initialized from DynTechMod. Once ModTek is out, DynTechMod will only be a compiler, compiling various ModTek mod in the BTML init phase and ModTek will initialize those once that the BTML init phase is finished.

Status:

Tyler-IN commented 6 years ago

I've done C# scripting (e.g. compiling snippets) before in UE games, but compiling entire projects at runtime .... is a bit of a huge, enormous ... overcomplication.

Mono provides a light-weight example of a REPL project that could be used as an example; http://www.mono-project.com/docs/tools+libraries/tools/repl/

Pretty sure all you need to include is Cecil and it's friends, not the entire framework...

Unity even bakes in support for compiling UnityScript for this kind of usage... but gah holy cheesy rice on a cracker Batman...

You may have over-scoped by ambition here.

Where exactly is VisualHardpointLimits using dynamic compilation? I guess I'll go looking. edit; Oh it literally builds the entire project. Yeah I don't think that's cool...

edit2; Also, I think that instead of dynamic compilation, if you have something that needs to be compiled at runtime, you might be better off looking at combining System.Linq.Expressions's C# language integrated Expression<Func<...>> parameters with Expression trees and "Lambda" (compiled) expressions, if you can't just get by with generics and/or file parsing.

CptMoore commented 6 years ago

Unity even bakes in support for compiling UnityScript for this kind of usage

Based on my research, Unit Editor has scripting support which is not available in the unity 3d engine runtime. Meaning you can't compile on runtime or let the script run on runtime. Please tell me if that's different, I really could use information on that.

System.Linq.Expressions's C# language integrated Expression<Func<...>> parameters with Expression trees and "Lambda" (compiled) expressions.

Don't know how far that can get me, but a query based language doesn't seem suited for the use case I envision.

In order for this feature to be really useful, I would like to have this class as a script: https://github.com/CptMoore/VisualHardpointLimits/blob/master/source/stats/MechStatisticsRulesCalculateHeatEfficiencyStatPatch.cs#L14

Oh it literally builds the entire project. Yeah I don't think that's cool...

One file, every file, best to have the options. In any case, another pro would be easy accessibility for people to look at code and modify it if they want. There is no alternative that makes it that easily unless the ecosystem forces it (e.g. Cocoapods forces it for iOS development).

REPL

Since mono is implementing CSharpCodeProvider by calling csc.exe I always assumed it doesn't have easy accessible compilation features, but REPL might be it. Gonna test that now. In the worst case modern language features might not be available, but that should be enough for most use cases where scripting is required.

CptMoore commented 6 years ago

REPL

Ok, this took me a while, but I have made it. Found out that in later mono version the compiler functionality is exposed and directly called for REPL functionality. Found out I can do the same with an older Mono.CSharp.dll thats compatible with unity, just need a bit of reflection. Was happy when I saw that instead of mono.exe I can just call Mono.CSharp.CompilerCallableEntryPoin.t

Prototypes:

So new status:

CptMoore commented 6 years ago

The csharp compiler thats compatible with unity mono is buggy. SelectMany crashes hard, not even an exception to catch. The same code compiled with the newest VS (or newest mono) works perfectly.

mpstark commented 6 years ago

I don't think that this ultimately should be in ModTek and you've got development rolled off into DynTech, so I'm closing the issue.

CptMoore commented 6 years ago

I agree, since ModTek provides a nice dependency management system, DynModLib seems to work fine.