HUD Break

Discussions about Coding and Scripting
Post Reply
User avatar
Nephew9999
Adept
Posts: 288
Joined: Wed Jul 06, 2011 11:20 am

HUD Break

Post by Nephew9999 »

this is from colorful mut... but it breaks some hud elements like relics, special beacons, (hudmutators) whats wrong in da code that crash down da hudmuts?

Code: Select all

class Tracker expands TournamentPickup;

simulated function PostBeginPlay()
{
	if ( Level.NetMode == NM_DedicatedServer )
		return;
	
	CheckHudMutators();
	Super.PostBeginPlay();
}

simulated function Timer()
{
	CheckHudMutators();
	Super.Timer();
}

simulated final function CheckHudMutators()
{ 
local color M;
local mutator sM;
local PlayerPawn P;
local Actor A;

	ForEach AllActors(class'PlayerPawn', P)
	{
		if ( P.myHUD != None )
		{

			M = color(P.myHud.HUDMutator);
			while ( M != None )
			{
				if ( M.IsA('color') )
				{
					return;
				}
				
			}
			M = Spawn(class'color',P);
			M.RegisterHudMutator();
			
		}
	}
	if ( Role == ROLE_SimulatedProxy )
		SetTimer(1.0, true);
}
(BC) (Scripts)
MrLoathsome
Inhuman
Posts: 958
Joined: Wed Mar 31, 2010 9:02 pm
Personal rank: I am quite rank.
Location: MrLoathsome fell out of the world!

Re: HUD Break

Post by MrLoathsome »

Code: Select all

         M = Spawn(class'color',P);
         M.RegisterHudMutator();
Those 2 lines look a bit off. Don't think an actor of class'color' will register as a hud mutator....
blarg
Higor
Godlike
Posts: 1866
Joined: Sun Mar 04, 2012 6:47 pm

Re: HUD Break

Post by Higor »

How did you get that to compile?

'Color' is a struct defined in the 'Object' class, rename your mutator.
In order to do so, export the package as .uc and then recompile it with "ucc.exe -make" after adding your package into the 'EditPackages=' lines in your UnrealTournament.ini

PD:
Have you tried setting bAlwaysRelevant=True, RemoteRole=ROLE_SimulatedProxy (in your mutator), then waiting for clients to automatically receive it with a PostNetBeginPlay() (must be a 'simulated' function) call?
That would avoid constantly creating an Inventory actor that consumes extra bandwidth everytime a client respawns and would save the client from an AllActors() iteration every second.
Also, if some other mod breaks the mutator chain, then have a timer run every second (simulated function as well) from the PostNetBeginPlay() event, you use to PostNetBeginPlay() event to locate the local player ( (PlayerPawn.Player != none) && (PlayerPawn.Player.IsA('ViewPort') ), store it, so you don't search every second.

Edit:
One more thing, calling RegisterHUDMutator might create an endless chain, instead of calling it on the timer, simply run a check through the local player's hud mutator chain

Code: Select all

local bool bResetHud;

bResetHud = true;
For ( H=LocalPlayer.myHud.HUDMutator ; H!=none ; H=H.nextHUDMutator )
{
    if ( H==self ) //Assuming this function is called from the mutator itself clientside
    {
          bResetHud=false;
          break;
    }
}

if ( bResetHud )
{
    nextHudMutator = LocalPlayer.myHud.HUDMutator;
    LocalPlayer.myHud.HUDMutator = self;
    bHudMutator = true;
}
This one seems like a safer Hud registration method that takes other programmer's blunders into account, besides, it's safe to be call it multiple times.

Edit 2: If the mutator isn't sent to client if you use my method, then subclass 'Actor' directly (bAlwaysRelevant=True, RemoteRole=ROLE_SimulatedProxy , bHidden=True) and make the server version of the mutator add it (NetMode != NM_Client).
That actor will be replicated, then you can use that one to spawn the Hud mutator once.

Edit 3: If you want to keep your method, then instead of running AllActors, simply do this:

Code: Select all

if ( (PlayerPawn(Owner) != none) && (PlayerPawn(Owner).Console != none)  )
 LocalPlayer = PlayerPawn(Owner);

Edit 4:
Lol, again.
Make sure that when your mutator runs PostRender( canvas), to call PostRender( canvas) on the nextHUDMutator if it exists, because that would otherwise break the HUD mutator render chain.
If you want your graphics to display on top, place the nextHudMutator.PostRender( canvas) at the beginning of your PostRender call.
User avatar
Nephew9999
Adept
Posts: 288
Joined: Wed Jul 06, 2011 11:20 am

Re: HUD Break

Post by Nephew9999 »

MrLoathsome wrote:

Code: Select all

         M = Spawn(class'color',P);
         M.RegisterHudMutator();
Those 2 lines look a bit off. Don't think an actor of class'color' will register as a hud mutator....
yea i know sounds weird but its!! xP and works fine the hudchain blocks hudmuts.. i think thats the only prob... here ya go!

higor thanks! for your help im trying now with postrender canvas..
Attachments
colorfulut.u
(569.52 KiB) Downloaded 133 times
User avatar
Nephew9999
Adept
Posts: 288
Joined: Wed Jul 06, 2011 11:20 am

Re: HUD Break

Post by Nephew9999 »

Fixed!! thanks for your help ;) close da topic plz!
User avatar
Shadow
Masterful
Posts: 743
Joined: Tue Jan 29, 2008 12:00 am
Personal rank: Mad Carpenter
Location: Germany
Contact:

