Check if an Actor is abstract

Discussions about Coding and Scripting
Buggie
Adept
Posts: 421
Joined: Sat Mar 21, 2020 5:32 am

Re: Check if an Actor is abstract

Post by Buggie » Mon Mar 29, 2021 5:46 pm

Mechanics - no. But some stuff (like ABI in OS) changed in terms of linker.
Native code strictly related on offset and fields/functions order.
So All depends how luck you are. If call stay on same places and placed in same hash basket then link will be fine.
If no - all goes to hell.

I try build native part for my EditorTools (not released yet). And if all fine in v436, on v469 not all good even in 469a. Some calls moved and linker pick another.
Engine and Core not native binary backward compatible.

Because changes not big as they can be, most functions called properly, but it is more happily coincidence rather predefined behavior.

User avatar
Shadow
Masterful
Posts: 725
Joined: Tue Jan 29, 2008 12:00 am
Personal rank: Mad Carpenter
Location: Halle/Leipzig, Germany

Re: Check if an Actor is abstract

Post by Shadow » Tue Mar 30, 2021 11:48 am

Look, its really not a big deal to check this stuff via a native function. I'm currently in deep development under 469a and everything is stable and works fine, which I cant say about 469b tho.
Image

User avatar
Feralidragon
Godlike
Posts: 5300
Joined: Wed Feb 27, 2008 6:24 pm
Personal rank: Work In Progress
Location: Liandri

Re: Check if an Actor is abstract

Post by Feralidragon » Tue Mar 30, 2021 2:20 pm

It kinda is a big deal, because native packages imply that you should compile for all supported platforms, which starting at 469 means all major 3 of them: Windows, Linux and even Mac, to support all types of clients.
Plus, you then also need to think about online support, because these have to be downloaded by the client to actually work, which means to use NPLoader at the very least, and to also have the player to accept to download custom .dll/.so files.

