1 |
[q]Ideally I could improve caretaker behavior with a widget that is accepted as default on by the devs. Is there a checklist/guidelines what that would entail?[/q]
|
1 |
[q]Ideally I could improve caretaker behavior with a widget that is accepted as default on by the devs. Is there a checklist/guidelines what that would entail?[/q]
|
2 |
The general requirements for a default widget (or UI/AI gadget) are as follows:
|
2 |
The general requirements for a default widget (or UI/AI gadget) are as follows:
|
3 |
* Do not hinder or make the UI worse for players that are unaware of the widget.
|
3 |
* Do not hinder or make the UI worse for players that are unaware of the widget.
|
4 |
* Pay attention to the performance cost in relation to the benefit.
|
4 |
* Pay attention to the performance cost in relation to the benefit.
|
5 |
* Write a gadget instead of a widget if gadget-space allows for a cleaner solution, or perhaps to remove the decision entirely.
|
5 |
* Write a gadget instead of a widget if gadget-space allows for a cleaner solution, or perhaps to remove the decision entirely.
|
6 |
\n
|
6 |
\n
|
7 |
The UI is often made worse through clutter or when units appear to act against what the player thought they told their units to do. Note that this is based on what the player thinks, not what actually happens, so even a widget that implements good behaviour can be bad if players often get the feeling of fighting against it. This can be a challenging requirement because, taken to the extreme, you would essentially have to read the players mind. If someone puts a Caretaker down on the frontline, and gives it no orders, did they intend for it to repair damaged units or reclaim? The UI has to guess.
|
7 |
The UI is often made worse through clutter or when units appear to act against what the player thought they told their units to do. Note that this is based on what the player thinks, not what actually happens, so even a widget that implements good behaviour can be bad if players often get the feeling of fighting against it. This can be a challenging requirement because, taken to the extreme, you would essentially have to read the players mind. If someone puts a Caretaker down on the frontline, and gives it no orders, did they intend for it to repair damaged units or reclaim? The UI has to guess.
|
8 |
\n
|
8 |
\n
|
9 |
Here are three good ways to avoid making the UI worse:
|
9 |
Here are three good ways to avoid making the UI worse:
|
10 |
* Don't override direct orders from the player. If the player orders a Caretaker to reclaim while their storage is full then trust that they did it for a reason. Even if they simply did not notice their metal bar, it is probably better to let them issue the order and move on rather than have the unit appear to fight against the order.
|
10 |
* Don't override direct orders from the player. If the player orders a Caretaker to reclaim while their storage is full then trust that they did it for a reason. Even if they simply did not notice their metal bar, it is probably better to let them issue the order and move on rather than have the unit appear to fight against the order.
|
11 |
* If implementing an active behaviour (such as Attack Move skirmishing) then keep it as simple as possible. This allows the player to learn what to expect when they issue the command. Teaching the player what to expect when they issue a command is basically as good as mind reading.
|
11 |
* If implementing an active behaviour (such as Attack Move skirmishing) then keep it as simple as possible. This allows the player to learn what to expect when they issue the command. Teaching the player what to expect when they issue a command is basically as good as mind reading.
|
12 |
* Limit the AI to only handle the dumbest and most common cases. I think players are fairly happy for unit AI to step in and stop unambiguously stupid automated behaviour, but when the UI tries to be smarter it risks fighting the player. For example, automatic reclaim at full storage is obviously bad in a way that reclaiming at 80% storage is not. Being a bit stupid in the edge cases, in the pursuit of reliability, is fine.
|
12 |
* Limit the AI to only handle the dumbest and most common cases. I think players are fairly happy for unit AI to step in and stop unambiguously stupid automated behaviour, but when the UI tries to be smarter it risks fighting the player. For example, automatic reclaim at full storage is obviously bad in a way that reclaiming at 80% storage is not. Being a bit stupid in the edge cases, in the pursuit of reliability, is fine.
|
13 |
\n
|
13 |
\n
|
14 |
Performance is obviously important, and it depends on what the widget does. Even a widget with a small performance impact may be no good if I can't find any evidence of the problem it solves ever coming up in real game. In my experience Spring.Get{Thing}In{Volume} can quickly result in very poor performance so I am wary of widgets that use it frequently. In gadget-space I'm wary of anything that reads or handles projectiles. The current smart nanos widget gets units within a volume so I would need to test its frequency. Also, don't use the iterators pairs or ipairs (I made a file called IterableMap to replace them if you want).
|
14 |
Performance is obviously important, and it depends on what the widget does. Even a widget with a small performance impact may be no good if I can't find any evidence of the problem it solves ever coming up in real game. In my experience Spring.Get{Thing}In{Volume} can quickly result in very poor performance so I am wary of widgets that use it frequently. In gadget-space I'm wary of anything that reads or handles projectiles. The current smart nanos widget gets units within a volume so I would need to test its frequency. Also, don't use the iterators pairs or ipairs (I made a file called IterableMap to replace them if you want).
|
15 |
\n
|
15 |
\n
|
16 |
Writing a gadget instead is often a solution to one or both of the first two issues. Gadgets,
|
16 |
Writing a gadget instead is often a solution to one or both of the first two issues. Gadgets,
|
17 |
* are latency-free,
|
17 |
* are latency-free,
|
18 |
* have access to the entire gamestate,
|
18 |
* have access to the entire gamestate,
|
19 |
* allow for cleaner implementations of unit states, and
|
19 |
* allow for cleaner implementations of unit states, and
|
20 |
* have many more callins and hooks into the engine.
|
20 |
* have many more callins and hooks into the engine.
|
21 |
The downsides are that they can be a bit harder to open up to player configuration, and their performance impact is felt for all players. Sometimes the possibility of a bit of unit AI reveals that the mechanic that necessitates the AI should not exist in the first place. In this case "writing a gadget" would be changing the game such that the widget can't exist. For example, imagine if cloak disabled when you have less than 100 energy. Someone could write a widget to manage the economy such that you don't drop below 100 energy. At this point the mechanic is rendered pointless so may have been removed in the first place.
|
21 |
The downsides are that they can be a bit harder to open up to player configuration, and their performance impact is felt for all players. Sometimes the possibility of a bit of unit AI reveals that the mechanic that necessitates the AI should not exist in the first place. In this case "writing a gadget" would be changing the game such that the widget can't exist. For example, imagine if cloak disabled when you have less than 100 energy. Someone could write a widget to manage the economy such that you don't drop below 100 energy. At this point the mechanic is rendered pointless so may have been removed in the first place.
|
22 |
\n
|
22 |
\n
|
23 |
To give some examples, the Kodachi AI widget was not included because its effectiveness was highly dependent on latency and it fought the player for control of the set target command. Similarly, the Artemis AI is vulnerable to latency and fights the player for control of firestates. Moreover, when I last checked, it uses massive Spring.GetUnitsInCylinder and similar, much cheaper, functionality exists in the target priority, overkill prevention, and "Don't fire at radar" gadgets.
|
23 |
To give some examples, the Kodachi AI widget was not included because its effectiveness was highly dependent on latency and it fought the player for control of the set target command. Similarly, the Artemis AI is vulnerable to latency and fights the player for control of firestates. Moreover, when I last checked, it uses massive Spring.GetUnitsInCylinder and similar, much cheaper, functionality exists in the target priority, overkill prevention, and "Don't fire at radar" gadgets.
|
24 |
\n
|
24 |
\n
|
25 |
Caretaker
AI
as
a
widget
sounds
fine
if
you
are
smart
about
it.
It
should
probably
be
merged
into
the
widget
that
gives
Caretakers
patrol
commands
when
they
are
idle,
since
it
is
the
only
other
widget
that
handles
Caretakers.
The
widget
is
implementing
an
idle
behaviour
so
to
start
with
I
would
focus
on
the
simplest,
dumbest,
behaviors.
More
can
be
added
if
further
issues
arise.
I
would
target
these
two
cases:
|
25 |
Caretaker
AI
as
a
widget
sounds
fine
if
you
are
smart
about
it.
It
should
probably
be
added
to
"Auto
Patrol
Nanos"
since
this
is
the
only
widget
that
handles
Caretakers.
The
proposed
widget
is
implementing
an
idle
behaviour
so
to
start
with
I
would
focus
on
the
simplest,
dumbest,
behaviors.
More
can
be
added
if
further
issues
arise.
I
would
target
these
two
cases:
|
26 |
* Don't reclaim automatically if metal storage is full.
|
26 |
* Don't reclaim automatically if metal storage is full.
|
27 |
* Don't build automatically if your storage is empty, provided there is something to reclaim or repair nearby.
|
27 |
* Don't build automatically if your storage is empty, provided there is something to reclaim or repair nearby.
|
28 |
Note that "Don't build automatically" is potentially too much automation, since I expect that many players manage their build priority partially via overbuilding Caretakers near their factory. As long as it is limited to cases where Caretakers could do something else then it is probably fine.
|
28 |
Note that "Don't build automatically" is potentially too much automation, since I expect that many players manage their build priority partially via overbuilding Caretakers near their factory. As long as it is limited to cases where Caretakers could do something else then it is probably fine.
|
29 |
\n
|
29 |
\n
|
30 |
I
would
try
using
area
commands
to
avoid
all
the
target
selection
issues.
here
is
an
approach.
|
30 |
I
would
try
using
area
commands
to
avoid
all
the
target
selection
issues.
Here
is
an
approach:
|
31 |
*
If
you
are
out
of
metal,
intermittently
insert
large
area-reclaim
and
repairinly
area-repair
commands
at
the
start
of
the
queue.
Insert
reclaim
before
repair,
and
stagger
the
Caretaker
updates
over
multiple
seconds
to
make
them
naturally
balance
their
reclaim.
Skip
inserting
repair
if
you
are
also
low
on
energy.
|
31 |
*
If
you
are
out
of
metal,
intermittently
insert
large
area-reclaim
and
repair-only
area-repair
commands
at
the
start
of
the
queue.
Insert
reclaim
before
repair,
and
stagger
the
Caretaker
updates
over
multiple
seconds
to
make
them
naturally
balance
their
reclaim.
Skip
inserting
repair
if
you
are
also
low
on
energy.
|
32 |
* If your metal storage is full, replace the Caretaker patrol command with area-repair. This update could be checked faster as balancing is less useful.
|
32 |
* If your metal storage is full, replace the Caretaker patrol command with area-repair. This update could be checked faster as balancing is less useful.
|
33 |
\n
|
33 |
\n
|
34 |
When using the area commands there are two things to consider:
|
34 |
When using the area commands there are two things to consider:
|
35 |
* If a Caretaker is already doing an appropriate command when one of the above conditions is triggered, then modify its command queue in such a way to not interrupt its current command.
|
35 |
* If a Caretaker is already doing an appropriate command when one of the above conditions is triggered, then modify its command queue in such a way to not interrupt its current command.
|
36 |
* Make the radius of the command extremely large (if this doesn't cause bugs) because drawing circles everywhere is ugly.
|
36 |
* Make the radius of the command extremely large (if this doesn't cause bugs) because drawing circles everywhere is ugly.
|