caesuric/mountain-goap

Extreme Goal Sequence Issues

Closed this issue · 2 comments

I noticed this when trying out extreme goals, and was able to quickly reproduce by modifying the ExtremeHappinessIncrementer.cs example. It appears as though actions whose postconditions are non-arithmetic will always satisfy an ExtremeGoal's MeetsGoal, which leads to infinite looping if any actions are non-arithmetic.

In my case, I need to create a sequence leading to an arithmetic action, where normal postconditions are necessary to plan for the arithmetic action's preconditions.

Below is a minimal modification where I make "Seek Greater Happiness" have a dummy postcondition, and it is chosen continuously over the arithmetic action.

        internal static void Run() {
            _ = new DefaultLogger();
            Agent agent = new(
                name: "Happiness Agent",
                state: new() {
                    { "happiness", 0 },
                },
                goals: new() {
                    new ExtremeGoal(
                        name: "Maximize Happiness",
                        desiredState: new() {
                            { "happiness", true }
                        })
                },
                actions: new() {
                    new(
                        name: "Seek Happiness",
                        executor: SeekHappinessAction,
                        arithmeticPostconditions: new() {
                            {
                                "happiness",
                                1
                            }
                        }
                    ),
                    new(
                        name: "Seek Greater Happiness",
                        executor: SeekGreaterHappinessAction,
                        postconditions: new()
                        {
                            { "anything", true }
                        }
                    ),
                }
            );
            while (agent.State["happiness"] is int happiness && happiness != 10) {
                agent.Step();
                Console.WriteLine($"NEW HAPPINESS IS {agent.State["happiness"]}");
            }
        }

And i've tracked the execution to this (seemingly incorrect) evaluation of MeetsGoal. I am wondering if it is because this method only checks isLowerThan / isHigherThan when it should be isLowerThanOrEqualTo since no arithmetic difference means no progress towards the extreme goal is made.

            // ActionAStar.cs (line 47)
            while (frontier.Count > 0) {
                var current = frontier.Dequeue();
                // this is always true for non-arithmetic postconditions
                if (MeetsGoal(current, start)) { 
                    FinalPoint = current;
                    break;
                }
                foreach (var next in graph.Neighbors(current)) {
                    float newCost = CostSoFar[current] + next.Cost(current.State);
                    if (newCost > costMaximum) continue;
                    if (!CostSoFar.ContainsKey(next) || newCost < CostSoFar[next]) {
                        CostSoFar[next] = newCost;
                        float priority = newCost + Heuristic(next, goal, current);
                        frontier.Enqueue(next, priority);
                        CameFrom[next] = current;
                        Agent.TriggerOnEvaluatedActionNode(next, CameFrom);
                    }
                }
            }

Though I might just be missing something

Thank you for your PR, which appears to fix this. I'll close this since it appears to be fixed. Feel free to reopen if the issue comes up again.

This fix is in 0.11.4.