Spawning Inventory items with navigation

Discussions about Coding and Scripting
1337GameDev
Skilled
Posts: 196
Joined: Thu Apr 16, 2020 3:23 pm
Personal rank: GameDev

Spawning Inventory items with navigation

Post by 1337GameDev » Sun Nov 07, 2021 6:03 am

I currently am working on a game mode with bots, where inventory items are spawned at runtime. I want to modify AI behavior to value my inventory items higher and path to them.

I know 'BotDesireability' can be used, and currently I return 4.0 as my desirability value.

The bots will occasionally pik items up, but routinely will walk away from them to do other things.

I know that Navigation is baked into maps, but im also curious if there's a way to encourage / shim my inventory items to be considered for pathing at runtime.

What is the proper method to do this and have bots path for my items?

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

Re: Spawning Inventory items with navigation

Post by sektor2111 » Sun Nov 07, 2021 6:30 am

Creating ReachSpecs is required here and plain UT frankly cannot do that - ask EPIC why not... and why certain constants are not exactly constants at C++ Level.
I did run-time paths (and corrections) using XC_Engine v21-v24, so far this is the only way to do that or... using some Botz mutator requiring paths-file aiming certain map.

Without Creating Paths (defining ReachSpecs) to said InventorySpot markers, bot will only pick them up when is getting closer, they are not a "long range" goal because there is no route mapped pointing at their place.

U227 has capability to do paths in Editor or Run-Time based on user options not always automated by C++ scripts, even deleting a ReachSpec and here is required a full remap of remaining ReachSpecs as long as these will have Index data decreased with 1 for each deleted ReachSpec.
Note: Here I did not do more testing for figuring if Garbage Collector from UE1 is not having a glitch at changing map, after previously removing some paths... either way it will be needed removing all references to navigation actors from this ReachSpec and then deleting it empty without references.

Methods strategy:
- Spawning a Non-Static Navigation Actor child of InventorySpot;
- linking it with desired Inventory;
- Probing some movement options coming from, or going to nearby PathNodes;
- capturing movement data into a few variables which are part of a future ReachSpec;
- creating ReachSpec;
- adding ReachSpec in Paths List (if List is not full) for Source Node and upStreamPaths list for Target Node;
- adding new spawned Navigation Actor in NavigationPointlist - requires a compilation capable to deal with so called "constants" - reworking Navigation chain in UScript using a plain stock compilation it's not possible (code won't compile) - Epic decided to mess up these things.

Higor
Godlike
Posts: 1835
Joined: Sun Mar 04, 2012 6:47 pm

Re: Spawning Inventory items with navigation

Post by Higor » Sun Nov 07, 2021 2:15 pm

I made v469's garbage collector clean up references from ReachSpecs too.
ImageImage
Image unreal://23.111.157.138:7777
Image unreal://46.228.199.205:7788

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

Re: Spawning Inventory items with navigation

Post by sektor2111 » Sun Nov 07, 2021 7:16 pm

Hmmm... which means that XC_PathsWorker might be better to remove first all references before purging ReachSpecs in front of a new paths build. Already deleted InventorySpot actors are going incremental 0 to 102 in next build means the newer ones will go to 103-205, I believe this happens due to this "history" still referenced somewhere...

1337GameDev
Skilled
Posts: 196
Joined: Thu Apr 16, 2020 3:23 pm
Personal rank: GameDev

Re: Spawning Inventory items with navigation

Post by 1337GameDev » Sun Nov 07, 2021 9:44 pm

So there's NO way to get bots to consider these when pathing because pathing is handled via c++ / at map rebuild time?

This is sad... I wish there was some way to just "enable" this in v469 and just make it how it is now in 436 clients/servers..... But knowing past experiences, any deviation in behavior frim 436 -> 469 is forbidden.....

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

Re: Spawning Inventory items with navigation

Post by sektor2111 » Mon Nov 08, 2021 6:42 pm

It's doable as Server-Side as long as client is not involved in processing these assets, A.I. behavior is dictated exclusively by server. Stock 436 client can join to a server running a map having paths done in run-time... Things concerning server-side only should not affect plain client, but such a "mod" won't run in a plain UT game/server because it crashes due to "unknown token" stuff.
Here is a sample in how game is crashing when is trying to execute an unknown function.
CrashSample.PNG
You do not have the required permissions to view the files attached to this post.

