Jump to content
coffeetable

Decompiling the beta

Recommended Posts

Instructions for decompiling the beta:

  1. Go download and install ILSpy: http://ilspy.net/
  2. Run it, then use it to open "Steam\SteamApps\common\Pillars of Eternity - Public Beta\PillarsOfEternity_Data\Managed\Assembly-CSharp.dll"
  3. You can now explore the decompiled code via the "Assembly-CSharp" node in the tree on the left. Thanks to this being C#, it's pretty readable. Most of Obsidian's work is in the "-" subnode, indicating the global namespace.
  4. Optional: to export the code from the tool, click on the Assembly-CSharp node in the tree, then File->Save Code. It'll create a .csproj which can be loaded using Visual Studio, or you can just poke around with the text editor of your choice.

This thread can be for discussing anything you come across. Be warned, there are obviously gonna be a lot of spoilers in there.

 

If any of the Obsidian programmers happen across this: how did CharacterStats.cs and StatusEffects.cs come about? I know some of it is bloat from the compiler, but both are north of 4,000 lines. Do all games look like this internally? How do you debug them?

Edited by coffeetable
  • Like 2

Share this post


Link to post
Share on other sites

I've been using dotPeek.

 

All the data for the old armor system is in the CharacterData as well as WeaponAttack (or whatever it's cold), looks like they haven't been removing things as they go along.

Share this post


Link to post
Share on other sites

Did you get a bunch of errors in PE_StreamTile.cs, in the LoadTexturesAsync() method? It's all mangled...

 

Edit: I'm using ILSpy, and saved the code.

 

Example of what I'm talking about:

[DebuggerHidden]
    private IEnumerator LoadTexturesAsync(string levelName, LevelInfo levelInfo)
    {
        PE_StreamTile.<LoadTexturesAsync>c__Iterator2B <LoadTexturesAsync>c__Iterator2B = new PE_StreamTile.<LoadTexturesAsync>c__Iterator2B();
        <LoadTexturesAsync>c__Iterator2B.levelName = levelName;
        <LoadTexturesAsync>c__Iterator2B.<[DebuggerHidden] private IEnumerator LoadTexturesAsync(string levelName, LevelInfo levelInfo) { PE_StreamTile.<LoadTexturesAsync>c__Iterator2B <LoadTexturesAsync>c__Iterator2B = new PE_StreamTile.<LoadTexturesAsync>c__Iterator2B(); <LoadTexturesAsync>c__Iterator2B.levelName = levelName; <LoadTexturesAsync>c__Iterator2B.<$>levelName = levelName; <LoadTexturesAsync>c__Iterator2B.<>f__this = this; return <LoadTexturesAsync>c__Iterator2B; }gt;levelName = levelName;
        <LoadTexturesAsync>c__Iterator2B.<>f__this = this;
        return <LoadTexturesAsync>c__Iterator2B;
    }

 

Also tried dotpeek, got other (different) manglings...

Telerik JustDecompiler, no love either...

 

How'd you guys get this to build?

Edited by PrimeHydra

Ask a fish head

Anything you want to

They won't answer

(They can't talk)

Share this post


Link to post
Share on other sites

I used dotPeek, Net Reflector and ildasm also work (for decompiling).

 

To compile I used ilasm, but Reflexil works too.

Share this post


Link to post
Share on other sites

I used dotPeek, Net Reflector and ildasm also work (for decompiling).

 

To compile I used ilasm, but Reflexil works too.

So you're editing the IL directly, not the decompiled (erroneous) CSharp code? Ugh...


Ask a fish head

Anything you want to

They won't answer

(They can't talk)

Share this post


Link to post
Share on other sites

Hats off to you then, you're a serious hax0r. I need my Intellisense :)


Ask a fish head

Anything you want to

They won't answer

(They can't talk)

Share this post


Link to post
Share on other sites

I am absolutely woeful at programming, but the code is not toooooo dissimilar. If you use the C# as a reference it's pretty easy to make small changes, but I'm not too confident about adding methods and stuff yet.

Share this post


Link to post
Share on other sites

Did you get a bunch of errors in PE_StreamTile.cs, in the LoadTexturesAsync() method? It's all mangled...

 

Edit: I'm using ILSpy, and saved the code.

 

Example of what I'm talking about:

[DebuggerHidden]

    private IEnumerator LoadTexturesAsync(string levelName, LevelInfo levelInfo)

    {

        PE_StreamTile.<LoadTexturesAsync>c__Iterator2B <LoadTexturesAsync>c__Iterator2B = new PE_StreamTile.<LoadTexturesAsync>c__Iterator2B();

        <LoadTexturesAsync>c__Iterator2B.levelName = levelName;

        <LoadTexturesAsync>c__Iterator2B.<[DebuggerHidden] private IEnumerator LoadTexturesAsync(string levelName, LevelInfo levelInfo) { PE_StreamTile.<LoadTexturesAsync>c__Iterator2B <LoadTexturesAsync>c__Iterator2B = new PE_StreamTile.<LoadTexturesAsync>c__Iterator2B(); <LoadTexturesAsync>c__Iterator2B.levelName = levelName; <LoadTexturesAsync>c__Iterator2B.<$>levelName = levelName; <LoadTexturesAsync>c__Iterator2B.<>f__this = this; return <LoadTexturesAsync>c__Iterator2B; }gt;levelName = levelName;

        <LoadTexturesAsync>c__Iterator2B.<>f__this = this;

        return <LoadTexturesAsync>c__Iterator2B;

    }

 

Also tried dotpeek, got other (different) manglings...

Telerik JustDecompiler, no love either...

 

How'd you guys get this to build?

That's not really mangling, it's because decompilers are not that smart about some high-level C# features like iterator blocks and async methods, so they show you the transformed code rather than its original high-level form. The DebuggerHidden attributes already tells you that this is almost certainly compiler generated code. The name of this method suggests that it should be an async method, but it returns IEnumerator so I'm not entirely sure. Perhaps async is implemented using enumerators underneath.

 

On that note, it's pretty nice that they are using such state-of-the-art features, it shows some high level of expertise with the language and hints that the code is probably of good quality.

Edited by Zeckul
  • Like 1

Share this post


Link to post
Share on other sites

 

Did you get a bunch of errors in PE_StreamTile.cs, in the LoadTexturesAsync() method? It's all mangled...

 

Edit: I'm using ILSpy, and saved the code.

 

Example of what I'm talking about:

[DebuggerHidden]

    private IEnumerator LoadTexturesAsync(string levelName, LevelInfo levelInfo)

    {

        PE_StreamTile.<LoadTexturesAsync>c__Iterator2B <LoadTexturesAsync>c__Iterator2B = new PE_StreamTile.<LoadTexturesAsync>c__Iterator2B();

        <LoadTexturesAsync>c__Iterator2B.levelName = levelName;

        <LoadTexturesAsync>c__Iterator2B.<[DebuggerHidden] private IEnumerator LoadTexturesAsync(string levelName, LevelInfo levelInfo) { PE_StreamTile.<LoadTexturesAsync>c__Iterator2B <LoadTexturesAsync>c__Iterator2B = new PE_StreamTile.<LoadTexturesAsync>c__Iterator2B(); <LoadTexturesAsync>c__Iterator2B.levelName = levelName; <LoadTexturesAsync>c__Iterator2B.<$>levelName = levelName; <LoadTexturesAsync>c__Iterator2B.<>f__this = this; return <LoadTexturesAsync>c__Iterator2B; }gt;levelName = levelName;

        <LoadTexturesAsync>c__Iterator2B.<>f__this = this;

        return <LoadTexturesAsync>c__Iterator2B;

    }

 

Also tried dotpeek, got other (different) manglings...

Telerik JustDecompiler, no love either...

 

How'd you guys get this to build?

That's not really mangling, it's because decompilers are not that smart about some high-level C# features like iterator blocks and async methods, so they show you the transformed code rather than its original high-level form. The DebuggerHidden attributes already tells you that this is almost certainly compiler generated code. The name of this method suggests that it should be an async method, but it returns IEnumerator so I'm not entirely sure. Perhaps async is implemented using enumerators underneath.

 

On that note, it's pretty nice that they are using such state-of-the-art features, it shows some high level of expertise with the language and hints that the code is probably of good quality.

 

Would be nice if I could get it into a compilable form. I know "mangling" might not be the right word. How about uncompilable output? It's the same to my eyes :)

Edited by PrimeHydra

Ask a fish head

Anything you want to

They won't answer

(They can't talk)

Share this post


Link to post
Share on other sites

dotPeek 1.1 and ILSpy boast that they can do this, but I haven't tried.

 

Note that Unity code is likely compiled with the mono compiler rather than the "standard" one in Visual Studio, so it's likely that these tools fail because they're only designed to recognize the specific patterns emitted by one specific compiler.

Edited by Zeckul

Share this post


Link to post
Share on other sites

I tried with dotpeek, ILSpy, Redgate Reflector as well. The output always had some weird unucompilable stuff in it. Eventually found on their forums that they're not trying to produce compilable code, due to security concerns. Makes sense...but I'm all set with hacking IL, I'll leave that to the hardcore.


Ask a fish head

Anything you want to

They won't answer

(They can't talk)

Share this post


Link to post
Share on other sites

×
×
  • Create New...