Editing Engine Files (Mutator)?

Discussions about Coding and Scripting
User avatar
ANUBITEK
Adept
Posts: 261
Joined: Sun Dec 28, 2014 1:10 am
Location: Anubitek

Editing Engine Files (Mutator)?

Post by ANUBITEK »

This is a bit of a 227 question but sort of ties globally to Unreal Tournament and Unreal.

I want to edit Unreal 227's Mutator script with the following bit of script because I need it for my mod:

Code: Select all

function bool AlwaysKeep(Actor Other)
{
	if ( PlayerPawn(Other) != None && !Other.IsA('Bot') )
	{
		Pawn(Other).PlayerReplicationInfoClass = Class'RPG_PlayerReplicationInfo';
		return True;
	}
	if ( NextMutator != None )
		return ( NextMutator.AlwaysKeep(Other) );
	return false;
}
But I don't know if it would be wise to edit an Engine file. Could someone post any links to topics on whether or not this type of thing should be done, also how can I do this and have my changes actually remain after I compile? Or just reply in topic, that works too. This falls yet again under the category of "things I haven't done to date". I really don't want to touch Engine files, but it is something I kinda have to do to give the player a custom PlayerReplicationInfo so they can use my level up thing (also mad props to Jack for letting me know I can use mutators and replications for this task). This bit of code is actually already in Unreal Tournament's Mutator class:

Code: Select all

/* Force game to always keep this actor, even if other mutators want to get rid of it
*/
function bool AlwaysKeep(Actor Other)
{
	if ( NextMutator != None )
		return ( NextMutator.AlwaysKeep(Other) );
	return false;
}
Last edited by ANUBITEK on Fri Jan 29, 2016 3:20 pm, edited 1 time in total.
<<| http://uncodex.ut-files.com/ |>>

Code reference for UGold, UT99, Unreal2, UT2k3, UT3
Additional Beyond Unreal Wiki Links
wiki.beyondunreal.com/Legacy:Console_Bar
wiki.beyondunreal.com/Exec_commands#Load
wiki.beyondunreal.com/Legacy:Exec_Directive#Loading_Other_Packages
wiki.beyondunreal.com/Legacy:Config_Vars_And_.Ini_Files
wiki.beyondunreal.com/Legacy:INT_File
User avatar
Wormbo
Adept
Posts: 258
Joined: Sat Aug 24, 2013 6:04 pm
Contact:

[Answer] Editing Engine Files (Mutator)

Post by Wormbo »

Don't edit engine classes for your mod. Every game type has a thing called "base mutator" that is essentially the mutator loaded before all others. It's really the only mutator that needs to expect being notified directly by the game type. That's the place where you should place such modifications - your own base mutator.

[edit]
Don't you feel it's a bit pointless prefixing your question with a "[Question]" tag? I mean, typography invented the question mark for that purpose.
JackGriffin
Godlike
Posts: 3774
Joined: Fri Jan 14, 2011 1:53 pm
Personal rank: -Retired-

Re: [Answer] Editing Engine Files (Mutator)

Post by JackGriffin »

Wormbo wrote: Don't you feel it's a bit pointless prefixing your question with a "[Question]" tag?
Symptom of a larger problem. Guys keep using a framing hammer to place a thumbtack.

UScript isn't about elegance, it's about simplicity. Gravitate to the easiest, simplest method to achieve your goals. Look at wormbos last four or five answers on this forum and see that he vastly simplified what was being proposed. Pay attention to his method as much as his result.

Nelsona is another good guy at this. His fixes are direct and simple, and they are backed up by testing.

This engine has been modded for a decade and a half. You most likely are not going to blaze new ground. If something is done a certain way then there is very likely a good reason it is so.
So long, and thanks for all the fish
User avatar
ANUBITEK
Adept
Posts: 261
Joined: Sun Dec 28, 2014 1:10 am
Location: Anubitek

Re: Editing Engine Files (Mutator)

Post by ANUBITEK »

Don't edit engine classes for your mod. Every game type has a thing called "base mutator" that is essentially the mutator loaded before all others. It's really the only mutator that needs to expect being notified directly by the game type. That's the place where you should place such modifications - your own base mutator.
This engine has been modded for a decade and a half. You most likely are not going to blaze new ground. If something is done a certain way then there is very likely a good reason it is so.
Makes sense, I'll post what is working when I am able to get to working on it.
Don't you feel it's a bit pointless prefixing your question with a "[Question]" tag? I mean, typography invented the question mark for that purpose.
Symptom of a larger problem. Guys keep using a framing hammer to place a thumbtack.
Ham fisted, but I see your point and will refrain from doing it in the future. I was doing it because I thought the convention would be easier to use to tell what has and hasn't been looked at and solved, but I see now how it could easily get obnoxious.
<<| http://uncodex.ut-files.com/ |>>