Re: HUD Break

Post by Shadow »

Oh and I advise you to use the pawn list to search for the playerpawn and not the slow iterator functions..
Image
Higor
Godlike
Posts: 1866
Joined: Sun Mar 04, 2012 6:47 pm

Re: HUD Break

Post by Higor »

The pawn list is most likely broken during NM_Client sessions.
User avatar
Feralidragon
Godlike
Posts: 5493
Joined: Wed Feb 27, 2008 6:24 pm
Personal rank: Work In Progress
Location: Liandri

Re: HUD Break

Post by Feralidragon »

Higor wrote:The pawn list is most likely broken during NM_Client sessions.
In theory the pawn list is a server-only list (like navigation list and other lists, I say theory since I never tried it in practice on client-side), specially since the server cannot sync the lists due to relevancy rules (a pawn is spawned, added to the list in the server, but since the player may not know about it yet, he cannot add a thing).
Shadow wrote:Oh and I advise you to use the pawn list to search for the playerpawn and not the slow iterator functions..
Indeed, but I must note that although those iterators are "relatively slow", they are not *that* slow at all (I made some heavy tests once, and in terms of "absolute values" they're lightning speed fast). And the more specific you are with the classes you want, the faster it is (at C++ it's fast, it only looses speed at UScript level when it has to return results for every found corresponding actor).
Also, in some situations they may be actually faster than processing UScript based lists with a for cycle like you're sugesting (C++ speed >>>>>>>>> UScript speed, let's not forget about that, UScript runs in a VM as byte code afterall, C++ is compiled to machine code itself), it all depends in the amount of pawns you have in-game and the class you want specifically (if you have 200 scriptedpawns and you want 1 playerpawn, I strongly believe that's faster to find him with a "foreach allactors(class'playerpawn'..." rather than a "for(p=level.pawnlist;p=p.nextpawn...)").
iloveut99
Skilled
Posts: 231
Joined: Mon Aug 16, 2010 10:25 pm

Re: HUD Break

Post by iloveut99 »

I strongly believe that's faster to find him with a "foreach allactors(class'playerpawn'..." rather than a "for(p=level.pawnlist;p=p.nextpawn...)").
That would mean that I was writing bad code, thinking was good...

Any official stats (testing)? I believe you wrote some benchmarks functions which would kill this doubts.
User avatar
Feralidragon
Godlike
Posts: 5493
Joined: Wed Feb 27, 2008 6:24 pm
Personal rank: Work In Progress
Location: Liandri

Re: HUD Break

Post by Feralidragon »

No, no, don't take me wrong. For 80~90% of the things you should indeed use the PawnList, since it's faster in most occasions. However I wanted to point out that is not for 100% of the occasions. For example, for MH or other gametypes that involve massive amounts of scriptedpawns, it's better to use "foreach allactors" to find the playerpawn, for every other situation (normal 24~32 players online game, bot games, small single players), use the PawnList.

I just benchmarked this with a tool I developed to check this kind of stuff out.
The TickBaseTime is the general tick time when the test occurred, and these are the results:

TEST 1: 1 PlayerPawn (the only pawn of the game):

Code: Select all

utest: *******************************************************************************
utest: ******************************* UTEST STARTED *********************************
utest: *******************************************************************************
utest: Starting uTest...
utest: Processing base Tick Delta time...
utest: Base Tick Delta Time = 5.000000ms
ForEach_AllActorsPawn: *******************************************************************************
ForEach_AllActorsPawn: * Executing test: Testing Foreach AllActors(Class'PlayerPawn')
ForEach_AllActorsPawn: * Time taken: 2.370056ms
For_PawnList: *******************************************************************************
For_PawnList: * Executing test: Testing For(PawnList)
For_PawnList: * Time taken: 0.066766ms
utest:  
utest: +------------------------------------+
utest: |   Test Results Table               |
utest: +-----------------------+------------+
utest: | TickBaseTime          | 5.000000ms |
utest: +-----------------------+------------+
utest: | ForEach_AllActorsPawn | 2.370056ms |
utest: +-----------------------+------------+
utest: | For_PawnList          | 0.066766ms |
utest: +-----------------------+------------+
utest:  
utest:  Total testing time: 2.573027 seconds
utest: *******************************************************************************
utest: ******************************* UTEST FINISHED ********************************
utest: *******************************************************************************
TEST 2: 1 PlayerPawn + 100 pupaes (101 Pawns total)

Code: Select all

utest: *******************************************************************************
utest: ******************************* UTEST STARTED *********************************
utest: *******************************************************************************
utest: Starting uTest...
utest: Processing base Tick Delta time...
utest: Base Tick Delta Time = 15.848287ms
ForEach_AllActorsPawn: *******************************************************************************
ForEach_AllActorsPawn: * Executing test: Testing Foreach AllActors(Class'PlayerPawn')
ForEach_AllActorsPawn: * Time taken: 2.220253ms
For_PawnList: *******************************************************************************
For_PawnList: * Executing test: Testing For(PawnList)
For_PawnList: * Time taken: 7.376379ms
utest:  
utest: +------------------------------------+
utest: |   Test Results Table               |
utest: +-----------------------+------------+
utest: | TickBaseTime          | 15.848287ms |
utest: +-----------------------+------------+
utest: | ForEach_AllActorsPawn | 2.220253ms |
utest: +-----------------------+------------+
utest: | For_PawnList          | 7.376379ms |
utest: +-----------------------+------------+
utest:  
utest:  Total testing time: 3.752778 seconds
utest: *******************************************************************************
utest: ******************************* UTEST FINISHED ********************************
utest: *******************************************************************************

TEST 3: 1 PlayerPawn + 135 pupaes (136 Pawns total)

Code: Select all

utest: *******************************************************************************
utest: ******************************* UTEST STARTED *********************************
utest: *******************************************************************************
utest: Starting uTest...
utest: Processing base Tick Delta time...
utest: Base Tick Delta Time = 24.113358ms
ForEach_AllActorsPawn: *******************************************************************************
ForEach_AllActorsPawn: * Executing test: Testing Foreach AllActors(Class'PlayerPawn')
ForEach_AllActorsPawn: * Time taken: 2.148554ms
For_PawnList: *******************************************************************************
For_PawnList: * Executing test: Testing For(PawnList)
For_PawnList: * Time taken: 10.872305ms
utest:  
utest: +-------------------------------------+
utest: |   Test Results Table                |
utest: +-----------------------+-------------+
utest: | TickBaseTime          | 24.113358ms |
utest: +-----------------------+-------------+
utest: | ForEach_AllActorsPawn | 2.148554ms  |
utest: +-----------------------+-------------+
utest: | For_PawnList          | 10.872305ms |
utest: +-----------------------+-------------+
utest:  
utest:  Total testing time: 4.767188 seconds
utest: *******************************************************************************
utest: ******************************* UTEST FINISHED ********************************
utest: *******************************************************************************

As you can see, in the first test PawnList is clearly the winner, after all it's exactly the first match.
However, as we add more Pawns of a different class, "ForEach AllActors" keeps somewhat around the same value (with some fluctuations, which are normal), while the PawnList gets more and more slower to process, and at around 130 pawns, it gets around 5x slower than an iterator.

In a MH server having over than 100 pawns running is normal, so run ForEach AllActors here, as for other gametypes/servers, use PawnList instead.
This all to say that not everything is black and white, since we're comparing UScript with C++, so at a certain point C++ always wins the race.

The tool I used was this one btw: http://www.unrealadmin.org/forums/showt ... hp?t=30567
The link is down, but I will reupload it if you want.
This benchmarking tool basically works with the tickrate in consideration, and makes 2 levels of several cycles per testing script, takes a central value (average or median, in these I used median since it's more accurate), so the end values are accurate (the more time it runs or the more cycles, the more accurate are the values).
Higor
Godlike
Posts: 1866
Joined: Sun Mar 04, 2012 6:47 pm

Re: HUD Break

Post by Higor »

In short:

Is your mod/function supposed to run clientside?
Use AllActors

Does your mod/intended gametype consist only of Player and Bot pawns?
Use PawnList

Are intended maps supposed to have thousands of actors?
Use PawnList

Else
Use AllActors


====
If you're coding a new gametype.
Use UT SDK and run DynamicActors

EDIT:
Hey Shadow, have you tried adding a c++ iterator function that iterates through the Level's pawnlist?
That would be golden for running checks between thousands of pawns.
User avatar
Shadow
Masterful
Posts: 743
Joined: Tue Jan 29, 2008 12:00 am
Personal rank: Mad Carpenter
Location: Germany
Contact:

Re: HUD Break

Post by Shadow »

Great proposal! Didn't think about that, will add it to the february release :D

love this community^^

// edit: oh I noticed the new iterator functions weren't static.. :ironic2: will move them to sdkActor and make them global
Image
Post Reply