Jump to content

Beyond DefaultGameCore.ini - Analyzing the Game Scripts


Beknatok

Recommended Posts

Oh, is that true? I hadn't thought about that. I guess it makes sense--maybe it's a debugging facility that most devs don't turn off. You know, when a new test build goes out you lock the hashes for all the game files into the executable so that your testers can't accidentally run the game with bits and pieces of old code. If that's the case, maybe there's a command line argument for some kind of "developer mode" where it doesn't bother with such sanity checks.

 

It only hash checks some files, which is weird. It's to guard against modifying the files. If they were concerned with data corruption, then they'd be hash checking everything (but, as I proved in another thread, that would take too long haha... like 12+ seconds additional startup time).

 

Anyways... I've been pouring over some of these scripts via hexediting, and the bytecode just sucks. Big time. I'm used to seeing java bytecode, but this is nothing like it.

 

The format for it seems to try to obfuscate the code. For example:

 

¢…..2U.......…..Â...................±...-...)...a....à?..²......š...........2U......ÿÿ..S..............

 

Is supposedly the bytecode for:

 

simulated state Executing
{

Begin:
Sleep(1.75);
CompleteAction();
}

 

Really? Because that makes me want to punch myself in the face. It just screams obfuscation.

 

EDIT: Ok, I'm being a little dramatic. ;) But still. It's ugly ass bytecode, heh. I hate looking at little endian numbers.

 

Anyways, I'm going to test reducing the delay when you overwatch/hunker down. I know you can just switch to another character manually during the delay, but whatever. The delay is unnecessary.

 

UPDATE: Yeah, I did it! haha... my first xcom mod :D I changed the delays from 1.75 seconds to .25, and it's awesome. :D

Edited by Daemonjax
Link to comment
Share on other sites

  • Replies 102
  • Created
  • Last Reply

Top Posters In This Topic

agree, for corruption they would have other ways

think its more like standart function of the engine

and they used it to protect the gamelogic and netcode

 

Edit:

 

Thanks god i'm not the only one who thinks this :D

Maybe its just because i didnt see ue bytecode before but its quite confusing

 

Edit2:

Grats, its an awesome feeling seeing a change after so much work, isnt it ? :D

Edited by dreadylein
Link to comment
Share on other sites

I don't have any experience with Java bytecode. Can you actually look at it in ASCII and see what's going on? I just assumed all compiled languages had to be read in hex (or run through a disassembler of some kind). In hex, I find it mostly makes sense, but there's some stuff that's presumably meant to improve performance that's just frustrating. Like the fact that there's a separate bytecode for constant 0 and 1. Or the way conditionals are an actual, literal thing, rather than semantic sugar that the compiler just turns into CMPxx and JMP instructions. And yeah, little-endian sucks. I'm sure there's some reason why it's better in this case, but I can't imagine what it was.

 

I guess they had to write their own interpreter by hand to read the compiled script language, and if those design choices made it easier for them to write the interpreter, I suppose I shouldn't begrudge them for it.

 