Code reference for UGold, UT99, Unreal2, UT2k3, UT3
Additional Beyond Unreal Wiki Links
wiki.beyondunreal.com/Legacy:Console_Bar
wiki.beyondunreal.com/Exec_commands#Load
wiki.beyondunreal.com/Legacy:Exec_Directive#Loading_Other_Packages
wiki.beyondunreal.com/Legacy:Config_Vars_And_.Ini_Files
wiki.beyondunreal.com/Legacy:INT_File
JackGriffin
Godlike
Posts: 3774
Joined: Fri Jan 14, 2011 1:53 pm
Personal rank: -Retired-

Re: Editing Engine Files (Mutator)?

Post by JackGriffin »

I'm the reigning king of overdone so trust me, I get it. I beat my head in trying to fix MonsterHunt. You should see the things I was trying. Along comes Nelsona and he politely
Image
me and showed me how everything I was doing was wrong and could be fixed by removing the ServerPackage line. So simple yet I never even considered it. Instead I went right to the 400 lines of replacement code and 22 replacement classes.

Reminded yet again I'll never be the smartest guy in the room.
So long, and thanks for all the fish
User avatar
ANUBITEK
Adept
Posts: 261
Joined: Sun Dec 28, 2014 1:10 am
Location: Anubitek

Re: Editing Engine Files (Mutator)?

Post by ANUBITEK »

Fair enough. However that still leaves my question somewhat unanswered: if I shouldn't edit engine files, then how could I add my code properly? The issue with this particular bit of code is that it is checking all Mutators for a piece of code that wouldn't be in the Engine file through the "return ( NextMutator.AlwaysKeep(other) );" check. Below is said function again, but this time I've included Engine.Mutator as well.

Code: Select all

function bool AlwaysKeep(Actor Other)
{
	if ( PlayerPawn(Other) != None && !Other.IsA('Bot') )
	{
		Pawn(Other).PlayerReplicationInfoClass = Class'RPG_PlayerReplicationInfo';
		return True;
	}
	if ( NextMutator != None )
		return ( NextMutator.AlwaysKeep(Other) );
	return false;
}

Code: Select all

//=============================================================================
// Mutator.
// called by the IsRelevant() function of DeathMatchPlus
// by adding new mutators, you can change actors in the level without requiring
// a new game class.  Multiple mutators can be linked together.
//=============================================================================

class Mutator expands Info;

var Mutator NextMutator;
var class<Weapon> DefaultWeapon;

event PreBeginPlay()
{
	//Don't call Actor PreBeginPlay()
}

// return what should replace the default weapon
// mutators further down the list override earlier mutators
function Class<Weapon> MutatedDefaultWeapon()
{
	local Class<Weapon> W;

	if ( NextMutator != None )
	{
		W = NextMutator.MutatedDefaultWeapon();
		if ( W == Level.Game.DefaultWeapon )
			W = MyDefaultWeapon();
	}
	else
		W = MyDefaultWeapon();
	return W;
}

function Class<Weapon> MyDefaultWeapon()
{
	if ( DefaultWeapon != None )
		return DefaultWeapon;
	else
		return Level.Game.DefaultWeapon;
}

function AddMutator(Mutator M)
{
	if ( NextMutator == None )
		NextMutator = M;
	else
		NextMutator.AddMutator(M);
}

/* ReplaceWith()
Call this function to replace an actor Other with an actor of aClass.
*/
function bool ReplaceWith(actor Other, string aClassName)
{
	local Actor A;
	local class<Actor> aClass;

	aClass = class<Actor>(DynamicLoadObject(aClassName, class'Class'));
	if ( aClass != None )
		A = Spawn(aClass,,Other.tag,Other.Location, Other.Rotation);
	if ( Other.IsA('Inventory') && Inventory(Other).myMarker != None )
	{
		Inventory(Other).MyMarker.markedItem = Inventory(A);
		if ( Inventory(A) != None )
			Inventory(A).myMarker = Inventory(Other).myMarker;
		Inventory(Other).myMarker = None;
	}
	if ( A != None )
	{
		A.event = Other.event;
		A.tag = Other.tag;
		return true;
	}
	return false;
}