1337GameDev
Skilled
Posts: 196
Joined: Thu Apr 16, 2020 3:23 pm
Personal rank: GameDev

Re: Spawning Inventory items with navigation

Post by 1337GameDev » Tue Nov 09, 2021 4:48 am

I would definitely check "role == authority" or for a dedicated server before running the function to update the AI pathing info.

Do you have an example of how this is done?

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

Re: Spawning Inventory items with navigation

Post by sektor2111 » Tue Nov 09, 2021 4:48 pm

I have patch files aiming server as a sort of ServerActors (dynamically loaded by a parent mutator) with classes having usually RemoteRole = ROLE_None - server-side. Functions are not simulated here and so client won't have anything screwed up. This is how NavAdder works in "Monster Gaming Server" hosted at NfoServers, even maps supposed without Bot Support are working normally - all maps there have Bot Support native or partially/completely patched in run-time.
This way is based on "XC_Engine.u" file and "XC_Engine_UT99.u" file embedded in XC_Engine distribution and sample codes and a few solutions are also inspired from GunLoc mutator by Higor. All these are supporting original client connected to a XC_Engine based server.

NavAdder and plugins are here https://hofgamingclan.com/forums/viewto ... f=29&t=161.

1337GameDev
Skilled
Posts: 196
Joined: Thu Apr 16, 2020 3:23 pm
Personal rank: GameDev

Re: Spawning Inventory items with navigation

Post by 1337GameDev » Wed Nov 10, 2021 10:48 pm

sektor2111 wrote:
Tue Nov 09, 2021 4:48 pm
I have patch files aiming server as a sort of ServerActors (dynamically loaded by a parent mutator) with classes having usually RemoteRole = ROLE_None - server-side. Functions are not simulated here and so client won't have anything screwed up. This is how NavAdder works in "Monster Gaming Server" hosted at NfoServers, even maps supposed without Bot Support are working normally - all maps there have Bot Support native or partially/completely patched in run-time.
This way is based on "XC_Engine.u" file and "XC_Engine_UT99.u" file embedded in XC_Engine distribution and sample codes and a few solutions are also inspired from GunLoc mutator by Higor. All these are supporting original client connected to a XC_Engine based server.

NavAdder and plugins are here https://hofgamingclan.com/forums/viewto ... f=29&t=161.
So their's no way to do this via stock v469b ut99? I have to use XC engine?

I don't mind if I need to make a native function or etc, I just want this to be easy for users to consume if they want to use / host my gametype.

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

Re: Spawning Inventory items with navigation

Post by sektor2111 » Thu Nov 11, 2021 11:19 pm

Original UT, like I said, doesn't have open access for user to do Paths/ReachSpecs using UScript connected with internal C++ Natives, only server-side extensions written in other programming language can do such stunts.

In plain UT you can deactivate a path, read a bit of data, probably a re-link of Navigation chain and... that's all.

1337GameDev
Skilled
Posts: 196
Joined: Thu Apr 16, 2020 3:23 pm
Personal rank: GameDev

Re: Spawning Inventory items with navigation

Post by 1337GameDev » Sat Nov 13, 2021 7:12 am

" re-link of Navigation chain"

What does this mean? Couldn't I manually link a navigating node at my inventory item to the navigation chain?

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

Re: Spawning Inventory items with navigation

Post by sektor2111 » Sat Nov 13, 2021 8:38 am

When a navigation node aka navigation actor is brought to the map using Mouse in Editor or Spawn function during run-time, this point has ZERO relations with current navigation points which are part of a linked list done by DevPath during Paths building process. As result, this new Navigation Point is not referenced anywhere in navigation calculus. New point needs a few new ReachSpecs and to get connected in chain - this main linked list. A sort of sample about building this linked list if it doesn't exist I rewrote in XC_PathsWorker.

