0

I'm trying to model and RTS game (AOE2) for an optimal build order and plan using OPTIC. My thought is to represent villagers (workers) as a function, then resources increase depending on the number of villagers. This action works, but I believe is inefficient and the plans are not optimal:

(:durative-action collect_resource
    :parameters (?r - resource) ;wood, food etc.
    :duration (= ?duration 10)
    :condition (and
      (at start (> (workers ?r) 0))
      (at start (idle ?r))
      )
    :effect (and
      (at start (not (idle ?r)))
      (at start (working ?r))
      (at end (idle ?r))
      (at end (not (working ?r)))
    (at end (increase (amount ?r) (* (collect_rate ?r)(workers ?r))))
    )
  )

I tried this PDDL Durative-Action: Flexible duration, but OPTIC doesn't support non-linear numeric conditions:

(increase (amount ?r) (* (#t)(* (collect_rate ?r)(workers ?r)))

Does anyone have any suggestions for a better approach?

EDIT (error message):

Unfortunately, the planner does not supported non-linear numeric conditions,
effects, or duration constraints, but one or more of these is present in
the problem you have provided.  Specifically, the sub-expression:

        (3*(workers lumber1)) * (#t)

... was encountered.  To use this planner with your problem, you will have
to reformulate it to avoid these.

Domain:

(define (domain aoe2)
  (:requirements :strips :typing :fluents :durative-actions :timed-initial-literals)

  (:types
    location society - object
    resource building - location
    town_center barracks - building
    lumber berries sheep gold - resource
  )

  (:predicates
    (working ?l - location)
    (idle ?l - location)
  )

  (:functions
    (idle_villagers ?s - society)
    (train_villager_time ?s - society)

    (workers ?r - resource)
    (walk_time ?r - resource)
    (collect_rate ?r - resource)
    (amount ?r - resource)

  )

  (:durative-action train_villager
    :parameters (?tc - town_center ?s - society)
    :duration (= ?duration (train_villager_time ?s))
    :condition (and
      (at start (idle ?tc))
    )
    :effect (and
      (at start (not (idle ?tc)))
      (at start (working ?tc))
      (at end (idle ?tc))
      (at end (not (working ?tc)))
      (at end (increase (idle_villagers ?s) 1))
    )
  )

  (:durative-action send_idle_to_resource
    :parameters (?r - resource ?s - society)
    :duration (= ?duration (walk_time ?r))
    :condition (and
      (at start (> (idle_villagers ?s) 0))
    )
    :effect (and
      (at start (decrease (idle_villagers ?s) 1))
      (at end (increase (workers ?r) 1))
    )
  )

  (:action send_resource_to_idle
    :parameters (?r - resource ?s - society)
    :precondition (and
      (> (workers ?r) 0)
    )
    :effect (and
      (increase (idle_villagers ?s) 1)
      (decrease (workers ?r) 1)
    )
  )

  (:durative-action collect_resource
    :parameters (?r - resource)
    :duration (= ?duration 10)
    :condition (and
      (at start (> (workers ?r) 0))
      (at start (idle ?r))
      )
    :effect (and
      (at start (not (idle ?r)))
      (at start (working ?r))
      (at end (idle ?r))
      (at end (not (working ?r)))
    (at end (increase (amount ?r) (* (collect_rate ?r)(workers ?r))))
    )
  )
)

Problem

(define (problem dark_age)
    (:domain aoe2)
    (:requirements :strips :typing :fluents :durative-actions :timed-initial-literals)

    (:objects
        tc1 - town_center
        mysociety - society
        lumber1 - lumber
        sheep1 - sheep
    )

    (:init
        (= (train_villager_time mysociety) 25)
        (= (idle_villagers mysociety) 0)
        (idle tc1)

        (= (workers lumber1) 0)
        (= (walk_time lumber1) 5)
        (= (collect_rate lumber1) 3)
        (= (amount lumber1) 0)
        (idle lumber1)

        (= (workers sheep1) 5)
        (= (walk_time sheep1) 0)
        (= (collect_rate sheep1) 3)
        (= (amount sheep1) 0)
        (idle sheep1)
    )

    (:goal
        (and
            ; (= (idle_villagers mysociety) 1)
            ; (> (workers lumber1) 1)
            (> (amount lumber1) 600)
            (> (amount sheep1) 600)
        )
    )
)
HRIGUY
  • 33
  • 5
  • Quick questions: shouldn't your action have `over all` conditions instead of `at start` and `at end`? *Maybe* what you have would work in context, but it seems wrong. Also, if `collect_rate` is constant on a per-resource basis, can't you make the increase a linear rate of $kw$ (workers times constant rate) instead? You might have to multiply out the number of actions to 1/resource rate, but I think that would work. – Robert P. Goldman Jul 10 '21 at 19:48
  • You're right about the `over all`, thanks for that. Unfortunately, workers*constant_rate is still non-linear because the number of workers changes – HRIGUY Jul 13 '21 at 16:07
  • you mean the number of workers changes over the course of the durative action? If the only way that this can happen is by sending idle to resource or sending resource to idle, and we replace the collect rates with constants, the rate of change should be *piecewise* linear, so I don't see why OPTIC would refuse to handle that. It would be nice if there were a Docker image for it, to lower the bar on testing it out. – Robert P. Goldman Jul 13 '21 at 23:17
  • I agree with you, I edited the question with the non-linear error. I pushed an image (here)[https://hub.docker.com/r/jdekarske/aoe2test] for you to try out – HRIGUY Jul 14 '21 at 17:20
  • Do you have an example `docker run` command that we can use for the test? – Robert P. Goldman Jul 15 '21 at 00:34
  • Try `docker run -it -rm jdekarske/aoe2test:latest bash` then to run the planner `./optic-clp/optic-clp domain_temporal.pddl problem_temporal.pddl`. You can edit the domain and problem inside using vi or your favorite editor or mounting a volume. – HRIGUY Jul 16 '21 at 13:17
  • Running your example, I see a message that the increments to lumber and sheep levels are order-dependent. But that isn't an error, is it? I see a short number of diagnostics and then it appears that the job is killed (timeout?). So I don't believe that the domain is rejected, it looks more like OPTIC simply can't solve it before its timeout. – Robert P. Goldman Jul 19 '21 at 13:37
  • Thanks for helping out so far. The previous domain was the working one (albeit slow). If you `docker pull jdekarske/aoe2test:latest` and run, I've added `problem_temporal_easier.pddl` which doesn't timeout. I've also added `domain_temporal_nonlinear.pddl` which will display the nonlinear error. – HRIGUY Jul 19 '21 at 17:23
  • I think at this point you are better off contacting the OPTIC developers. This looks like an OPTIC issue, rather than a PDDL issue. – Robert P. Goldman Jul 19 '21 at 19:28

0 Answers0