Pocket Familiars and fambattle.php

Veracity

Developer
Staff member
I've been through a number of Pokefam ascensions now and have engaged in many hundred of pokebattles in the relay browser. I'm starting to consider what would be the best way to automate them.

My first observation is that simply automating via a CCS is not likely to be useful. You may set up your favorite team, but your opponent's team can throw a wrench into your favorite strategy.

- tackle can send your front row familiar to the back
- ULTIMATE: Atomic Bomb (or what ever it is) can simply take out your back row familiar

And many others.

So, CCS is out, consult script is in. What does a consult script need to know?

For both teams, who is 1st, 2nd, and 3rd
Which powers are available this round to each of your familiars? Some are only available at the front, some only at the rear, and so on.
What is the opponent's next action? Which familiar, which action? That is available to you; it is called out in the HTML.

If your opponent is about to automatically take out your front or rear familiar, perhaps you want to use the soon-to-be dead familiar before they die? Or perhaps you want to disable that attack by tackling the foremost opponent and making the attack no longer valid? Or something. That is completely up to the script to decide; it is not KoLmafia's job to come up with a strategy, unless we want to build in an automated fambattle automation, which I am not proposing.

And the consult script needs a function to actually make such-and-such a familiar perform such-and-such an action.

So:

- Each round of a battle, parse the current fambattle page and set properties to describe the current battle position
- Provide a function to perform a fambattle action.
- What is an action? It's a familiar-specific skill performed by a particular familiar. You can have multiple familiars in your team who can Backstab, for example, so an action is a combination of a familiar + a familiar skill.

Here are some URLs used in fambattle.php:

Code:
				// fambattle.php?pwd&famaction[ult_crazyblast-209]=ULTIMATE%3A+Spiky+Burst
				// fambattle.php?pwd&famaction[sting-98]=Sting
				// fambattle.php?pwd&famaction[backstab-209]=Backstab
As you can see, it gives you the familiar doing the skill, which is specified by keyword and also with full "pretty" name.

You need to specify familiar + skill. How do you want to represent the skill?
By string, presumably, but both "pretty" skill name and "keyword" is needed.
Does anyone have a list of all possible familiar skills?

Those who have written (or would like to write) consult scripts or combat filters, please chime in now about what you would like KoLmafia and ASH to make available to you to simplify/clarify/reliablize you code.

Thanks.
 

Veracity

Developer
Staff member
Additional interesting things:

For all familiars, what are their primary, secondary, and ultimate power?
Put it into familiars.txt. Somewhere.

I notice that have_familiar() seems to work. I assume (somebody) coded up parsing the "manage team" page or something.

Given that - and the fambattle data I mentioned - scripts could choose teams with such-and-such characteristics without having to hardcode familiar data.
 

Veracity

Developer
Staff member
It looks like there is a new argument at the end which is "pokefam" if it is pocket familiars only.
Seems like it could be "pokefam,HP,Bite,Laser Beam,ULTIMATE: Violent Shred", for example, omitting the "pokefam" if it is a regular familiar.

A separate file seems plausible, but way back in the old days, we had both "items.txt" and "itemdescs.txt" (or something), which had to be maintained in parallel. I think not having to have parallel files is better.

And, by the way, in order for combat filters to work, we'd need to add "CCS actions", since that is what a combat filter returns. something like:

pokefam [familiar type], [skill name]

You could certainly put that into a CCS, but, as I mentioned, the opponent team can invalidate it.

Edit: Your proposal of "poke/HP/HP/Pow/Claw/Howl/ViolentShred/Armor" is basically the more complete version of what I suggested above. I like.
 
Last edited:

lostcalpolydude

Developer
Staff member
The "pokefam" value currently there does nothing right now, except let scripts know that the familiar isn't usable outside the path if they care to check. I don't know how much it really needs to do. KoLmafia doesn't even know if one has those familiars outside of the path, since they can only be seen on the Manage Familiar Names page (so snapshot will have to check there now). That just leaves the session when freeing the king after a pokefam run when things could be handled incorrectly.

I remember that my main reason for merging itemdescs.txt and tradeitems.txt was that 75% of the fields were identical between the two. I don't have any real opinion about how this data should be added, since I'm unlikely to add data or use data added there.
 

Veracity