function bool IsRelevant(Actor Other, out byte bSuperRelevant)
{
	local bool bResult;

	bResult = CheckReplacement(Other, bSuperRelevant);

	if ( bResult && (NextMutator != None) )
		bResult = NextMutator.IsRelevant(Other, bSuperRelevant);

	return bResult;
}

function bool CheckReplacement(Actor Other, out byte bSuperRelevant)
{
	return true;
}
EDIT:
Spoiler
I know that it has already been discussed that Unreal 227 code/materials/mods shouldn't be discussed here, but whenever I take a question over to OldUnreal I keep getting 13+ response threads that I never ultimately get a cut-and-dry answer to because of a certain Captain Falcon. If I had a grain of salt for every reaction image he posted, I might have a small packet for which to ruin a burger with. In fact if it wasn't for this site and the people on it, I wouldn't even have a PlayerPawn coded (again mod props to the Higor).
<<| http://uncodex.ut-files.com/ |>>

Code reference for UGold, UT99, Unreal2, UT2k3, UT3
Additional Beyond Unreal Wiki Links
wiki.beyondunreal.com/Legacy:Console_Bar
wiki.beyondunreal.com/Exec_commands#Load
wiki.beyondunreal.com/Legacy:Exec_Directive#Loading_Other_Packages
wiki.beyondunreal.com/Legacy:Config_Vars_And_.Ini_Files
wiki.beyondunreal.com/Legacy:INT_File
User avatar
Barbie
Godlike
Posts: 2792
Joined: Fri Sep 25, 2015 9:01 pm
Location: moved without proper hashing

Re: Editing Engine Files (Mutator)?

Post by Barbie »

LannFyre wrote:However that still leaves my question somewhat unanswered
So your aim is to change the default PlayerReplicationInfo class? I've done that in this way:

Code: Select all

class KHMBase expands Mutator config(BarbiesWorld);
...
function ModifyLogin(out class<playerpawn> SpawnClass, out string Portal, out string Options) {
/******************************************************************************
******************************************************************************/
	Super.ModifyLogin(SpawnClass, Portal, Options); // calls NextMutator.ModifyLogin
	
	SpawnClass.default.PlayerReplicationInfoClass = Class'PlayerReplicationInfoSB';
}
...
"Multiple exclamation marks," he went on, shaking his head, "are a sure sign of a diseased mind." --Terry Pratchett
User avatar
ANUBITEK
Adept
Posts: 261
Joined: Sun Dec 28, 2014 1:10 am
Location: Anubitek

Re: Editing Engine Files (Mutator)?

Post by ANUBITEK »

So this is what compiles, just wanted to get a second opinion on whether or not this would be suitable or if I should add some more sanity checks.

Code: Select all

var RPG_GameMutator NextRPGMutator;

function bool AlwaysKeep(Actor Other)
{
	if ( PlayerPawn(Other) != None && !Other.IsA('Bot') )
	{
		Pawn(Other).PlayerReplicationInfoClass = Class'RPG_PlayerReplicationInfo';
		return True;
	}
	if ( NextMutator != None && NextMutator == Class'RPG_GameMutator' )
		return ( NextRPGMutator.AlwaysKeep(Other) );
	return false;
}
Last edited by ANUBITEK on Fri Jan 29, 2016 5:43 pm, edited 1 time in total.
<<| http://uncodex.ut-files.com/ |>>

Code reference for UGold, UT99, Unreal2, UT2k3, UT3
Additional Beyond Unreal Wiki Links
wiki.beyondunreal.com/Legacy:Console_Bar
wiki.beyondunreal.com/Exec_commands#Load
wiki.beyondunreal.com/Legacy:Exec_Directive#Loading_Other_Packages
wiki.beyondunreal.com/Legacy:Config_Vars_And_.Ini_Files
wiki.beyondunreal.com/Legacy:INT_File
User avatar
Wormbo
Adept
Posts: 258
Joined: Sat Aug 24, 2013 6:04 pm
Contact:

Re: Editing Engine Files (Mutator)?

Post by Wormbo »

Don't mess with the mutator chain that way. Call NextMutator.AlwaysKeep, not something you came up with. You are bound to break things otherwise.
User avatar
Barbie
Godlike
Posts: 2792
Joined: Fri Sep 25, 2015 9:01 pm
Location: moved without proper hashing

