Penalties. How? Docs missing, doesn't work as expected

  1. The angle-penalty for terrain graphs seems odd. Increasing the factor above 100 has no effect, and at 100 it is too subtle. I couldn’t find docs to explain what the 100 is. I’m guessing it’s a percent, since increasing it has literally zero effect.

So I tried manually creating the correct penalties based on slope. Easy enough, only 30 lines of code for an arbitrary Terrain. But, when I tried to use my (checked by hand!) correct data … the docs on setting penalties are 3 lines of code that only “sort-of” work.

  1. The “how to set penalties” documentation is mostly missing. The example given uses an unexplained magic number. I found that increasing this number by different amounts has RANDOM effects on the data. The number is clearly not just a scalar.

I had best results at scalars of 10,000,000 (10 million!) and at 1,000,000,000 (1 billion!). 100 million? No. Random weird data. 10 thousand? No, identical to 1 thousand (even though it clearly isn’t). 100 thousand? Random weird data coruption in the library.

  1. I found that if you don’t also call “guo.updatePhysics = false;” then the data that is output is mostly wrong, again in seemingly random ways. I read and re-read the docs on that boolean several times, they are still meaningless to me, and I have no idea how/why they affected the output. I’m not even using physics!

  2. What do the Bounds objects mean? What are they defined relative to? Undocumented. I guessed “absolute space” but experimenting suggests this is only “patially” true. Increasing/decreasing them by 0.001f has enormous random effects. Increasing from a bounds of 1f to 2f … seems to disable the calculation completely.

So much randomness, in something that should be precise! And so little docs on what the magic numbers are, what units, what co-ordinate space, etc :(.

  1. With the penalty-dbugger … what’s it doing? I get red and green, but … what defines them? The docs give no info on what a penalty means - what units is it in? What does it do? How does it interact with a graph? etc.

So I also wrote my own Gizmos-based data displays to check the above: I now have much clearer displays of “penalties” than is built-in to this library, which is a shame. But it makes it easy to show that the penalties system in this library doesn’t work how the docs imply (and I have run out of guesses at what’s missing from the docs).

In my experience “editing the penalties” is absoltely critical to using A* in a non-trivial way in game design. I am on the verge of giving up on this library completely, because penalty-management is so intensely difficult, and yet it’s one of the main features of the algrorithm.

NB: on the whole, I think it’s an excellent package. I love the editor integration, and the automatic bits. I would like to buy the commercial version even though I don’t want or need any of the features simply as a “thank you” to the author.

It’s just that a lot of it is unexplained and very frustrating when it stops working, or does the wrong thing (why did it do that? I have no idea, and no way to find out :(. By trial and error I’ve found a lot of controls that SHOULD NOT affect each other, but do ).


Sorry that the documentation is a bit confusing and/or slightly missing in that area.

A penalty is applied on a node in a graph. This means that when a path traverses the node, the penalty is added to the path’s cost. The penalty is essentially unitless, but since it is used with paths which have lengths, and that is easy to compare against I like to state it as: a penalty of 1000 is equivalent to the cost of moving 1 world unit (this magic number is determined by Int3.Precision).

The bounds are defined in world space, all nodes contained inside of it are updated (though in case of grid graphs, some checks on the Y axis are removed for performance as you want to update a rect in the grid graph 99% of the time).
Try to play around a bit with the GraphUpdateScene component, which is basically a simple wrapper for the GraphUpdateObject class. Using it you can easily configure which nodes are going to be updated.

The penalty angle factor is the penalty applied for a 90 degree slope (90 degree slopes won’t exist, but close to 90 degree slopes anyway), half of that would be applied at a 45 degree slope, etc.

The penalty debug mode in the editor has a field below it called “Gradient max (red)”, when it is enabled it will show a green color for nodes with a penalty of 0 and a red color for nodes with a penalty of [value of the gradient max field] and something between red and green for values in between.

I am not sure why you get so seemingly random behaviour from the penalties that you apply, it could be a bug. Does the penalty debug mode (either the built in one or the one you wrote) show what you expect? Screenshots?
Btw, how did you write your penalty debugger? Would be interesting to know so that I could improve the built in one.

I have made some documentation updates to clarify this (won’t be visible until the next update).

Thanks - very useful info!

My penalty debugger was dumb but ended up working better than expected:

  1. Draw a cube on the mesh at every node/edge (depending what you’re applying the penalty to)
  2. Cube size is proportional to weight
  3. Use OnGizmosSelected to only display it when the component with the debugger is selected

This gives a hugely easy-to-read debug view that only appears when you ask for it. To scale the weights I set my weights as ranging [0…1] and then added 1 to this (to represent a default travel cost), and mulitplied by a scalar (the big numbers - thousands or millions) before sending data to AStar component(s).

…advantage of this is that I then alos was able to auto-render those cubes at useful size/scale without much effort: scale their [0…1] by half the distance separating the node on mesh. So a “max” penalty comes out as occupying 100% of the area in this graph of weights, and a “zero” penalty comes out as blank.

Re: penalty units … so, if you don’t apply ANY post-processing weights, the graph created by astar will have put a weight of 1000 on every node?

Tried again from scratch with the above info.

This time, I cannot get any “angel penalty” to have any effect at all on the paths.

Even setting it to 1000’s is ignored: paths go striaght up a 85-degree cliff, ignoring the gentle route adjacent :(.

(PS: I found that the raycast-based scanner was artificially cutting-off routes by failing to make enough points in-between adjacent nodes. This caused some of my problems - I hadn’t realised that the different colors on terrain meant “unreachable sub-areas”. Doubling the grid resolution made things path a lot better)

Looking with debug mode set to “Penalty”, I have never ever seen a color that is not green or red.

Trying with a higher-res graph, the graph is always 100% green, even with angles ranging to almost vertical / 90 degrees. Perhaps this is one of the problems: the angle-penalty code isn’t actually running at the moment? (is something needed other than enabling it?)