Developer
Staff member
Can you use the item that grows the familiar if you get it outside of the path? Or do you have to obtain it AND use it while on the path?
 

Veracity

Developer
Staff member
Can you use the item that grows the familiar if you get it outside of the path? Or do you have to obtain it AND use it while on the path?
To answer my last question, I bought the cheapest pokefam-only familiar and "grew" it on a test multi. It gave a success message and shows up on the Manage Familiar Names page.

Regarding familiar data, I'm going to start fambattle.txt. I'm considering this:

Code:
# Name of familiar, as in familiars.txt
# L2, L3, and L4 specify what improves at those levels: HP or Pow
# S1 is skill #1
#    list here
# S2 is skill #2
#    list here
# S3 is the ULTIMATE skill
#    list here
# AT is the special attribute
#    none
#    smart (2 XP per battle)
#    armor
#    spiked
#    regen

# Type	L2	L3	L4	S1	S2	S3	AT
I notice that the spreadsheet now has "Power at L5" and "HP at L5". Obviously, if you have the L2, L3, and L4 data, that tells you the same, but
it's not obvious which is easier to collect: if you can see a familiar at L5, you get those numbers, but if you only see lower levels, you may not have that. I'm going to start collecting data for L2, L3, and L4, as you suggested.
 

Darzil

Developer
I'm collecting it on an alt, and adding it to spreadsheet.
You don't usually need all the data points. L1 is always 1 Pow, 2 HP. L4 = L5. So often one other data point (sometimes none) is enough to fill in the gaps.
Main trick on my alt is finding the familiars being used (as he doesn't have many himself, and doesn't have IotM).
 

Veracity

Developer
Staff member
I'm thinking of adding (optional) logging, So, round 0 of a fight, when we see the opponent for the first time:

<*> Oily Woim level 3, 2/3, Bonk, Lick, Unknown, None
...next familiar...
...
...for all six on both teams

<*> lets us select the lines and only the lines of the session log that have pokefam info.
Collect those lines - over however many days - sort them, and remove duplicates, and you have all the info that KoL tells you about the abilities of such and such a familiar at such and such level.

I have seen a ton of familiars which have little or no data in the spreadsheet.
Automated data collection could work really well.

Of course, after day 1, I am running with ML 85+, so am not seeing the L1 or L2 data any more.

Which is to say, everything that KoL showed us about each familiar can be saved and entered into the database.

FightRequest.parseFamBattleHTML skips over all the HTML until it gets past the "his team" and "your team" stuff. Rather than "skipping over" it, it could parse each node that contains a Familiar (enemy or ally) and log what it saw in that format, which will give us the data we want.

Log only round 0 (1?) so we don't see the effects of moves that add power, and so on.

Simple matter of coding! :) Too bad the weekend is essentially over, and I am done coding KoLmafia until next weekend...
 

Veracity

Developer
Staff member
I'm going to do this for fambattle.txt

Code:
Name	1/3	2/3	3/3	Sting	Howl	Violent Shred	Spiky
Name - familiar type, from familiars.txt
1/3 - the power/hp seen at levels 2, 3, (4 or 5), respectively
Sting, Howl - moves #1 and #2
Violent Shred - the ULTIMATE move
Spiky - attribute.

If we have not seen the familiar at levels 2, 3, (4 or 5), x/x
If we have not seen the familiar at level 5, ULTIMATE move is Unknown
If we have not seen the familiar at all, Move #1 and #2 and the attribute are also Unknown

I'll finish filling out this file with the data that is known from the spreadsheet and my own records this evening and will submit it.

Given that, in FightRequest on round 1 of a fambattle - before either side has moved - parse name, level, power, hp, move 1, move 2, [move 3], attribute and register with FamiliarDatabase (which will have read fambattle.txt). If it disagrees with previously known data - either missing or incorrect! - updata database and return a string to be logged to the session log, just as we do for unknown items, etc.

This will let KoLmafia automatically collect unknown fambattle attributes.

And those 7 things - three power/hp pairs, three moves, and attribute - can all be familiar proxy fields.

Now, the above is "unknown data" type logging, which will happen regardless of user settings.

We could also have "pretty" logging of His Team vs. Your Team at the beginning of the battle, for the "who's on a monster's team" data collection you mentioned.
 

Veracity

