Search Unity

  1. Unity 2019.2 is now released.
    Dismiss Notice

C# 6.0

Discussion in 'Scripting' started by Deleted User, Mar 27, 2015.

  1. Ludiq

    Ludiq

    Joined:
    Mar 6, 2015
    Posts:
    594
    Hm, that icon does stay a bit longer (a couple of seconds, indeed), but nothing dramatic like 30 seconds. But it's enough to be noticeable. After "turning", the loader "stops" for a few more seconds while Unity is frozen. This happened on two separate projects, on two separate machines.

    Do you have any way to profile that process? Perhaps somewhere in your hook / dispatch hack, there's a small bottleneck?
     
  2. Ludiq

    Ludiq

    Joined:
    Mar 6, 2015
    Posts:
    594
    Just saw this in the VSTU changelog (v.2.2):
    • The C# language version is now restricted to C# 4, the latest version of the language supported by Unity.
    Will this be a problem? Do you think it's easily overridable?
     
  3. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,404
    Whatever it means, it doesn't seem to work. The only effect I see is I can no longer open Project Properties. The rollback to VSTU 2.1 solves the issue.
     
  4. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,404
    I don't know what causes it. The rolling stops right when the compilator process exits. Then I observe a small freeze about one second long (maybe two in a larger project), but the same freeze is also present in projects that use the standard compiler.
     
    Last edited: Feb 5, 2016
  5. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,404
    I'm not sure whether not being able to open the Project Properties window is a bug or a feature, but actually there's another difference: if you let Unity recreate the .csproj files, they'll get an extra line:

    Code (csharp):
    1. <LangVersion Condition=" '$(VisualStudioVersion)' != '10.0' ">4</LangVersion>
    A simple solution is to remove the line manually or change the version to 'default'. I'll see what I can do to make the change automatically.
     
    Last edited: Feb 6, 2016
  6. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,404
    Fixed. You need to update your CSharp60Support.dll or reimport the latest CSharp60Support for Unity X.unitypackage.
     
    Last edited: Feb 5, 2016
    Ludiq and MaxEden like this.
  7. Plutoman

    Plutoman

    Joined:
    May 24, 2013
    Posts:
    257
    Hey there,

    I am having a particularly stubborn issue. This would be phenomenally useful (unbelievably useful, really) to have set up, since we have many, many parallel operators, and they could very much benefit from the syntax, and especially the lazy resolving as well. The concurrent dictionary could improve performance by 50%+ as well, in addition to allowing us to utilize all the threads to a much greater extent.

    That said, when I integrate this, I get these errors;
    "Assets\Scripts\Layouts\Theme\Theme Elements\Leviaform\ThemeElementRigidSet.cs(369,22): error CS0012: The type 'XElement' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'"

    That's just one example - I get about 19 of them, and they involve every reference to the XElement in System.Xml.Linq dll file. This particular reference occurs when I use an interface from one of our own DLL's that uses the XElement. It does not happen when the XElement is used in the main project. However, if I try and move that interface into the main project, the error now occurs on every usage of XElement in the main project.

    The catch? It only happens when integrating the C# plugins and code. I have experimented with quite a few things, and visual studio's errors are corrected when I manually fix the .csproj and reference it with the specific version information. That allows visual studio to build it successfully, but Unity, however, will rebuild them itself and remove that specific version info.

    My only guess (but it also seems off) is that the DLL's were compiled with a specific version, and that adding them into the project, the project now wants a specific version for classes from that specific library. That said, I was browsing the assembly, and I cannot seem to find any references to System.Xml.Linq, but I assume, since it extends Linq, that it does have something to do with it.

    Do you happen to have any ideas? I can setup a test project if you're willing, as well, that demonstrates the issue.

    Thanks,
    ~Kurtis

    This is somewhat urgent for me, so at the least, if it is not possible to help (time constraints and all, I do realize this is free!), I would like to know as soon as possible!

    Edit: Upon further research, it only happens when our DLL's reference System.Xml, System.Xml.Linq (maybe more? at that point I stopped checking) - and the DLL's from this are added together. As I removed the Xml.Linq references, those errors went away, and the Xml ones popped up. I am now merging the DLL's into the main project to test that case.

    That said, the usage of separate DLL's is quite important, and the fact that it breaks on just this is somewhat scary in terms of using this in production level code.
     
    Last edited: Feb 18, 2016
  8. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,404
    No ideas yet.

    That would help a lot.
     
  9. Plutoman

    Plutoman

    Joined:
    May 24, 2013
    Posts:
    257
    Here's the test;
    https://www.dropbox.com/s/nljcere1kir0t58/AsyncTesting.zip?dl=0

    Of course, as I said it is urgent, I also came down sick, so that has limited my productivity. Oh well.

    This project demonstrates the error, and it includes two visual studio solutions that target Unity 3.5 subset, get compiled to a DLL, and then I, for this test, manually copied the DLL's over into the unity project (I automate in the main one, but forgot the syntax and did not feel like looking it up right now). Each of the solutions has a simple interface, one which uses an Xml.Linq XElement, and the other that uses an XML XMLAttribute. Just referencing the interfaces in the main project breaks.

    I have a lot of separate third-party DLL's as well as my own, and one of them is also causing the error, even as I moved all my code into the main project. It would be a simple fix, if simply speaking, unity allowed setting a specific version.

    You can use these DLL's in a normal project, without issue, or you can use the CSharp 6.0 extensions, but combining them breaks. I have tried setting it to a build target of .net 3.5, unity 3.5 full, and .net 3.5 client, just to test that.

    I can perform any testing you'd like, though I think it's generally covered in the project! It is just layered over the top of your demo project. New unity project, added the CSharp per directions, added unity package, dragged and dropped demo in.
     
  10. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,404
    Switch API Compatibility Level to .NET 2.0. I have no exact understanding of what this option really does, but switching it helps.
     
    Last edited: Feb 19, 2016
  11. Plutoman

    Plutoman

    Joined:
    May 24, 2013
    Posts:
    257
    Whaddya know. That worked wonders.

    Thank so you much! Now that I'm getting over this junk I came down with, I can take advantage of this.

    Amazing how simple that was - never even occurred to me to change the unity project settings.
     
  12. Plutoman

    Plutoman

    Joined:
    May 24, 2013
    Posts:
    257
    Just commenting back on how useful this has been; it's been phenomenal. Took a bit of work to properly get it all working, like deadlocking the main thread when trying to queue stuff back to it (finally figured out it was one of our loops; it queued and processed objects, and these were some of the objects I was moving to tasks.. so when they queued stuff back, it never left the loop to continue onto the FixedUpdate/Update loops).

    It's fixed a lot of internal Unity errors we'd have on occasion, where we'd write code that it couldn't figure out, but we'd not be sure where it was.

    So, just coming back to say thanks after we've worked with it for a week.
     
  13. h8spaCec4EspUdE

    h8spaCec4EspUdE

    Joined:
    Jan 8, 2015
    Posts:
    9
    excuse me, how to let monodevelop recognize the c#6.0 syntax?
    I downloaded .Net 4.6 developer pack and set the monodevelop target framework to 4.6.
    However, monodevelop still show the new syntax in red.
     
    Last edited: Mar 3, 2016
  14. Plutoman

    Plutoman

    Joined:
    May 24, 2013
    Posts:
    257
    Is it not possible to use visual studio? It's a much better IDE to work with, if you're willing to take the opportunity. I do not know how to fix that issue, but I'd definitely recommend VS - the community edition is free and great.
     
  15. h8spaCec4EspUdE

    h8spaCec4EspUdE

    Joined:
    Jan 8, 2015
    Posts:
    9
    Thanks for the advice.
     
  16. doq

    doq

    Joined:
    Aug 17, 2015
    Posts:
    121
    Are primary constructors supported? I'm testing all the C# 5.0 and 6.0 features out, and using await / async, string interpolation works fine so I know my sample project is setup correctly.
     
  17. doq

    doq

    Joined:
    Aug 17, 2015
    Posts:
    121
    I'm using Visual Studio 2015 Community edition with Unity 5.3.3p2, and I'm not getting Intellisense to autocomplete anymore. Anyone know a fix?
     
  18. doq

    doq

    Joined:
    Aug 17, 2015
    Posts:
    121
    Ignore my previous post. I just tried closing VS and had Unity regnerate the csproj, and the UnityEngine namespace was recognized by VS again.
     
  19. OutOfMyMindDave

    OutOfMyMindDave

    Joined:
    Jun 2, 2015
    Posts:
    5
    I'm trying to use CSharp60Support to integrate the Microsoft Band SDK with Unity. I'm using Unity 5.3.3f1 and VS2015 on a Win8.1 machine.
    I'm able to get to the point where I can run your demo code from earlier in this thread and everything looks good. However, when I add the Band SDK and try to implement it, I get some errors that tell me that I am missing references to the System.Threading.Tasks and System.Runtime assemblies. I believe that this is because several types are used in the Band SDK, and those 2 specific DLLs are not in the references list in the VS project.
    I've found several System.Runtime.dll and System.Threading.Tasks.dll files in the Reference Assemblies directory, but I can't add them as references to the project file.
    Does anybody have any suggestions for how to add these references? Or is this a fool's errand?
     
  20. Plutoman

    Plutoman

    Joined:
    May 24, 2013
    Posts:
    257
    I would suspect that, trying to add an SDK that was compiled with those libraries, would not work. Because this does not actually add those specific libraries, but rather a re-implementation of them made for .net 3.5.

    So the actual references would never be the same, and there are in fact some minor API differences (such as TaskEx instead of all the related functions actually being inside the Task class, like Task.WhenAll (.net 4.5) vs TaskEx.WhenAll (this library).

    The actual task to make it work would be to remove the references in the library to the normal .net 4.5 libraries, and then add these libraries as a reference, and re-build everything to work with it as appropriate. However, since you are talking about an SDK, I would guess you do not have that kind of liberty.
     
  21. OutOfMyMindDave

    OutOfMyMindDave

    Joined:
    Jun 2, 2015
    Posts:
    5
    Thanks. I figured as much. I'm currently attempting to get it working with anonymous or named pipes, which is presenting new opportunities for frustration. I'm able to run the sample code from MSDN just fine, but Unity seems reluctant to cooperate. I'll possibly move on to trying TCP after I exhaust my pipe attempts.
     
  22. OutOfMyMindDave

    OutOfMyMindDave

    Joined:
    Jun 2, 2015
    Posts:
    5
    Just a quick update. I ended up using a TCP connection, due to isolation of UWP and Windows desktop apps. I'm also currently having to run the apps on separate machines, due to Windows isolating loopback connections as well. I believe that I will be able to come up with a more elegant, and single machine, solution after more research. But it will do for now to get my project up and running.
    If only I had found this doc before I started trying: https://software.intel.com/en-us/ar...on-between-windows-8-ui-and-windows-8-desktop
    Thanks, Microsoft.
     
  23. Plutoman

    Plutoman

    Joined:
    May 24, 2013
    Posts:
    257
    That sounds rather fancy.

    I am having lots of debugging issues; even when running in a single-threaded context, having it compiled w/ the new setup tends to make debugging painful. Locals often not showing values, occasional crashes. Anything to do, or just something to deal with?
     
  24. Trojaner

    Trojaner

    Joined:
    Jan 18, 2013
    Posts:
    1
    Hi,
    I just upgraded Unity and now I have problems when using C# 6 features in Visual Studio, since VS Tools forces it to use C# 4.0.
    This doesn't seem to work anymore, it still forces C# 4.0 even after regenerating the .csproj's multiple times

    Unity version: 5.3.4f
    VS Tools: 2.2.0.0

    I'm using the latest version of this plugin.

    Also, prior to upgrading Unity, I was able to use C# 6 but debugging wasn't working at all with VS.
     
  25. tolstenko

    tolstenko

    Joined:
    May 31, 2012
    Posts:
    14
  26. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,404
    I checked 5.3.4f1 on OSX El Capitan - no errors.
    If it's a newly created Unity project, could you upload it for experiments?
     
  27. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,404
    I would say, deal with it. I experienced most of the crashes while trying to use Mono C# 6 compiler. Roslyn is more stable. Can't really compare it with the stock compiler because debugging in Unity never was that painless and smooth for me as debugging regular .Net applications in VS.

    I don't remember any "locals not showing values", but sometimes some locals seem to be missing. Usually it turns out that they are just hiding, like targetPoints collection on this screenshot:

    Capture.PNG
     
  28. Plutoman

    Plutoman

    Joined:
    May 24, 2013
    Posts:
    257
    It's sporadic, but usually speaking, it was inside a task thread and it would allow me to view properties of static variables or variables outside the stack context, but nothing inside would be visible - no hovering over, locals would click the arrow tab and pull down nothing.

    Can definitely deal with, since it's really worth the hassle anyways, the game itself seems more stable (just not debugging), just curious. Unity was always painful to debug, yes, and this made it a bit more painful, but meh, that's just reason to keep up the debugging and logging tools that we've built.
     
  29. Ludiq

    Ludiq

    Joined:
    Mar 6, 2015
    Posts:
    594
    I'm having the same problem. Unity 5.3.4f1 on Windows. I can't upload my whole project for testing, though.
    I deleted the CSPROJ files, and I'm on the latest version.
     
  30. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,404
    Does it help to not delete .csproj but just click "Open C# Project"?

    Capture.PNG
     
  31. Ludiq

    Ludiq

    Joined:
    Mar 6, 2015
    Posts:
    594
    Yep, that seems to work.
     
  32. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,404
    My solution to language version restriction problem relies on undocumented AssetPostprocessor.OnPreGeneratingCSProjectFiles event. VSTU also uses it for its own project files postprocessing. I suspect that sometimes my event handler is not called or called before VSTU's one, which brings the version restriction back.

    There are 3 possible solutions:

    1. Sometimes clicking "Open C# Project" helps. If not, click it one more time.

    2. Add this editor script to your project. I didn't put it in the repository because it relies on VSTU being installed. If it's not, SyntaxTree.VisualStudio.Unity.Bridge namespace is not available and you'll get errors.

    3. Use VSTU 2.1 until some future version makes C# 4.0 restriction optional.
    VSTU 2.1 for VS 2015: https://dl.dropboxusercontent.com/u/102171874/vstu.msi
     
    rakkarage and Ludiq like this.
  33. Ludiq

    Ludiq

    Joined:
    Mar 6, 2015
    Posts:
    594
    Thanks, I'll use the editor script solution!
     
  34. Ludiq

    Ludiq

    Joined:
    Mar 6, 2015
    Posts:
    594
    Actually, nevermind. It worked when I first added the script, but now I'm getting missing namespace errors. The About Unity window reports VSTU 2.2 is enabled.
     
  35. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,404
    You put this editor script in Editor folder, didn't you?
     
  36. Ludiq

    Ludiq

    Joined:
    Mar 6, 2015
    Posts:
    594
    D'oh. Thanks.
     
  37. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,404
    It has just crossed my mind that Roslyn's csc.exe is an ordinary managed executable that is jit-compiled every time it runs. Unity splits the compilation process into separate stages and can run the compiler up to 4 times, and each time the compiler itself has to be compiled before it can do the actual job.

    The same is true for pdb2mdb.exe that converts debug symbols from .pdb to .mdb format.

    Since on Windows I use .Net Framework instead of Mono to launch csc.exe and pdb2mdb.exe, why not to use NGEN to precompile the executables? And I did.

    Three columns on the left show the original times it took to run csc.exe and pdb2mdb.exe on one of my projects. Three columns on the right show the results after precompiling these executables using NGEN.

    ngen.PNG

    1. Unpack ngen cmd.zip into your project's Roslyn folder.
    2. Run ngen install.cmd as administrator.
    3. Enjoy.

    csc.PNG
     

    Attached Files:

    makeshiftwings, rakkarage and Ludiq like this.
  38. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,404
    I hope I finally fixed VSTU 2.2 C# 4.0 restriction issue. This script uses reflection and doesn't care whether VSTU is installed or not. I've integrated it in the new CSharp60Support.dll replacing the old fix that didn't work well enough.

    Code (CSharp):
    1. using System;
    2. using System.Reflection;
    3. using UnityEditor;
    4. using UnityEngine;
    5.  
    6. [InitializeOnLoad]
    7. public static class CSharpProjectPostprocessor
    8. {
    9.     static CSharpProjectPostprocessor()
    10.     {
    11.         foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
    12.         {
    13.             if (assembly.FullName.StartsWith("SyntaxTree.VisualStudio.Unity.Bridge") == false)
    14.             {
    15.                 continue;
    16.             }
    17.  
    18.             var projectFilesGeneratorType = assembly.GetType("SyntaxTree.VisualStudio.Unity.Bridge.ProjectFilesGenerator");
    19.             if (projectFilesGeneratorType != null)
    20.             {
    21.                 var delegateType = assembly.GetType("SyntaxTree.VisualStudio.Unity.Bridge.FileGenerationHandler");
    22.                 if (delegateType == null)
    23.                 {
    24.                     Debug.Log("Type 'SyntaxTree.VisualStudio.Unity.Bridge.FileGenerationHandler' not found");
    25.                     return;
    26.                 }
    27.  
    28.                 var projectFileGenerationField = projectFilesGeneratorType.GetField("ProjectFileGeneration", BindingFlags.Static | BindingFlags.Public);
    29.                 if (projectFileGenerationField == null)
    30.                 {
    31.                     Debug.Log("Field 'ProjectFileGeneration' not found");
    32.                     return;
    33.                 }
    34.  
    35.                 var methodInfo = typeof(CSharpProjectPostprocessor).GetMethod(nameof(RemoveLanguageVersionRestriction), BindingFlags.Static | BindingFlags.NonPublic);
    36.                 var postprocessHandler = Delegate.CreateDelegate(delegateType, null, methodInfo);
    37.  
    38.                 var delegateValue = (Delegate)projectFileGenerationField.GetValue(null);
    39.                 delegateValue = delegateValue == null ? postprocessHandler : Delegate.Combine(delegateValue, postprocessHandler);
    40.                 projectFileGenerationField.SetValue(null, delegateValue);
    41.  
    42.                 return;
    43.             }
    44.         }
    45.     }
    46.  
    47.     private static string RemoveLanguageVersionRestriction(string name, string content)
    48.     {
    49.         return content.Replace("<LangVersion Condition=\" '$(VisualStudioVersion)' != '10.0' \">4</LangVersion>", string.Empty);
    50.     }
    51. }

    I should have done it this way from the beginning.
     
    Last edited: May 14, 2016
    Ludiq likes this.
  39. Ludiq

    Ludiq

    Joined:
    Mar 6, 2015
    Posts:
    594
    Will download the new version tomorrow. Is Ngen part of it by default, now?

    Even using the Ngen fix, I still have annoyingly long compile times. Is there a way for me to debug what takes so long in my projects / on my machine? I see you were able to pull some metrics for the Ngen benchmarking, but maybe there's an even more detailed way?
     
  40. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,404
    Yes, I've added the ngen scripts to CSharp60Support folder. You have to run them manually though.
    ngen.PNG
    I took those times from 'compilation log.txt'.

    Here is a graph I get using PerfView and Windows Performance Analyzer.
    perfview.png
    After the compilation has finished Unity does something that takes a noticeable amount of time. I don't know what it is. My guess, it can be serialization and deserialization.
     
    Last edited: May 18, 2016
  41. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,404
    @ludiq
    Try this:
    1. Open Unity Profiler.
    2. Enable 'Profile Editor".
    3. Reimport any script file to trigger the recompilation.
    4. Find a spike in the profiler.
    5. Check what's going on there.
     

    Attached Files:

    • 1.png
      1.png
      File size:
      22.2 KB
      Views:
      537
    • 2.png
      2.png
      File size:
      32.1 KB
      Views:
      731
  42. MardukCorp

    MardukCorp

    Joined:
    May 21, 2016
    Posts:
    64
    Hi there!

    I installed the newest version today but when I try to debug my project I get "missing ;" errors everywhere, for example at
    Code (CSharp):
    1. public static UnityTaskScheduler MainThreadScheduler => UpdateScheduler;
    2. public static TaskScheduler ThreadPoolScheduler => TaskScheduler.Default;
     
  43. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,404
    What IDE do you use for debugging?
    Do these messages appear in Unity console or inside the IDE?

    PS
    If you use MonoDevelop that comes with Unity, try to disable "Use MSBuild engine ..." in the project settings.
    md.PNG

    Since Unity compiles everything itself there's no point in doing the same job inside MonoDevelop as well.
     
    Last edited: May 22, 2016
  44. mdrotar

    mdrotar

    Joined:
    Aug 26, 2013
    Posts:
    377
    This still seems to be an issue for me occasionally. I manually fix it and eventually it comes back, with VSTU overwriting the project files again. Not sure exactly what conditions cause it though.
     
  45. Plutoman

    Plutoman

    Joined:
    May 24, 2013
    Posts:
    257
    Do you know of any way to dynamically compile using Roslyn on a runtime basis? Including Mac/Linux, ideally?

    Alternatively - to use CodeDOM but preserve the features that were added here?

    I've been browsing and I feel like some approach should be possible - but it's a lot to learn in an afternoon to understand how the compilers are setup.
     
  46. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,404
    I haven't used CodeDOM yet, don't know how it works and what are the requirements and differences on Win/Mac/Linux.

    The most primitive solution that should work:
    1. Generate or fetch some C# code, save it in a file.
    2. Launch Roslyn or mcs.exe as a separate process with command line parameters to compile the cs-file to a dll.
    3. Load the dll and do whatever you like with its content. It's pretty easy.
     
    Plutoman likes this.
  47. Ludiq

    Ludiq

    Joined:
    Mar 6, 2015
    Posts:
    594
    I'm not certain it has anything to do with your wrapper, but I'm getting crashes on every script change recently. It seems to happen after compilation. Do you know what Unity even does after compilation finishes (when that little roller icon stays frozen?)

    EDIT: Doesn't have anything to do with your wrapper.
     
    Last edited: May 26, 2016
  48. Plutoman

    Plutoman

    Joined:
    May 24, 2013
    Posts:
    257
    CodeDOM is pretty much the same, except being that it's supported by Unity's version of .net, it can generate the assembly in memory rather than on a hard-disk. It's just lacking all the true language features like syntactical understanding - it just only compiles code, and actually wraps to the msc.exe (sp? not sure if that's actually the name, but basically MSBuild).

    However, that said, not a bad idea. I was thinking first that an assembly on disk would be bad, but we would probably just hash the scripts, compile them into an assembly, overwriting the old one. And it does appear that Roslyn is cross-platform.
     
  49. Plutoman

    Plutoman

    Joined:
    May 24, 2013
    Posts:
    257
    One more question - is it okay to use some of your code? Didn't see a license listed on your stuff (attribution is a given, I generally do that even if not required). I've taken some of it to set up a dynamic runtime compilation, set up differently but essentially to use your general code setup to organize the sorting of mac/windows and calling the compiler externally. We compile a class library, load it in, through roslyn. Works great. Adds a ton of flexibility to our scripting to use C# to code. A visual studio solution (not compiled, but just a solution) linked back to the DLL's means we get intellisense for our scripting while still having it runtime compatible.

    It's almost a dream come true - it's like a scripting engine that's actually powerful. Who knew!
     
  50. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,404
    fantastisch_ likes this.