Code: Select all

	if ( TheMap.NavigationPointList == None )
	{
		Log ("Navigation Chain Not Found, Creating Navigation Chain.",'UScriptDevPath');
		foreach TheMap.AllActors(class'NavigationPoint',N)
		{
			it++;
			ScrUpdate++;
			if ( ScrUpdate > 20 )
			{
				ScrUpdate = 0;
				Redraw();
				Log("Iterations count :"@it$".",'UScriptDevPath');
			}
			if ( LiftCenter(N) != None && ( LiftCenter(N).LiftTag == '' || string(LiftCenter(N).LiftTag) ~= "None" ) )
			{
				log ("Trash point"@N.Name@"won't go into Navigation chain as it doesn't have a valid LiftTag defined.",'UScriptDevPath');
				continue;
			}
			if ( TheMap.NavigationPointList == None ) //First will go into chain 
			{
				NNav++;
				TheMap.NavigationPointList = N;
				NOld = N;
				NOld.nextNavigationPoint = None; //Remove any possible point...
			}
			else
			{
				NNav++;
				NOld.nextNavigationPoint = N;
				N.nextNavigationPoint = None;
				NOld = N;
			}
		}
		NOld = None;
		N = None;
		Log("Linked"@NNav@"NavigationPoint actors as Navigation chain. Processed cycles :"@it$".",'LinkedNavigationList');
	}
And here is (for me it was...) a problem: "nextNavigationPoint" wrong called "variable" is a "constant" at UScript Level - not for C++ internals. As response to UScript, code won't compile with plain "ucc.exe" (umake) until you have to adjust these variables - screwing Stock assets more exactly - and this is the stage where an advanced modder/coder will use another tweaked copy of his UT install and not the same copy used for playing in public servers. Coding in UT will require some fine tuning or else mods written there are low level ones facing all sort of restrictions. For movers is the same story, you can alter them in the way you need but code won't compile in plain stock even if such a code is not damaging anything.

In other hand, a new point can be linked into chain using nearby nodes as references if navigation chain it's already build - another sample from MapGarbage.

Code: Select all

	foreach MyMap.AllActors( class'NavigationPoint',N ) //Walk through Actors not through chain - node is not in chain yet
	{
		if ( N.bSelected )
		{
			if ( !bSelection )
				bSelection = True;
			if ( !IsInChain(N) ) //if this node is not a linked one
			{
				if ( LinkThisNode(N) ); //if possible having nearby chained nodes
					NumNodes++;
			}
			else
			{
				log (N.Name@"is already into NavigationChain... refrain from guessing...",'AlreadyLinked');
			}
		}
	}
...
final function bool IsInChain(NavigationPoint N)
{
	local NavigationPoint Point;
	local bool bChained;

	bChained = False; //As first measure is False by any matter
	for ( Point = MyMap.NavigationPointlist; Point != None; Point = Point.nextNavigationPoint ) //Try find Node in chain
	{
		if ( Point == N )
		{
			bChained = True;
			break;
		}
	}
	return bChained;
}
...
final function bool LinkThisNode(NavigationPoint N)
{
	local NavigationPoint APoint, Connector;
	local int BestDist;

	if ( N == None )
	{
		log (Self.Name@"LinkCurrentNode :: NavigationPoint :: None",'UnExpectedError');
		return False;
	}

	BestDist = 1600;
	foreach N.RadiusActors( class 'NavigationPoint', APoint, 1600, N.Location ) //Scan points in 1600 UU radius - it should be enough for pathing
	{
		if ( Apoint == N )
			continue;
		if ( APoint.nextNavigationPoint != None && VSize( APoint.Location - N.Location ) < BestDist ) //if found something linked and closer as possible
		{
			BestDist = int(VSize( APoint.Location - N.Location ));
			Connector = APoint;
		}
	}
	if ( Connector == None ) //No closer nodes = linking is denied
		return False;
	else
	{
		log (N.Name@"looks closer to"@Connector.Name$", trying insertion here.",'CloserFound');
		if ( Connector.nextNavigationPoint != None ) //Deal with the closest one - insert new comer
		{
			N.nextNavigationPoint = Connector.nextNavigationPoint;
			Connector.nextNavigationPoint = N;
			log ("nextNavigationPoint for"@N.Name@"is"@N.nextNavigationPoint.Name,'NextAdded');
			log ("and the closer point"@Connector.Name@"will have nextNavigationPoint"@Connector.nextNavigationPoint.Name$".",'CloserChanged');
			return True;
		}
		else
		{
			log (N.Name@"could not be linked...",'NoValidCloserPoint'); //Can be another new comer or last in chain - requires iterations for checks = Nah !
			return False;
		}
	}
	return False;
}
Solutions can be more or less improved but Engine doesn't include only flaws based on incomplete codes but also no logic for these limitations, it's not like users cannot create a linked list in end.