Honestly, I think it makes sense to me because it kind of works the way I was planning something similar for a game engine I'm working on. You basically parse all the scripts that are going into the package, get every unique token, put them in a table, and then replace the text tokens with their table index. So, "CompleteAction()" in your example gets turned into 0x0122 (or, maybe 0x2201, if it's little-endian? I don't understand endianness as well as I really should). "simulated" and "state" also probably have a specific bytecode associated with them, but since they're native to the language it's not stored in any of the tables in the UPK. This way, you can retain all your semantic information, so you can decompile scripts perfectly, but it's still fairly efficient to read using (I'm assuming) some kind of FSM.

 

So yeah, basically, I don't think it's obfuscation, I just think that it was designed primarily for the interpreter, not for hand-editing. Though, personally, I would have also allowed it to load uncompiled scripts, and compile them manually during startup, like HLSL. Maybe you can, and it's just a feature that's disabled in release builds.

Link to comment
Share on other sites

Hey guys,

 

I was wondering you could help me out... A lot of people have been wondering about item build times and how they are instant. This code pertains to why:

 

function int GetItemBuildTime(XComGame.XGGameData.EItemType eItem, XGStrategyActor.EItemCategory eItemCat, int iEngineerDays)
{
local float fBalanceFactor;

// End:0x19 Loop:False
if(iEngineerDays == -1)
{
	return -1;
}
// End:0x52 Loop:False
if(eItemCat != 3 || (IsShipWeapon(eItem)))
{
	iEngineerDays = 0;
}
fBalanceFactor = class'XGTacticalGameCore'.default.ITEM_TIME_BALANCE;
return int(float(iEngineerDays * 24) * fBalanceFactor);
}

 

This is under Xcomstratygame XGItemTree: It essentially says, if item category is category 3, or it's a aircraft weapon, the time to build is -1 hours... Anybody know how to change this? or maybe get rid of it entirely? Can we do this yet, or are we only really able to change small parts of the scripts?

 

*** EDIT: I had the wrong code.... lol

Edited by tbkiah
Link to comment
Share on other sites

How much you are able to change only depends on the time you inviest tbh ;)

 

IF conditions are done with a Jumpifnotequal loop

 

Guess changing the Jumpifnotequal to a unconditional jump would do the trick here as the next token after the jump is the leaving point

So in Theory the script would skip this step undconditional

Link to comment
Share on other sites

 

This is under Xcomstratygame XGItemTree: It essentially says, if item category is category 3, or it's a aircraft weapon, the time to build is -1 hours... Anybody know how to change this? or maybe get rid of it entirely? Can we do this yet, or are we only really able to change small parts of the scripts?

 

*** EDIT: I had the wrong code.... lol

 

Great find, man!

 

But what the code actually does:

 

if item category is NOT category 3, or it's a aircraft weapon, the time to build is 0 hours. :D

 

 

I'll look at it, and try to come up with a mod that'll work.

Edited by Daemonjax
Link to comment
Share on other sites

<stuff about java>

 

if(eItemCat != 3

 

I think I found the 3, but how do we change the != into an == ?

 

Where do I get that information from on the web?

 

 

I'd like to rewrite it as:

 

if(eItemCat == 255

 

That should essentially remove that code, since I doubt there's an item category 255, and even if there is, whatever. ;)

Edited by Daemonjax
Link to comment
Share on other sites

That's odd, I just opened an old .class file from ages ago and it doesn't look anything like that. It has what seems to be a string table at the beginning, and the rest looks very much like compiled UnrealScript. Maybe we're talking about different things here? I thought the only two states for Java were source and compiled bytecode (ie., "javac Blar.java") . Is there some middle state between those two I didn't know about? Maybe compiled applets are different than compiled console applications?

 

Back on topic a bit, has anyone figured out where the game saving happens? I glanced through most of the main UPKs but couldn't pin down the exact spot it all happens. I have a sinking suspicion it's just dumping all those Checkpoint instances, which look like they're going to be a nightmare to parse. I looked at the save files themselves and it's bizarre--strings seem to be fractured and incomplete and sometimes you see bits and pieces of a variable name. Like, where you'd expect to see the value of bPsiGift, you see "bPsiG." Identifying (by inspection) an actual value in all that mess is impossible.

 

EDIT: OH! I see what you're talking about. You're talking about the disassembled code. Yeah, that makes more sense. What we see in UE Explorer is the disassembled code for UnrealScript, equivalent to what you get from javap. I was talking about the compiled UnrealScript we see in the actual UPK, and the compiled Java code you get from javac. Both are pretty similar. I wouldn't mind having a tool for UnrealScript like the JBE or Visual Studio's disassembly view, where it views it as an assembly language. THAT would be more convenient.

Edited by kanet32
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.

×
×
  • Create New...