That is, if the native package has a client component of course (for server-side-only packages a native package is 100% fine, and doesn't necessarily need to be compiled to every platform).

Having that said, the release of new public headers and a native SDK is definitely planned, but there's still some work to do that only Anthrax knows about, and there's also some extra stuff to be validated with Epic first (which may take a little while).

I suggest you to head towards the official 469 Discord server, to discuss with them directly about this:
https://discord.gg/bYkXPUZs

(nice to see you back btw :tu: )

Buggie
Adept
Posts: 421
Joined: Sat Mar 21, 2020 5:32 am

Re: Check if an Actor is abstract

Post by Buggie » Tue Mar 30, 2021 3:29 pm

Feralidragon wrote:
Tue Mar 30, 2021 2:20 pm
That is, if the native package has a client component of course (for server-side-only packages a native package is 100% fine, and doesn't necessarily need to be compiled to every platform).
It is most time true, until you not need update server.

For example you are happy with your custom server-only native stuff on v451 Linux server.
And now you want update your server to v469b.
It is meant fully rebuild all your native stuff with new headers (which not released yet :lol2: ).
So this native stuff prevent you upgrade.

User avatar
sektor2111
Godlike
Posts: 5209
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

Re: Check if an Actor is abstract

Post by sektor2111 » Tue Mar 30, 2021 5:22 pm

In Uscript as I can see there is no easier way to detect an abstract than trying to spawn actor. Either way in C++ you might have opened gates to gain these class flags. Perhaps in Editor a builder won't hurt any compatibility if it does only a check and not adding stuff in Level....

Code: Select all

AActor* ULevel::SpawnActor
(
	UClass*			Class,
	FName			InName,
	AActor*			Owner,
	class APawn*	Instigator,
	FVector			Location,
	FRotator		Rotation,
	AActor*			Template,
	UBOOL			bNoCollisionFail,
	UBOOL			bRemoteOwned
)
{
	guard(ULevel::SpawnActor);

	// Make sure this class is spawnable.
	if( !Class )
	{
		debugf( NAME_Warning, TEXT("SpawnActor failed because no class was specified") );
		return NULL;
	}
	if( Class->ClassFlags & CLASS_Abstract ) //How can I see these easily ?
	{
		debugf( NAME_Warning, TEXT("SpawnActor failed because class %s is abstract"), Class->GetName() );
		return NULL;
	}
	else if( !Class->IsChildOf(AActor::StaticClass()) )
	{
		debugf( NAME_Warning, TEXT("SpawnActor failed because %s is not an actor class"), Class->GetName() );
		return NULL;
	}
	else if( !GIsEditor && (Class->GetDefaultActor()->bStatic || Class->GetDefaultActor()->bNoDelete) )
	{
		debugf( NAME_Warning, TEXT("SpawnActor failed because class %s has bStatic or bNoDelete"), Class->GetName() );
		return NULL;		
	}
Which means that Editor can actually spawn all sort of actors as it doesn't have restrictions... It's Editor after all.

User avatar
sektor2111
Godlike
Posts: 5209
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

Re: Check if an Actor is abstract

Post by sektor2111 » Thu Apr 01, 2021 9:47 pm

I've got something for MapGarbage at this chapter. It is concerning STOCK abstracts as posted by Buggie.
We are iterating through factories / Actors

Code: Select all

...
	local int i;
...
		if ( ThingFactory(A) != None )
		{
			for ( i=0; i<66; i++ )
			{
				if ( Instr(string(ThingFactory(A).Prototype),Abstracts[i] ) != -1 )
				{
					log (A.Name@"uses an abstract prototype"@ThingFactory(A).Prototype$", this won't spawn in map's run-time...",'TRASHFactory');
					break;
				}
			}
		}
Abstracts[ i ] is an array hard-coded with 66 types (+ position 0) which are... strings, lol...

Code: Select all

defaultproperties
{
...
...
	Abstracts(0)=Arena
	Abstracts(1)=Bot
	Abstracts(2)=ChallengeVoicePack
	Abstracts(3)=FemaleBotPlus
	Abstracts(4)=HumanBotPlus
	Abstracts(5)=Ladder
	Abstracts(6)=MaleBotPlus
	Abstracts(7)=StationaryPawn
	Abstracts(8)=TFemaleBody
	Abstracts(9)=TMaleBody
	Abstracts(10)=TournamentAmmo
	Abstracts(11)=TournamentConsole
	Abstracts(12)=TournamentFemale
	Abstracts(13)=TournamentHealth
	Abstracts(14)=TournamentMale
	Abstracts(15)=TournamentPlayer
	Abstracts(16)=TournamentWeapon
	Abstracts(17)=UTHumanCarcass
	Abstracts(18)=UT_Decoration
	Abstracts(19)=VoiceFemale
	Abstracts(20)=VoiceMale
	Abstracts(21)=Commandlet
	Abstracts(22)=BrushBuilder
	Abstracts(23)=Actor
	Abstracts(24)=Ammo
	Abstracts(25)=DamageType
	Abstracts(26)=Decoration
	Abstracts(27)=HUD
	Abstracts(28)=Info
	Abstracts(29)=Inventory
	Abstracts(30)=Keypoint
	Abstracts(31)=MessagingSpectator
	Abstracts(32)=Pawn
	Abstracts(33)=Pickup
	Abstracts(34)=Projectile
	Abstracts(35)=ReplicationInfo
	Abstracts(36)=VoicePack
	Abstracts(37)=Weapon
	Abstracts(38)=FractalTexture
	Abstracts(39)=WaterTexture
	Abstracts(40)=CustomBot
	Abstracts(41)=customplayer
	Abstracts(42)=Relic
	Abstracts(43)=UBrowserServerListFactory
	Abstracts(44)=Burned
	Abstracts(45)=Corroded
	Abstracts(46)=Decapitated
	Abstracts(47)=Drowned
	Abstracts(48)=Fell
	Abstracts(49)=UnrealDamageType
	Abstracts(50)=Bots
	Abstracts(51)=DeadMales
	Abstracts(52)=Female
	Abstracts(53)=FemaleBot
	Abstracts(54)=Human
	Abstracts(55)=HumanBot
	Abstracts(56)=HumanCarcass
	Abstracts(57)=Male
	Abstracts(58)=MaleBot
	Abstracts(59)=ScriptedPawn
	Abstracts(60)=ShareSounds
	Abstracts(61)=Skaarj
	Abstracts(62)=UnrealIPlayer
	Abstracts(63)=MeshBrowser
	Abstracts(64)=UTLadder
	Abstracts(65)=UTLadderStub
For another abstracts we can only pray for more mapper intelligence... either way, logging Factories...
Code might be like a doggy slow and causing iterations but it won't create dependencies and then it prevents loading all sort of assets in memory...

If we talk about run-time checks, I think this check would need to be scheduled for second 1 or 2. Me one I have a lot of iterations in PostBeginPlay and the rest, I have already too much charge around first tick... it's why I moved all movers tweaking in a background state code...