Giter VIP home page Giter VIP logo

Comments (7)

chrisschwartzdev avatar chrisschwartzdev commented on July 28, 2024 1

@roy-t Thanks for replying! It's cool, I can totally understand that you haven't had much time. I was just wondering is all :) There are some interesting points in your conclusions.

Since you asked: in my application, the grids would be mostly static. I've been working on a 2D top-down MMORPG game (in Unity) where the players can move freely, but NPCs and monsters use path-finding to move around randomly (within a limited distance of their spawn point) and follow players to attack them. For my grid data, I'm exporting collide-able tiles for the server to read and use for path-finding and player movement verification. Since the tiles are being exported from Unity, the general use for the path-finding is that the grid will be static. The only instance that I could see them not being static is if I decide to add some randomized dungeons (which is something I'd love to do at some point).

If it helps any further, my plan is to have the game world be a relatively large size. The world itself is already split up into regions, for the purpose of the interest areas for players and which entities they should receive updates for. It'd likely be too much for the server to generate paths within a giant grid of about 1280x1280, so perhaps I would have one grid per 40x40 region.

Sorry if that was a bit much to read. Thanks for your time and I appreciate the help!

from astar.

chrisschwartzdev avatar chrisschwartzdev commented on July 28, 2024

Hey! I've been searching around for simple AStar libraries and have decided to go forward with using this one for now. It looks very promising, but multi-threading support would make this a lot more appealing. I was just wondering how far along multi-threading support is, or if there's any rough timeline. Thanks, I appreciate it!

from astar.

roy-t avatar roy-t commented on July 28, 2024

Hey @BassaForte,

Unfortunately there has been no progress. I'm switching jobs and doing some work on the side so I haven't had much time.

But I've thought about it a fair bit. So far my conclusions:

  • Doing an individual path search multi-threaded is nearly impossible with A*. So far all my attempts have made it slower instead of faster, even for very long paths.
  • The way to go would be to create a wrapper in which you can queue path queries which will be executed on the thread pool. But there are some gotcha's:
    • What if someone modifies the grid after a path query was queued, what if someone modifies it during the computation of the path (that would lead to bad things). Probably best to only guarantee that the path was valid/shortest for the moment you queued the query.
    • How to do the callbacks when a query is done? Putting the results in a ConcurrentQueue? Callbacks? Events? Observables? I have not yet figured out which approach is the best for the usage scenarios.

Can I ask, what are you using this library for? It will give me a better idea on who to tailor the implementation to.

Depending on your feedback and the time I have the coming days I might create a PR request with minimal prototype for you to test. No promises :).

from astar.

bradzoob avatar bradzoob commented on July 28, 2024

This is a fabulous lib, thanks! have been using it for a while.

Yeah it's not deterministic so won't work in parallel for a single job as far as i'm aware (i'm not educated to know otherwise, but intuitively it's a brute force operation and as such needs to be domain aware, hence parallelism is traditionally off the cards, but maybe Compute handles these things with magic now?), BUT you can use an interpolation of broad graph values for long path determination, breaking each chunks cell entry/exit path finder into it's own thread/process and manage it via a queue, while not perfect this is pretty much the only solution I know of / could come up with for large graphs (which is virtually ALL graphs in 2018 lol). You could then set multiple LOD scales of your graphs depending on the range required (i only need 2).

I already multithread queue this lib for navigating entry/exit points in chunks, but obviously not calculating all cells multithreaded but just dispatching each in-chunk path request to a thread as needed (when path within a chunk is required), hence can only use about 64x64 cells for minimal frame impact as this lib is computationally heavy compared to straight 2d unweighted A*, although it may be my poor understanding of .NET/Unity that is leading to the speed issues, benchmarks provided in earlier versions of this lib i couldn't even get close to (5x the computational cost), I did have to hack Unity to use 4.6.NET though, so it could be that, now it's native so maybe I should revisit the benchmarking and maybe start using the proper parallel jobs architecture :)

In any case you'd still need to use chunk / cell navigation on anything over 512x512 (mine is 16384x16384xN heights, if you want to maintain realtime tick and can't afford units to be idle while waiting for a single gigantic path array.

I'd love it if you implemented a Multi-threaded architecture with path completion callbacks that provide the ID of the request so that the calling method can map it back to the original action as I'm certain it would be far better than mine. I'm still trying to figure out this beast known as the GC and what it truly wants. :P

Happily using this lib to drive river pathing on terrain. There's obviously some issues with the range available for the broad check, as I'm limited to 64x64 cells at any scale, which leads to angular paths that don't look natural, but I've been tricking it with various simplex "bubbles" to wind the paths a bit, but every now and again i come back here to see if any performance breakthroughs have been made so i can wrench just a little bit more performance out which would allow me to increase that cell range and get more natural winding of rivers as they descend into the sea :)

rivos

from astar.

roy-t avatar roy-t commented on July 28, 2024

Hey brradzoob,

Thanks for your praise :D

sorry to hear that your running into speed issues. I gave this somethought and I think the more you change the weights the more the worse the A* prediction is, thus the worse runtime you have. Try to have most cells weighted at 1.0 for the best performance.

Btw what do you mean by this library not being deterministic? There is no randomness involved so you should get exactly the same path every time.

Btw 16384 is gigantic :D, I never thought the library would be used for such large maps. Maybe in your case you're better of with a graph based A* algorithm. Use it on pre-computed entry and exit paths for chunks. Then only use grid based search inside chunks.

Btw for generating rivers check out the blog and Twitter of Amit Patel: https://twitter.com/redblobgames

from astar.

bradzoob avatar bradzoob commented on July 28, 2024

Sorry my bad, i went into an optimization frenzy straight after this post, and i gained a lot of performance with pathing, basically lopped 70% execution time off (editor attachment/unity2018.2/IL2CPP). It's still not great but it's at least buying tickets to the ball park of great :)

Oh, i've read heaps of his older stuff back in the day on various gamedev things, one of my fav reads was: http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/

But i see he's doing fresh new things!

hah, i was going to mention I'm intending to shift your A-Star to AI duties where i can queue/thread and it's not time sensitive but for pre-compute game init phase i'll use a DAG (+some winding trickery), and that's what Amet was illustrating in this very article I first read many years ago. This is a bizarre twist of fate, i've returned home to understand the lessons of former masters :P Thanks!

from astar.

bradzoob avatar bradzoob commented on July 28, 2024

Deterministic: I mean it's iterative, you can't run the search in parallel per query because the results feed back into the subsequent query, so a path point isn't known until it's discovered, so not really appropriate for GPU calculations which is about brute parallelism except where you need to run thousands of them over very small domains, as I've seen done with compute shaders, but presumably you'd be unable to do the same over a larger domain because as the domain grows the usefulness of parallelism provided by the GPU is lost.

Yeah 16384 seems large, but I wasn't happy with games like Rimworld using 400x tiles as a benchmark for "huge", which i understand to be about the reasonable extent a fast A* can be frequently run before exponentially losing performance, so 16384 seemed a nice number to challenge :) 16384 isn't really even that large though. I was going to make it unlimited but wanted to keep the initial scope finite while figuring out how to do river pathing for performance over large areas, then figure out how to cordon off parts of the map for pre-rendering, because river chunks need to be connected you can't pre-determine them over infinite distance etc. Might use some sort of broad cellular network for this in the future, so that rivers exist in determined geometric regions and when first discovered will generate the node network required within that region.

from astar.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.