Re: Editing Engine Files (Mutator)?

Post by Barbie »

Just a note: In my understanding of object hierarchy a PlayerPawn can never be a Bot. So if PlayerPawn(Other) != None is true, Other.IsA('Bot') is always false.
"Multiple exclamation marks," he went on, shaking his head, "are a sure sign of a diseased mind." --Terry Pratchett
User avatar
ANUBITEK
Adept
Posts: 261
Joined: Sun Dec 28, 2014 1:10 am
Location: Anubitek

Re: Editing Engine Files (Mutator)?

Post by ANUBITEK »

Then that unfortunately brings me back to compiler errors:

Code: Select all

Error: C:\GOG Games\Unreal Gold\RPG_Game_dev\Classes\RPG_GameMutator.uc(28) : Error, Unrecognized member 'AlwaysKeep' in class 'Mutator'
Error: C:\GOG Games\Unreal Gold\RPG_Game_dev\Classes\RPG_GameMutator.uc(28) : Error, Missing ')' in expression
Error: C:\GOG Games\Unreal Gold\RPG_Game_dev\Classes\RPG_GameMutator.uc(28) : Error, Type mismatch in 'Return'
Error: C:\GOG Games\Unreal Gold\RPG_Game_dev\Classes\RPG_GameMutator.uc(28) : Error, Missing ';' before '('
Error: C:\GOG Games\Unreal Gold\RPG_Game_dev\Classes\RPG_GameMutator.uc(28) : Error, ')': Expression has no effect
Error: C:\GOG Games\Unreal Gold\RPG_Game_dev\Classes\RPG_GameMutator.uc(28) : Error, Missing ';' before ')'
So two things need to be fixed -- AlwaysKeep needs to be called, and I need to add in AlwaysKeep to Mutator somehow as subclassing is what part of the issue is. Could someone post an example of this? I'm afraid this is beyond me, to be honest this is code Jack handed to me and while I kind of get it, it appears I understand less of it than I thought. I've already posted 227's Mutator class, here is the custom mutator:

Code: Select all

//=============================================================================
// RPG_GameMutator.
//=============================================================================
class RPG_GameMutator expands Mutator 
	config(RPGGame);

//Setup
var bool Initialized;

function PreBeginPlay()
{
	if ( Initialized ) //sanity check to stop multiple loads of the same mutator
		return;
	if ( NextMutator != None )
		NextMutator.PreBeginPlay();
}

//Add this into Mutator
function bool AlwaysKeep(Actor Other)
{
	if ( PlayerPawn(Other) != None && !Other.IsA('Bot') )
	{
		Pawn(Other).PlayerReplicationInfoClass = Class'RPG_PlayerReplicationInfo';
		return True;
	}
	if ( NextMutator != None )
		return ( NextMutator.AlwaysKeep(Other) );
	return false;
}
Also the call for it in DefaultProperties of RPG_Game:

Code: Select all

