Jump to content
gamecreator

Getting All Accurate Pathfinding Points

Recommended Posts

I'm trying to figure out how to do pathfinding over the network and I'm not having any luck so far.  I found this nice thread and post where you could supposedly get the navmesh points.  I threw together a project using it but my tests weren't too promising.  The problem is that if the character is going fast enough, he'll miss points entirely, kind of acting like it's drunk, making all but the start and end points useless for network prediction/interpolation.  Here's the video:

The red markers represent all the points that FindPath returns (10 points + beginning and end).  Note that I'm only using GoToPoint once.  I have a feeling that FindPath only works for the default speed (and perhaps acceleration).  Here's the code:

#include "Leadwerks.h"

using namespace Leadwerks;

Entity* player = NULL;
Entity* navpointbox[100];

int main(int argc, const char *argv[])
{
	int j=0;

	Leadwerks::Window* window = Leadwerks::Window::Create("Navmesh Point Test", 0, 0, 1280, 720);
	Context* context = Context::Create(window);
	World* world = World::Create();

	Camera* camera = Camera::Create();
	camera->SetRotation(65, 0, 0);
	camera->Move(0, -2, -12);

	Light* light = DirectionalLight::Create();
	light->SetRotation(35, 35, 0);

	Map::Load("Maps/map.map");
	NavMesh* navMesh = world->navmesh;

	//Enable navmesh debugging
//	camera->SetDebugNavigationMode(true);

	//  Start: -15.0, -2
	//  End: 9, 7

	//Create a character
	player = Pivot::Create();
	Entity* visiblecapsule = Model::Cylinder(16, player);
	visiblecapsule->SetScale(1, 2, 1);
	visiblecapsule->SetPosition(0, 1, 0);
	player->SetPosition(-15, 0, 2);
	player->SetMass(1);
	player->SetPhysicsMode(Entity::CharacterPhysics);

	while(true)
	{
		if(window->Closed() || window->KeyDown(Key::Escape)) return false;

		if(window->KeyHit(Key::Space))
		{
			player->GoToPoint(9, 0, 7, 10.0, 5);
//			player->GoToPoint(9, 0, 7, 5.0, 5);

			NavPath* path = new NavPath();
			vector<Vec3> pathpoints;
			path->navmesh = navMesh;
			path->navmesh->FindPath(player->GetPosition(true), Vec3(9, 0, 7), pathpoints);

			for(std::vector<Vec3>::iterator it = pathpoints.begin(); it != pathpoints.end(); ++it)
			{
				std::cout << "Point: " << it->x << ", " << it->z << endl;
				navpointbox[j] = Model::Box();
				navpointbox[j]->SetColor(1.0, 0.0, 0.0);
				navpointbox[j]->SetScale(0.3, 1.0, 0.3);
				navpointbox[j]->SetPosition(it->x, 0.5, it->z);
				j++;
			}
		}

		Leadwerks::Time::Update();
		world->Update();
		world->Render();

		context->Sync();
	}
	return 0;
}

So, is there a way to get ALL the ACTUAL points the character will walk through (not just markers it might miss anyway)?  Meaning, if a host lags for a second, I want the client to know exactly where the character should be at any given time.

If this can't be done for Leadwerks 4, maybe we could have a FindPathPoint in Leadwerks 5 that returns a Vec3 at a given time.  I understand that a character could be pushed out of the way or whatever too so it won't be 100% reliable.

Share this post


Link to post

The above code doesn't seem to be networked and that seems to be the issue you're having right? So you have other code for that? In that code do you keep calling GoToPoint() in a loop? I seem to recall, and this is a long time ago so if I'm wrong I'm sorry, you shouldn't be calling GoToPoint() in a loop. Instead call it once, then check if you're at the next point and once you hit it, call GoToPoint() again, then same thing. 

Share this post


Link to post

I was just theorizing about how to make sure that a pathfinding character on a host ends up correctly in the same position for a client.  Actual network code would come later.

And yes, I call GoToPoint only once (when I hit the spacebar).  Ignore that it's possible to hit space multiple times in that code.

Share this post


Link to post

Why not let the server control all movement so there is no discrepency to resolve?

Share this post


Link to post
8 hours ago, gamecreator said:

I was just theorizing about how to make sure that a pathfinding character on a host ends up correctly in the same position for a client.  Actual network code would come later.

And yes, I call GoToPoint only once (when I hit the spacebar).  Ignore that it's possible to hit space multiple times in that code.

To me it sounds like you're talking about 2 issues really. The first one being GoToPoint() with high speeds isn't doing what you think it should be doing. It clearly has some kind of smoothing curve movement which means it can overshoot the points by a lot causing some issues. Then you're worried the client will do the same. Network movement code can be a pain to work with honestly and it all depends on your game style. 

Share this post


Link to post
6 hours ago, JMichaelK said:

Why not let the server control all movement so there is no discrepency to resolve?

Well yes, that's the plan.  But I'm trying to figure out how the client would have the proper position for the character, since you can't just use GoToPoint() on the client (I think).  The ideal way to do it would be for the host to not need to send anything to the client, once it sent the client the start and end points of the navigation (with timestamps).  The client should then be able to calculate where the character needs to be at any given time.

1 hour ago, Rick said:

To me it sounds like you're talking about 2 issues really. The first one being GoToPoint() with high speeds isn't doing what you think it should be doing.

Yes.  I was debating whether to include that but it demonstrated well that the controller might not even be where we expect.  Probably should have been a separate discussion.

Share this post


Link to post

"Ideal" is sort of misleading. Easy would be more the word. Leaving it up to the client creates lots of cheating possibilities. This again depends on the game as well. If it's a slower paced game you can run the movement on the server and have it send position information to the clients and just smoothly move the clients based on the server positions. A turn based or RTS could do something like this. There is latency from the command from client to server then getting information back but often these kinds of games can mask that in various ways. In some games the character will do a little animation acknowledging the command like "Yes, sir" with a little solute, then start moving. That time is meant to mask the delay of this communication. If you're doing an RPG of sorts you can get away with having the client do all the movement and just send the positions to the server and have the server validate certain things like are they moving to fast (speed hack), did they move through walls, etc. If you're doing a fast paced shooter than that's the hardest networked movement to get right and there are many topics online about that.

Share this post


Link to post

Right.  The host would still be authoritative and could check that the client didn't cheat.  But that's down the line.  Right now I'm just trying to get to step 1: making sure the client is where the host was.

Share this post


Link to post

Maybe you have to call GoToPoint() from pathPoint to pathPoint ?

I can imagine this would limit the "drunk" effect, maybe check the distance from player to the next path point and reduce the moving speed if coming near to it.

Share this post


Link to post

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...