Bug - Not A Bug fight.php relay overrides use previous encounter data for round 1

zarqon

Well-known member
For fight.php relay overrides, functions that should refer to your current monster (such as last_monster(), monster_element(), etc.) still refer to your previous monster for the very first round of combat. After the first round/page load, these functions return the expected values for the current monster.

This led to some very confusing results when a table I had that displays combat options along with projected damage to the monster seemed to be considering monster resistances very capriciously.

It seems that mafia doesn't register the encounter until after the fight page has loaded -- which makes sense. However, it is problematic for relay overrides that want to use mafia's monster functions throughout combat. Is there a way around this?
 

Winterbay

Active member
Having no idea how these things work I wonder if it could work (as a workaround) to parse the name of the monster from the fight.php-page yourself for the first round and supply that to the monster fuctions.
 

zarqon

Well-known member
I really don't know what to do about this. If I need to parse the monster from the page rather than use mafia's functions, it will mean a major rewrite. I had no idea porting a consult script to relay would encounter this rather stupefying roadblock.

Moving mafia's handling (and enhancing) of the page before override handling would solve this issue, but would probably have unwanted repercussions with existing override scripts.

Perhaps mafia could parse the page once before, then run the relay override, and finally run the page decorator?

Or perhaps only switch the handling around for fight.php?

I could twiddle thumbs once -- but that's an extra server hit per combat, i.e. evil. The opposite of BatMan, which is good.
 

StDoodle

Minion
Huh, this is odd... my fight.ash script is returning the current monster info just fine.

(Also: please let me know what time would be good to talk, or if I should just give up. :()

Edit: ok, it doesn't, I'm an idiot.

Edit2: Other info, such as turncount, fails to update as well. In other words, mafia seems to know nothing at all about your current turn when a fight.php override first runs; it isn't just the monster.

Edit3: I wonder if this is at all related to problems that sometimes occur in a CCS, ie it fails irregularly to go beyond the first line.
 
Last edited:

holatuwol

Developer
Looking through the code, as soon as it sends a request to the server, it's supposed to parse that data before returning control to the ASH script, assuming it believes you're on the first round.

Only thing I can think of is if it's confused about what round it's on (it only does the parsing if it believes it's the first round). Could you provide me with an example relay script that I can try? I might just rework all of KoLmafia's round tracking to rely on the server's information (since it already provides that data to us) if it turns out that it's a problem in the round tracker.
 

Theraze

Active member
Thinking it may have to do with initiative and winning/losing it, since that officially makes it different rounds according to mafia's current tracking code...? Just a thought.
 

StDoodle

Minion
hola, all you should need is a fight.ash override with:
Code:
void main() {
   print(my_turncount() + ": " + last_monster());
}
to see what's happening.
 

slyz

Developer
I might just rework all of KoLmafia's round tracking to rely on the server's information (since it already provides that data to us) if it turns out that it's a problem in the round tracker.

There was a bit of discussion about this in this thread. I also think Veracity or Jason already explained a few times that changing Mafia's internal round numbering would break the way CCSs are handled.

It might be unrelated, but I ran into a little problem when using KoL Combat Macros with adventure(). My post is here. I'm pointing it out here because of the difference I found between cases where it worked and cases where it didn't work: the first action in the Macro is correctly executed when "fight.php?ireallymeanit=<number>" is requested before "fight.php?action=<action>" is requested.

Since I don't know what "fight.php?ireallymeanit" does, or if it causes a redirect that would confuse Mafia, I'm just throwing this here =)
 

holatuwol

Developer
hola, all you should need is a fight.ash override with: ... to see what's happening.
Well, that one would not work because visit_url() is not called before the invocation of last_monster(), and visit_url() is what parses that data.

Is there an example where you do call visit_url()?
 

StDoodle

Minion
No, that's precisely the behavior that is troubling. It seems counter-intuitive that any fight information accessed by mafia on a fight.php override will reference the previous fight during the first page load of a new fight. Also, it makes it impossible to calculate anything based on the current fight in said situation without an extraneous visit_url(), which is rather a waste of a server hit. Unless, of course, the first visit_url() uses data saved somehow by mafia; in this case, it doesn't hurt. But as far as I know that doesn't happen.
 

holatuwol

Developer
When KoLmafia calls fight.ash, KoLmafia has not even visited the page describing the first round. It's waiting for your fight.ash to tell it to using a visit_url() before it does so.

Is the problem that scripts have no way to know that this is the first round and therefore scripts cannot be written to behave differently? If you know your script will always call visit_url, one workaround would be to always call it at the start and store it into a global script variable, and reference the global script variable instead of visit_url wherever you actually need it.

If not, how do you propose for KoLmafia to know what the last monster is given that it has never even hit the KoL servers to know what's taken place? I mean, the functionality was written so you would never have to visit the actual page that you're overriding, but if the functionality's never been used like that, maybe it can be re-evaluated.
 
Last edited:

StDoodle

Minion
Wait, so the visit_url() with 0 parameters, in a relay script, just reads what's currently there and doesn't do another server hit? If this is so, then we have absolutely no problem; we just visit_url() at the start of the script as you said. Our concern was that doing so (using visit_url() with 0 parameters in a fight.php override) would indeed hit the server an extra time. I admit, I'm a bit unclear on when each version hits the server, and when they don't. Any insight is appreciated.
 

zarqon

Well-known member
@hola: I hadn't given thought to the fact that relay scripts wait for a specific command to fetch the page being "replaced." I'll see if this knowledge gives me a workaround -- but it's problematic that I can't put this visit_url() before importing the BatBrain function library -- which is also used in the consult version and therefore should not call visit_url().
 

holatuwol

Developer
Well, the current process is that KoLmafia stores the URL that it needs to visit into its own internal variable without ever hitting KoL. When you invoke visit_url() with zero parameters, it uses that local variable in order to decide what URL to request, and then issues the request. It's described briefly in the first post in the relay forums.

This means that repeatedly calling visit_url() will repeatedly visit the KoL servers with the URL that was originally passed, so it wasn't to save server hits. The idea was to allow scripts which submitted an entirely different URL without hitting the original URL (so, something similar to KoLmafia's warning messages when counters expire), or do before/after checks when deciding how to render the data much the same way KoLmafia does.