defaultproperties
{
	DefaultPlayerClass=Class'RPG_Game_dev.RPG_LionPlatformer'
	DefaultWeapon=none
	MutatorClass=Class'RPG_Game_dev.RPG_GameMutator'
}
Just a note: In my understanding of object hierarchy a PlayerPawn can never be a Bot. So if PlayerPawn(Other) != None is true, Other.IsA('Bot') is always false.
Should the code remain in there then? It is to my understand that it was done as a sanity check to make sure no bots receive the PRI (which they wouldn't anyway, considering this is a single player mod).
<<| http://uncodex.ut-files.com/ |>>

Code reference for UGold, UT99, Unreal2, UT2k3, UT3
Additional Beyond Unreal Wiki Links
wiki.beyondunreal.com/Legacy:Console_Bar
wiki.beyondunreal.com/Exec_commands#Load
wiki.beyondunreal.com/Legacy:Exec_Directive#Loading_Other_Packages
wiki.beyondunreal.com/Legacy:Config_Vars_And_.Ini_Files
wiki.beyondunreal.com/Legacy:INT_File
User avatar
Barbie
Godlike
Posts: 2792
Joined: Fri Sep 25, 2015 9:01 pm
Location: moved without proper hashing

Re: Editing Engine Files (Mutator)?

Post by Barbie »

I've taken your RPG_GameMutator into my project and there it compiles without errors (I had to change 'RPG_PlayerReplicationInfo' of course). You should double check if that what you compile is actually that what you have posted.
LannFyre wrote:
Barbie wrote:a PlayerPawn can never be a Bot.
Should the code remain in there then?
It doesn't matter:

Code: Select all

PlayerPawn(Other) != None
has always the same result as

Code: Select all

PlayerPawn(Other) != None && !Other.IsA('Bot')
Attachments
PawnsHierarchy.jpg
"Multiple exclamation marks," he went on, shaking his head, "are a sure sign of a diseased mind." --Terry Pratchett
User avatar
Wormbo
Adept
Posts: 258
Joined: Sat Aug 24, 2013 6:04 pm
Contact:

Re: Editing Engine Files (Mutator)?

Post by Wormbo »

Just wondering, since AlwaysKeep should be part of the Mutator class, what exactly are you compiling against?
User avatar
sektor2111
Godlike
Posts: 6403
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

Re: Editing Engine Files (Mutator)?

Post by sektor2111 »

Bot, player, I cannot figure why they have to be mentioned twice in some moments.

In my regens + bonuses I was using a sort of "Pawn.PlayerReplicationInfo" and it works properly with Bot too to not mention properly checking if their team match what I need because I'm not interested to add in stage Monsters with replications to mess up into trash.

If I would write again a controller special for 1 team (as MH) I guess I'll setup things different...

This RPG has now a lot of snippets and errors shown are very... nasty. It's still very... basic - you should waste time in modifications first. Looking at things and logging will make you to understand the route from GameInfo forward. What engine does, how is initialized (this chapter I did not love either) example Botpack has a bad TimeDilation setup - read well, reconsider that if game has a bad start will go wrong by default and this is what I think and why I sustain this ex-theory because I have practiced it already, simply all Skaarj fixations logs went vanished - THINGS suddenly started to work properly. Sadly - happened after a few years of blabbering codes - doing fixes over a bad started root rather that attacking root. SO... reconsider first that you need a bit of experience for coding a game-type, else it will be another one never used by nobody. I'm encouraging you to understand how is called AlwaysKeep CheckReplacement and the rest of Relevance things.
For this case I would add logs in those classes called and see what they do. Did they get called or not ? Why AlwaysKeep is not called since it should be ? You have rammed "IsRelevant()" ? Check again what you did.

Aside:

Code: Select all

function PreBeginPlay()
{
   if ( Initialized ) //sanity check to stop multiple loads of the same mutator
      return;
   if ( NextMutator != None )
      NextMutator.PreBeginPlay();
}
Is this useful at something ? Who loads/spawn the same actor ? Unless something evil calls this function with no purpose and then is good a wrapper somehow but I think this is a result of other mods messing calls to our classes making them to run a twice Prebegin PostBegin. If you don't have something harmful at double initialization then you can quit using PrebeginPlay(). Else with doing nothing there, its existence is pretty pointless.
Last time I got rid of things messing with these double starts. How to check ?( - you don't need to believe me). DO a mini-mutator with these functions and add a single log line. See if gets called many times, if yes look what anything else runs in there.
Engine.Mutator

Code: Select all

event PreBeginPlay()
{
	//Don't call Actor PreBeginPlay()
}
As a note.
And now if you load a mutator B for sure the log from PrebeginPlay will pop up. Then if you call that again, probably the log will show again - BAD. The only chained calls which should be used are functions from mutator self-Explanatory those having NextMutator added by default. In mutator class function PostBeginPlay doesn't even exist but it was created later in BotPack and messing a twice call to mother PostBeginPlay which engine calls anyway automatically.
Try to understand bad things done and improve them.

And related to another replication.
First I'll wander if I do really need that. An owned actor cannot track things ? I'm talking about an actor with a TAG which can be fast checked as Higor was describing in some iterator topic.

If certain thing seems to not work/not spawn for sure has relevance check not approved. Make a PreBeginPlay() empty to get rid of relevance test else that actor gets discarded. Btw I would write that prebeginplay empty preventing something to be executed as long as function is null.

Don't get as rules what I'm saying, these are my conclusions after toying with a few default modified game-types and the rest of stuff.
JackGriffin
Godlike
Posts: 3774
Joined: Fri Jan 14, 2011 1:53 pm
Personal rank: -Retired-

Re: Editing Engine Files (Mutator)?

Post by JackGriffin »

If I remember you are creating your own game type for this? Just assign your custom pri in GameRules.
So long, and thanks for all the fish
Post Reply