PDA

View Full Version : changing engine source files for a TC?



dcalogue
11-14-2009, 08:09 PM
Hey all, this is my first post here, so excuse the noobnees of the question.
I have plenty of experience programming for games (in several engines) but I am new to UE3.

I have readed several times that you shouldn't change the source UT files, instead you should extend the classes to inherit (and change) the behaviors for your game. I understand this for a mutator or a mod, so it remains compatible with UT3 and you can distribute it to other people.

Does this remains as a rule for UDK and total conversions (or games from scratch)? :confused:

I want to base my vehicle mechanics from the UT vehicles, but I want to make some heavy changes that are easier to make from the UT files instead of extending the classes. Do you foresee a problem with this?

Thanks for any opinions on this

immortius
11-14-2009, 08:39 PM
Strictly speaking you are free to change the base packages now. However:

* Be careful not to lose any native functionality
* Be aware that changing base scripts will make upgrading to newer versions of the UDK more difficult. You might be able to mitigate that with some careful version control (http://svnbook.red-bean.com/en/1.5/svn.advanced.vendorbr.html)
* And be aware you can royally screw things up because the editor and engine is dependant on some of the base classes.

dcalogue
11-14-2009, 08:55 PM
Hi immortius, thanks for the reply.

I ALWAYS use version control when working with source files (even in home projects) and I'm used to having to merge new versions of engines to my existing code, so we are safe on that side.
Good point with the editor dependences, I will be really careful with that.

So far it's actually easier than I thought it would be (right now I'm working on allowing the player control a vehicle from any seat, this was a nightmare if I tried extending classes but I think its pretty straightforward by changing just a few functions and some hardcoded seat numbers)

SpartanDonut
11-14-2009, 10:16 PM
I'm kind of pulling this out of somewhere inappropriate so correct me if my logic is wrong on this...

Couldn't you extend the base class and just rewrite the function? I feel like I have seen this before to add functionality where you would also call Super.FunctionName() to be sure to include the parent class' functionality. But if you want to override functionality completely, couldn't you simply not include that function call?

If this works, I would then copy the parents code into my function, and change the code as I saw fit, much like you are currently doing to the base class files.

JeremyStieglitz
11-14-2009, 11:41 PM
You can change any class that's not marked "native" without trouble, though as mentioned above, you should probably keep track of your changes so that you can smoothly re-integrate them with subsequent UDK releases.

However, if the class is marked "native" at the top, that means the Engine will attempt to regenerate the C++ exports for the class, which will currently cause a crash if you change or add any of its members. Don't mess with those classes! Epic will probably correct this with a more obvious error message in a future UDK release, but it will not likely ever be supported to change such classes since they are tied to a specific native layout in the executable.

However, specific "native" classes that are also marked "noexport" (such as Object.uc) will not actually attempt to auto-regenerate the exports, and you can add new _functions_ (which don't actually change the native layout) to such "native" classes without error.

So yeah, it's pretty testy. And prior to UDK Beta 2, if you broke your core compiled script packages by screwing with the native classes, the app would fail to start as it required pre-existing script packages to even launch the Unreal Code Compiler.

This has been fixed in UDK Beta 2 (which will now compile scripts from scratch), so you can at least play around, as long as you have a back-up of the original script code in case you break anything :)

So if you do intend to modify any Core/Engine/Framework classes, be sure to keep a backup of their script code files (.uc's), should anything go awry!

-Jeremy Stieglitz

JeremyStieglitz
11-14-2009, 11:51 PM
By the way, as SpartanDonut says, it's usually a better option to simply override the method you want to change, in a subclass, rather than change the base class' original version.

That's safer and generally fits better within the ideals of object-oriented design.

But in some cases that may not be possible, if for example you want two objects at different areas of the framework hierarchy to both share some new functionality. Then you may find yourself digging around the base framework :cool:

-Jer

SpartanDonut
11-15-2009, 01:23 AM
But in some cases that may not be possible, if for example you want two objects at different areas of the framework hierarchy to both share some new functionality. Then you may find yourself digging around the base framework :cool:

-Jer

Ah, but on the contrary... what should actually be done is another level of inheritance! You create a first class that extends the core class and overrides the functionality, and then you would create the classes that will use the functionality extending the first class you made. Or maybe I misunderstood?

immortius
11-15-2009, 01:49 AM
There is what ideally should be done, and what can practically be done. If you want to add some functionality to a class which has hundreds of existing subclasses... Well, you could subclass it and then make copies of every single subclass so that they inherit from the modified class. But that isn't all that reasonable, and you'll have problems with having to patch in code changes from new versions of the UDK. And you can't do that at all if any of the subclasses are native.

In some cases an interface can be used though. Say you wanted a whole bunch of different existing classes to have a power rating - vehicles, pawns, karma actors, weapons. What you could do is create an interface



interface IPowered;

simulated function float GetPowerLevel( );


And then every subclass you want to have a power level just needs to implement it.


class MyPawn extends UTPawn implements (IPowered);

simulated function float GetPowerLevel( )
{
return 9001;
}

To get the power level of something, you'ld just cast it to the interface and if it is not none, call the function.

But that only helps in some cases.

dcalogue
11-15-2009, 11:50 AM
There is what ideally should be done, and what can practically be done. If you want to add some functionality to a class which has hundreds of existing subclasses... Well, you could subclass it and then make copies of every single subclass so that they inherit from the modified class. But that isn't all that reasonable, and you'll have problems with having to patch in code changes from new versions of the UDK. And you can't do that at all if any of the subclasses are native.

My point exactly.

Besides, if I'm trying to change the function EnterDriver(Pawn P), which is extremely recursive, I would have to copy the content of all the parent EnterDriver functions to make a big local function that contains all the code (since I can't use Super.Super.EnterDriver(P)).

Lets say I want to make a subclass of the Cicada and the Manta (to name a couple), I would have to duplicate the same code in both subclasses, and if I just create other vehicles from scratch (derived from a main class) I would lose the cpp code for those classes (among others) which is pretty handy (try to make a subclass of UTAirVehicle instead of subclass of UTVehicle_Cicada and you will lose movement code that is really usefull when prototyping, so you don't have to program the movement behavior again).

Valeranth
11-15-2009, 01:26 PM
My point exactly.
(since I can't use Super.Super.EnterDriver(P)).


Super(Pawn).EnterDriver(P); will call the EnterDriver function in the pawn class.