Closed GoogleCodeExporter closed 8 years ago
I've added a link from the main page. It's listed as part of the description,
because the project links section (on the right side) is starting to look messy.
Thanks for making it, and let me know if you need more information on some of
the options.
Original comment by faithful...@gmail.com
on 14 Oct 2010 at 12:00
Hi faithful;
I'm wondering if you can send me a sample state file that has skill information
for the other three homunculus types. I'd like to implement them. I'll be
adding the delay on load information sometime soon (Issue 42) as well as
switching around some of the other options to reflect your most recent
update(s).
Original comment by landstei...@gmail.com
on 23 Nov 2010 at 7:19
Also, it'd be neat to implement Kiting options within the GUI. I'll dig around
your code to figure out how you want KiteDistance, KiteMode, and
KitePriorityModifier written in the state file.
I assume that I can write the state file out in any order I want assuming I
write the list initialization element first ({}), if so I think I'll be
outputting the state file alphabetically for ease of use in future releases of
the GUI.
One more area of clarification I'd like has to do with defend options. What do
they do?
ex.:
rail_state["DefendOptions"]["FriendThreshold"] = 4
rail_state["DefendOptions"]["OwnerThreshold"] = 1
rail_state["DefendOptions"]["SelfThreshold"] = 5
A few people have asked me what they're for, and I've told them to not change
them unless they knew what they did.
Original comment by landstei...@gmail.com
on 23 Nov 2010 at 9:10
After writing the table initialization {}, it doesn't matter what order options
are in. So alphabetical is fine, and RAIL will rewrite its state-file when it
loads anyway. When your GUI updates the state-file, I hope it will also set the
following option to cause RAIL to update its configuration on the fly:
rail_state["update"] = true
That will allow users to change configuration without restarting the AI, and I
often use this when testing various values on new options.
I'll explain KiteDistance, KiteMode, and KitePriorityModifier in issue 47,
since they are new options. The defend options are more difficult to explain.
Basically, they define the number of monsters attacking an actor that are
needed before prioritizing that actor's defense. If none of the thresholds are
reached, the AI will defend against the highest priority monster that's
attacking any of: owner, self, friends. Once a threshold is reached, only the
monsters that are attacking that actor (owner,self,friends) will be chosen
among. If multiple thresholds are reached, RAIL will determine which actor has
more attackers and select that one.
I think an example is needed. For the following examples, assume that there is
one friend (although it works with more as well). Also assume that all
thresholds have been set to 2.
When 1 monster is attacking each of Owner, Self, Friend: RAIL will have 3
monsters to choose from.
When 2 monsters are attacking Owner, but Self and Friend only have one: RAIL
will only select from the 2 monsters attacking owner.
When 2 monsters are attacking Owner and Self, but only 1 is attacking Friend:
RAIL will select from the 4 monsters attacking Owner and Self, but not include
the one attacking Friend
When 2 monsters are attacking Owner, Self, and Friend: RAIL will select from
any of the 6 monsters.
When 3 monsters are attacking Owner, 2 are attacking self, and 1 is attacking
Friend: RAIL will only select from the 3 that attack Owner.
Now if the options are as defined in the defaults: Owner = 1, Self = 5, Friend
= 4
With 1 monster attacking each of Owner, Friend, Self: Only the one attacking
owner will be selected.
With 4 monsters attacking each of Owner, Friend, Self: RAIL will select from
the 4 that are attacking the friend.
With 5 monsters attacking the Owner and 4 attacking Friend and Self: RAIL will
only select from the 4 attacking Friend.
With 5 monsters attacking Self and Friend, 1 attacking Owner: RAIL will only
select from the 5 attacking Self.
For now, the code can be found in TargetBasic.lua on lines 216-243. It's ugly
and generates plenty of new tables needlessly, but it's there. When I get some
inspiration, I do plan on rewriting it to also allow for thresholds based on
the sums or averages of attacker priority levels. But it'll be some time before
I get to that.
Skills are divided into several groups. The whole list of skill types is:
AreaOfEffect - Skills that do area damage; eg, Merc's Bowling Bash and Arrow
Shower
Attack - Skills that do single-target damage; eg, Filir's Moonlight, Vanil's
Caprice
Buff - Untargeted buffs; eg, Filir's Flitting, Lif's Mental Change
Debuff - Targeted debuffs; eg, Merc's Decrease AGI
Defense - I will probably merge Defense skills into Buff skills, and set custom
Condition functions for them. As of now, they're unimplemented anyway.
Emergency - Skills that will prevent all other action when used; Right now this
only includes the Merc's Scapegoat (which kills the merc and gives remaining
merc HP to the owner).
HealOwner - Skills that heal the owner; eg, Vanil's Chaotic Blessings, Lif's
Healing Hands
HealSelf - Skills that heal the AI; eg, Vanil's Chaotic Blessings
PartyBuff - Targeted buff skills. These are unimplemented and I'll probably
rename the type of skill to PartySupport or similar. This will include
Mercenary's Sacrifice
Provoke - This only refers to Merc's provoke, since it can count both as a
offensive debuff and (according to iRO Wiki; I've yet to test this) it can be
cast against friendly units as well. If this is the case, I will implement code
to cast against Owner when it seems beneficial. Otherwise, I'll merge it into
Debuff.
Pushback - Skills that knock monsters away; eg, Merc's Arrow Repel, Skid Trap
Recover - Merc skills that recover certain status effects. I'm unsure if I'll
ever implement AI for these due to the mercenary being unable to determine if
any status effects are active.
Reveal - Currently, this is only the level 2 bowman mercenary's Sight skill.
All skills have the following options:
Enabled - true/false of whether the skill should be automatically used by RAIL.
Name - the way in which RAIL will refer to the skill in the log.
Condition - Lua function that will be evaluated before deciding upon a skill.
This is a hidden option and should only be used by advanced users. I'll
document it more thoroughly later...
ReservedSP - the amount of SP that RAIL should not go below when using the
specified skill.
ReservedSPisPercent - true if the above amount is a percentage, false if it's
an actual value.
In addition to the above, all offensive skills (Attack, Debuff, Provoke,
Reveal) include some additional options:
PriorityOffset - Since these skills are targeted they take their base priority
from the monster they'd be cast against and then offset it with the number in
PriorityOffset. In this way, the highest priority skill will be used against
the highest priority target.
MaxFailures - The number of failures to count before RAIL stops trying to use
the skill. This number is per-target, so it should probably be lower than the
default of 10.
Buff skills also have the previous 2 options, but base their priority on the
value specified in rail_state["SkillOptions"]["BuffBasePriority"].
Other skill types have not been implemented yet, and I'll get back to you on
those options.
I hope that helps. Let me know if anything isn't clear.
Original comment by faithful...@gmail.com
on 24 Nov 2010 at 4:09
Brilliant! Thanks for the clarification. I'll be implementing changes to the
GUI per your suggestions here.
I don't know enough about Mercenary mechanics, so I think I'll touch on those
later. From a GUI standpoint, it should be easy, but I do like including a
mouse-over tool-tip for particularly confusing options.
Original comment by landstei...@gmail.com
on 24 Nov 2010 at 8:24
[deleted comment]
Hi faithful,
I happened upon your post
http://forums.irowiki.org/showpost.php?p=765524&postcount=19 here, suggesting
that another possible way to write the state file out in tables, and I became
intrigued. The closest pythonic representation to the state file you're writing
is a dictionary, but currently the GUI reads the state file in line by line as
an array, which is incredibly inefficient when it comes across a newer tag that
you've implemented that the GUI doesn't recognize.
The current implementation of the GUI, when it encounters a line it doesn't
recognize, is to append it to a list of unknown lines and then simply re-add
the same lines at write time. I figured that this would be the best solution at
the time, specifically since I didn't want to overwrite any work done by hand
of the user.
Handling unknown state file options became more and more cumbersome as the GUI
became more sophisticated in how it handled certain types of options.
Where am I going with this? Well, I'm contemplating moving away from an array
based implementation and over to dictionaries. This will eventually allow for
several things, including real-time error checking of values (instead of
write-time checking like is currently implemented), reduction in file write
sizes (I'll get to this later), and built-in support for unknown state file
options.
Re: your post in iRO, I know RAIL will rewrite a state file to the line by line
fashion to which we're all accustomed, so smaller file write sizes are pretty
negligible.
What I need to know is will RAIL parse this file correctly (I cannot test this
currently)?
Original comment by landstei...@gmail.com
on 2 Dec 2010 at 10:41
Attachments:
Almost. If you write quotes on either side of the key names, then you'll have
to also write brackets. In fact, RAIL just parses the state-file like any other
lua file, but protects the call so that errors in the file (or lack of a file
entirely) will not give the user an error.
So you can write
rail_state = { option_name = "option_value", opt2 = 2, }
or
rail_state = { ["option_name"] = "option_value", ["opt2"] = 2, }
Note that you do not have to worry about a trailing , inside the table brackets
{}. With RAIL's serialization, I use ["option"] in the case that an option
value contains a reserved word (function, end, local, etc) or contains spaces.
Further, I use the line-by-line expanded mode because it is the least
error-prone for serializing potential cyclic tables.
For example, imagine that rail_state["ActorOptions"]["ByType"][1] is equal to
rail_state["ActorOptions"]. The state file would have had been sabotaged, but
RAIL would still be able to both read and write that. There is no way to
reference another element of a table before the definition of the table is
completed with }. The only other options would be to "remember" which values
are cyclic and rebuild them later, or to just do it line-by-line. I opted for
line-by-line because it is cleaner.
Note that in Lua tables, specifying the number for a key-value pair inside the
table definition must also use square-brackets. It is invalid Lua to write:
a = { 15 = "value" }
Where the correct way would be
a = { [15] = "value" }
but note that there are cases where the index is a string that contains a
number. The following would probably have undefined behavior:
a = { ["15"] = "string", [15] = "number" }
That's probably more than you wanted to know, but I hope that it helps with
your GUI using dictionaries instead of arrays.
Original comment by faithful...@gmail.com
on 2 Dec 2010 at 11:22
Actually, no-- this is perfect. I think I'll just write a recursive function to
parse out the embedded dictionaries to convert them to LUA once again.
Thanks for the formatting heads up, take a look at the file and see if there
are any formatting irregularities I need to hammer out before I gut the GUI and
write a good chunk over again.
Original comment by landstei...@gmail.com
on 3 Dec 2010 at 4:48
Attachments:
As much as I can just look at it, it seems fine. I don't think it does anything
wrong as far as Lua syntax is concerned.
Are you able to keep up with the state-file changes I'm making in RAIL? I know
that I've let the Wiki information slip a bit...
Original comment by faithful...@gmail.com
on 5 Dec 2010 at 12:29
Yes and no. I'm currently bogged with the switch over to dictionaries, which
requires a great deal of code for initializing values and changing values, but
very light in terms of lines of code used in writing the changes to a file.
Last night I was able to finish the read to internal dictionary subroutine and
I'm currently finishing up with the ability to load ActorByTypes by click.
Still, it makes the GUI completely unusable at the moment since I have not
implemented any of the value changes in the code, but... step by step.
I get pings on the issues I've interest in and I periodically read your
revision notes. My GUI releases correspond with your revision numbers, so to
match the latest revision I'll have to implement the changes to the tag names
(/pif) and add the new options, but it isn't hard... it just takes time. After
I finish with the dictionary revision, I'll be publishing under r185_4, and
then I'll work on changes up to r196.
Most of the changes you're making to the state-file are pretty self
explanatory, but I love this kind of thing. The Wiki will have to be updated
sooner or later, as I point individuals to that file as a reference for how
their state file should be changed without a GUI.
Original comment by landstei...@gmail.com
on 5 Dec 2010 at 11:47
I'm currently in the process of switching over to a windowing based error
system as part of the sync/validation subroutine, which is now about 1/2 done.
Tomorrow I'll write the 'write' functionality back in and the guts will be
fully updated by then.
I added a new table under rail_state called GUI, which should give you a heads
up about which GUI people are using as well as GUI version to help troubleshoot
end-user configuration errors. In it I've fields ["Name"],["Version"] and
["URL"]. It'd be nice if future GUIs would use these, too.
Original comment by landstei...@gmail.com
on 6 Dec 2010 at 5:01
I'm about to upload a new windows binary containing all of my latest changes;
this should implement up to r185 (well, sort of, newer skill options still need
to be addressed...) but more importantly all of the internal gut work has been
successfully written (*crosses fingers*). It turns out the file was written
correctly, which was a huge sigh of relief.
Error checking is now dynamic at both write time and tab time; the GUI will not
allow you to switch tabs if you've entered an erroneous value, and
alternatively will specify a reasonable (often times the default) value if you
delete the erroneous value.
Original comment by landstei...@gmail.com
on 8 Dec 2010 at 11:57
Original issue reported on code.google.com by
landstei...@gmail.com
on 13 Oct 2010 at 10:52