itemhunterdummy / ro-rail

Automatically exported from code.google.com/p/ro-rail
0 stars 0 forks source link

pyRAIL GUI #41

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
I whipped together a RAIL GUI because the one listed has no download; I'll make 
a windows installer later.

http://code.google.com/p/pyrail/

If you would be so kind, link it from your main page and I'll update my project 
as you update yours.

Original issue reported on code.google.com by landstei...@gmail.com on 13 Oct 2010 at 10:52

GoogleCodeExporter commented 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

GoogleCodeExporter commented 8 years ago
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

GoogleCodeExporter commented 8 years ago
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

GoogleCodeExporter commented 8 years ago
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

GoogleCodeExporter commented 8 years ago
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

GoogleCodeExporter commented 8 years ago
[deleted comment]
GoogleCodeExporter commented 8 years ago
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:

GoogleCodeExporter commented 8 years ago
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

GoogleCodeExporter commented 8 years ago
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:

GoogleCodeExporter commented 8 years ago
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

GoogleCodeExporter commented 8 years ago
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

GoogleCodeExporter commented 8 years ago
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

GoogleCodeExporter commented 8 years ago
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