Developer
Staff member
I committed my current version of fambattle.txt in 18521.

There are a lot of easily spaded things: Pokefam familiar things from somebody who owns that familiar. I am such a person; there are a fair number of intermediate L2/L3 things I did not record that automated logging would have caught.

Next steps:

- Parse this file and make the data available via familiar proxy values
- parse the (first) fambattle page and register fambattle parameters with FamiliarDatabase, which will log to the session log if there is something new (or corrected) from this file
- Log the fambattle familiars in the session log in a "pretty" way for people who want to see what the initial setup is.

(And eventually, we could log the effects of enemy familiar actions (and our familiar actions) to allow tracking the whole battle. If anyone cares. Sort of like Alice's Army...)

Comments and suggestions - and updates - are welcome. I'll get some more myself tomorrow, although manually checking if I have new data is not all that fun...
 

Darzil

Developer
Put some updates in fambattle.txt. I have a low level alt going to various out of the way places with varying ML.
 

Veracity

Developer
Staff member
Revision 18530 adds familiar proxy fields.

Code:
[color=green]> ash $familiar[ Smashmoth ][/color]

Returned: Smashmoth
hatchling => Smashmoth
image => pokefam39.gif
...
attributes => pokefam
poke_level => 0
poke_level_2_power => 1
poke_level_2_hp => 3
poke_level_3_power => 1
poke_level_3_hp => 4
poke_level_4_power => 2
poke_level_4_hp => 4
poke_move_1 => Bonk
poke_move_2 => Swoop
poke_move_3 => Owl Stare
poke_attribute => None
 

Veracity

Developer
Staff member
Regarding walking the HTML of a fambattle, here is the parse tree of a familiar on your foe's team:

Code:
  <table class="">
    <tbody>
      <tr>
        <td rowspan="2">
          <img src="https://s3.amazonaws.com/images.kingdomofloathing.com/itemimages/frankengnome.gif">
        <td class="tiny" width="150">
          Vincentenstein
        <td rowspan="2" width="120">
          <img src="https://s3.amazonaws.com/images.kingdomofloathing.com/itemimages/blacksword.gif">
          <img src="https://s3.amazonaws.com/images.kingdomofloathing.com/itemimages/blacksword.gif">
        <td rowspan="2" align="center" width="60">
        <td rowspan="2" width="150">
          <img src="https://s3.amazonaws.com/images.kingdomofloathing.com/itemimages/blackheart.gif">
          <img src="https://s3.amazonaws.com/images.kingdomofloathing.com/itemimages/blackheart.gif">
          <img src="https://s3.amazonaws.com/images.kingdomofloathing.com/itemimages/blackheart.gif">
          <img src="https://s3.amazonaws.com/images.kingdomofloathing.com/itemimages/blackheart.gif">
      <tr>
        <td class="tiny">
          Lv. 5 Reagnimated Gnome
      <tr>
        <td height="10">
      <tr>
        <td>
        <td colspan="5" class="small" valign="center">
          <b>
            Skills:
          <span title="Deal [power] damage to the frontmost enemy and reduce its power by 1.">
            [Punch]
            
          <span title="Heal the frontmost ally by [power].">
            [Hug]
            
          <span title="Deal 5 damage to the frontmost enemy.">
            [ULTIMATE: Deluxe Impale]
            
And here is one from your team:

Code:
  <table class="">
    <tbody>
      <tr>
        <td rowspan="2">
          <img src="https://s3.amazonaws.com/images.kingdomofloathing.com/itemimages/familiar7.gif">
        <td class="tiny" width="150">
          Boney Grrl
        <td rowspan="2" width="120">
          <img src="https://s3.amazonaws.com/images.kingdomofloathing.com/itemimages/blacksword.gif">
        <td rowspan="2" align="center" width="60">
          <img src="https://s3.amazonaws.com/images.kingdomofloathing.com/itemimages/whiteshield.gif" alt="Armor:  This familiar will take 1 less damage from attacks (minimum of 1)." title="Armor:  This familiar will take 1 less damage from attacks (minimum of 1).">
        <td rowspan="2" width="150">
          <img src="https://s3.amazonaws.com/images.kingdomofloathing.com/itemimages/blackheart.gif">
          <img src="https://s3.amazonaws.com/images.kingdomofloathing.com/itemimages/blackheart.gif">
          <img src="https://s3.amazonaws.com/images.kingdomofloathing.com/itemimages/blackheart.gif">
      <tr>
        <td class="tiny">
          Lv. 2 Spooky Pirate Skeleton
      <tr>
        <td height="10">
      <tr>
        <td>
        <td colspan="5" class="small" valign="center">
          <form style="display: inline" action="fambattle.php" method="post">
            <input type="hidden" name="pwd" value="xxx">
            <input title="Deal [power] damage to the frontmost enemy and reduce its power by 1." class="button skb" type="submit" value="Punch" name="famaction[punch-7]">
             
            <input title="Knock the frontmost enemy to the back." class="button skb" type="submit" value="Tackle" name="famaction[tackle-7]">
             
HTMLCleaner is handy; KoL is known for sloppy HTML, but it regularizes it.

Easy to see how to count the power images, the hp images, the attribute image, where to find the moves, and so on.

But it's probably a big enough project that I'd prefer to wait until the weekend.

I have a function which is called six times (one per table) with the "table" node, when we are parsing the fambattle page. Will I be able to resist continuing to work on it tonight? We'll see. ;)
 

Veracity

Developer
Staff member
Revision 18533 parses the teams on round 1 of a fambattle and extracts everything interesting. Doesn't do anything with it yet. Next up:

1) Pass that data to FamiliarsDatabase to update PokefamData for familiars, as needed. And log a discovery line in the session log and gCLI, much as we do for items.
2) Log something pretty in the session log showing the teams.
3) Parse the Team Management page and pass what we find to FamiliarDatabase to update data if needed.
4) Given that, I can look at my own appropriately leveled familiars to discover all of KoL's "short names" for them. For example, ULTIMATE: Spiky Burst is "ult_crazyblast". We'll need those if we want to provide a function to ask a particular familiar to do a particular move.