Again, that was the original intention, but the feature as it was designed was added several years ago, and I have no idea how it's been used since I stopped playing. So, if it turns out that this is a surprise to everyone and that, in fact, it should just visit the URL before passing the data in, and have visit_url() simply return a cached copy of the page, then I can certainly change the behavior.

@hola: I hadn't given thought to the fact that relay scripts wait for a specific command to fetch the page being "replaced." I'll see if this knowledge gives me a workaround -- but it's problematic that I can't put this visit_url() before importing the BatBrain function library -- which is also used in the consult version and therefore should not call visit_url().
It's a little bit of a hack, but what you can do is provide a fight.ash that does nothing inside of its main method except visit_url() followed by a cli_execute("call someotherscript.ash"). Though I guess that doesn't provide you with the page text or the current monster in the same way that an ASH consult script would.
 
Last edited:

Veracity

Developer
Staff member
Don't do that. That will break scripts that want to pre-empt visiting the url that the user requested. Instead, educate.

I was amazed to learn that people didn't realize that if you have a relay override, that KoLmafia doesn't actually visit the URL until the override TELLS it to do so with the no argument version of visit_url(). Now they know.

I'm inclined to mark this one "not a bug" - once people realize how to use the way things REALLY work currently to accomplish what they want to accomplish. Now, if it turns out there is some other issue, cool (or not) - but the issue is not that KoLmafia has not updated the monster variables for a fight.php override before fight.php has ever been called.
 

Theraze

Active member
Well, in the relay version of fight.php, the proper behaviour is just to have the first line be visit_url() so that it updates the information... right? Or does that mean it does 2 hits for every round, and every other round gets skipped?
 

Veracity

Developer
Staff member
Read what hola wrote, what you asked, think about it, and answer your own question.

Hint: the relay override script is called when the user is about to request a URL from KoL. At the time it is called, the URL has not yet been submitted.
 

holatuwol

Developer
I suspect the problem is that the imported script declares some global variables that are initialized based on the current round information in the global scope, and that's how it all works. Therefore, by the time you call visit_url(), it's already too late because the global scope has already executed.

The only thing you can really do (assuming you cannot just call a helper script's main method with no parameters) is modify the imported library script to provide an initialize() method that does all the actual initialization, have it call initialize() in its own global scope, and then call initialize() again in the relay script after the visit_url().

Well, in the relay version of fight.php, the proper behaviour is just to have the first line be visit_url() so that it updates the information... right?
That largely depends on what you want your fight.php to do. In the example script I provided when I introduced the feature, calling visit_url() as the first action is precisely what you do not want to do, because it was actually generating links that were complete gibberish as far as KoL was concerned, but that the relay script could convert into a sensible chain of requests simulating a disco combo.
 
Last edited:

zarqon

Well-known member
Yeah, hitting the server beforehand is not the way to go. The current method is wonderful for saving server hits in the event that a page is actually replaced -- also for fictional links being followed and then generated entirely by an override (which I used elsewhere before the relay_ prefix and menu was available, and still use in some cases).

I agree that this is not a bug per se, but it's not a feature either -- didn't know what to call it, really. It is a not insignificant problem for me to script around, so I wondered if people who know more than me might be able to suggest a workaround or implement a change that would help this particular situation, without requiring a significant rewrite of my approaching-1500-lines script, which was originally written as a purely consult script, where mafia's monster functions always refer to the current monster.

Since there don't appear to be any solutions that don't cause unnecessary server hits, and the problem is not unsurmountable in-script, it would appear that the rewrite is necessary. And it shall be made... eventually. Feel free to mark this not a bug.

/eeyore
 
Top