I suppose next will be parsing the state of the teams every round and keeping track of everything in settings, so that consult scripts can do something sensible. And then adding CCS actions (which are used in Combat Filters, too) and a function that a consult script can use.
 

Veracity

Developer
Staff member
Revision 18535 will print a line to the gCLI and the session log when previously unknown - or previously incorrect - pokefam data is seen.
 

Veracity

Developer
Staff member
In the final turns of my latest pokefam run, when I was trying to determine all the "short" skill names (as used in URLs for submitting skills for familiars), I wanted to level up one of my L3 familiars whose ULTIMATE skill was Vulgar Display, since I had none at the level. So I spent 5 pokedollars and bought the "add Smart to a familiar" thing.

Next battle, I got a "this familiar is incorrect" update line.

Seems like we might want to track which familiars have been augmented this ascension with which perma-boost. You can only have one per familiar, if I understand. Given that, I'll compensate when parsing familiars.

I wish I'd saved a DEBUG log for applying the potion to the familiar. I'll ascend into another Pokefam run tomorrow, and, by and by, will boost a familiar. It'll be easiest to reproduce once I add code to parse the Team Management page, where it shows you all of your familiars at their current level - Power/HP - but also shows you all of the skills they will have at level 5.

I have a LOT of familiars. I'm only missing 2 of the Pokefam-only familiars, because I spent about 1.5 million before I ascended. 600K of which was for a Slotter, since I really wanted it. I'll buy at least a Cornbeefadon before I ascend this time, since I need the short name for the Pepperscorn move...

(I wonder what Mu has? No way, no how, will I buy it at anywhere close to its current price. Maybe at a tenth of that price.)
 

Magus_Prime

Well-known member
Thank you for your continued efforts. I posted to the New Content thread for the path with some new/updated Pokefam data from encounters.
 

Veracity

Developer
Staff member
Thanks for helping!

Anotother observation: Familiars can have multiple "attributes". They only ever start with one, but you can feed one a potion to add another, and various battle moves can grant an attribute. The column has room to show two attributes without wrapping. (Just as the Power has room to show 4 without wrapping - but if you power up the familiar, the fifth sword will wrap.)

For the purpose of looking at 1st round teams, need to parse all the attributes - and ignore the "added" one, if present. But if I make this parse subsequent rounds of fambattles, will need to save multiple attributes in the "current" state of the familiar.
 
Top