Request: Wok of Ages script

suinoq

New member
Goal: Script that burns turns at the Wok of Ages, for the purpose of selling Wok-able food items at low prices.


Background: My pastamancer multi sits around with his hands in his pockets all the time, as I've no time to play him. There's a whole lot of adventures that could be used for pro-bono cooking, but instead they're going to waste. Unfortunately, his new career as a volunteer chef isn't going to get off the ground unless the necessary actions are scripted. I've very little experience with .ash scripting, however, so I've chosen to post this request.


Reward: How about the first month of revenue from the store? I'll let the script designer pick the markup per item during this interval - whatever profit is secured will be theirs. It'd be essentially a month worth of Wok farming.


Detail: Here's an outline of the desired behavior:


First, generate today's menu
1. Check mall price of wok-able ingredients (casseroles, sour sauces, etc. - exclude lobster and dumplings)
2. Check mall price of each wok final food (lasagnas, hi meins, etc.)
3. Calculate the price premium of each final food as (current price) - sum(ingredients)
4. If the price premium is greater than epsilon (say 200), then that dish is on today's menu.

Second, get some turns
1. If today's menu is not empty, then consume something fairly cheap to generate some turns (EatDrink.ash?)
2. Save fullness for cookies (maybe). A couple semi-rares thrown into the cooking could help offset costs, but it's not necessary. (CounterChecker.ash?)

Third, start the fires
1. Cook 'em up! Target equal inventory levels of all foods on the menu.
2. If SRs are implemented, take a break and get 'em at the appropriate time.

Fourth, sell it all
1. Toss it all in the store with daily limits of 3 (hi mein) or 5 (lasagna) - whatever will satisfy a single player's per day stomach.
2. Set the price at just slightly (50?) over cost.


The pricing policy is not quite resolved in my mind. What price? On one hand, I've no desire to make any profit off of the process, so selling at cost would be fine. On the other, there's bound to be some day-to-day cost fluctuations in ingredient prices. Preferably the process will be robust to these changes - I don't want to have to continually pump meat into the multi to keep him afloat.

Further, even if I'm cooking up 250 or so foods per day then I still might 'stock out' daily... if it's to be a soup kitchen then I'd prefer it to be open 24 hours. It seems that this problem is an intrinsic issue with the market, and not something to be bothered with in the script, however.


Thanks so much~
 
Last edited:

heeheehee

Developer
Staff member
Working on it, should have an initial copy up in a bit.

Edit: Preliminary version up, expect it to be buggy, because, well, it hasn't been put through any remotely realistic simulations. Requires the latest version of EatDrink.ash.

Double edit: Of course I would forget to make it overdrink at the end of the day. Just add this line as the second to last:
Code:
eatdrink(fullness_limit(), inebriety_limit(), spleen_limit(), true);
 

Attachments

  • wok.ash
    2.5 KB · Views: 58
Last edited:

suinoq

New member
I've just run this for the first time, and it is definitely getting the broad strokes right. Stuff is being bought and wokked, and then put in the mall store. I'm going to sit down and pick through the pricing decisions that were made, but here are a couple quick observations.

-Lasagnas started popping out at ~2k each, with mall prices sitting around 4k. This got me excited. Unfortunately, with casserole prices sitting at ~1000 each I think that these were underpriced. There are cheap casseroles with limits that were bought, and I suspect that the final pricing decision were based on these.

-Chow meins were produced and put for sale at 5 - 5.5k each, though these were not at mall min, or even below stores with unrestricted purchase quantities.

-Hi Meins came out at just a touch over 5k, and started selling immediately. The prices on these seemed about right.

Overall, there's probably some issues with mall stores that have limits corrupting the pricing decisions along the way. As I understand it, this is a common problem - does it help that this script is actively buying from the mall? That is, since I'm buying, I'm also permitted to do more price checking in the course of the script?

Anyhow, fabulous stuff. Put a huge smile on my face!
 

heeheehee

Developer
Staff member
The script does the buying, then compares your meat after buying to your meat before buying to figure out how expensive these things should be. The only calls to historical_price(), which ignores stores with limits all together, are to check if the item should be sold at all.

Sorry, can't do any diagnostics at the moment, since it's rollover.

For the time being, though, if you want to confirm prices instead of letting the script automatically toss the noodles into your store, you can add
PHP:
if(user_confirm("Put "+i+" into your store at "+(netCostPerUnit+MARKUP)+"?"))
in front of this line:
PHP:
put_shop(netCostPerUnit+MARKUP, 3 + i.contains_text("mein").to_int()*2, i);

Edit: Just checked it out, and it turns out that the lower prices are most likely the cause of these lower prices. Go philanthropy, extended one degree!
 
Last edited:

suinoq

New member
So I spent an hour typing up a detailed response, and then lose it due to the forum shutting down the session... lesson learned.

Here's what I've got so far:


1.
In the assessment step Bat wing chow meins were a go. After creation and mall placement, however, they were a good bit higher in price than the mall min (unlimited). The script correctly calculated the selling price for these, it just should have rejected them during the assessment step. It would seem one of two issues:

*Mall state change during script running. Either ingredient price changes, or the competing mall store.

*The prices delivered by historical_price during the assessment step were incorrect. What result does this function return if there have been no calls to mall_price yet?


2.
The final price set to Fishy fish lasagnas does not compute correctly. I've pulled out the stated prices and done the math, and it doesn't add up. Perhaps there was a sale from my mall store during script execution, corrupting the usage of my_meat? Internal variables to collect purchase prices might be necessary if this is a problem.


3.
There is a potential issue with the repeated purchasing of ingredients from the mall - the go/nogo decision could switch as I push up prices. Though it would seem workable to iteratively call my_price (as it would be buying repeatedly), it would feel a bit tawdry to make so many server hits.


Ok, let's hope I can submit this much more brief reply...
 

heeheehee

Developer
Staff member
Historical price uses data from the KoLmafia server, if you have the "Share mall price data with other users" preference checked. Generally preferable, as historical_price() saves quite a few server hits. If you don't have it checked, then I think it uses the data in mallprices.txt, which depends on your version of Mafia.

#2 seems likely. I wonder if I could make some changes to make this much less likely while still using the same mechanism to maximize correctness.

Either way, there seem to be several (obvious) possible changes I could make for this script:
a) scrap the whole mechanism altogether, using mall_price(). Biggest problem with this is that you probably would have to do the pricing manually. I'd rather not do this if possible.
b) buy in chunks, say, 10, and check to see if you're going over a limit while buying. But, as you mentioned, this would hit the server a bit more than I'd like.
c) toss in the selling portion at the very end. I'll probably have to combine this with one of several other measures, if I want to minimize risk of items being sold and changing meat state.

I really don't want to add in a storelog parser, but I do have the code if it's really necessary.

Edit: For the time being, here's a somewhat modified version that implements b) and c), along with several other slight changes.
 

Attachments

  • wok.ash
    3.9 KB · Views: 50
Last edited:

Bale

Minion
Historical price uses data from the KoLmafia server, if you have the "Share mall price data with other users" preference checked. Generally preferable, as historical_price() saves quite a few server hits. If you don't have it checked, then I think it uses the data in mallprices.txt, which depends on your version of Mafia.

That's why it is good to check historical_age() and if the value is larger than 2 or 3, call mall_price() instead of historical_price().
 

suinoq

New member
I've yet to execute this newest code - I'll give it a try in a few hours time. For now I think I'll break the loops so that I can step through the actions as the script runs, see what's happening, and offer feedback direct to the existing line of conversation.


That said, here's a couple of ideas that have been on my mind:

I'm thinking that the we could leverage the delta price between MARKUP and PREMIUM to sidestep the issues of "storelog vs. my_meat" and "buying beyond menu threshhold". That is, based off of current price knowledge there would theoretically be exactly MARKUP profit for each wokked item. We could include the optional max_price parameter of the buy() command and set it to the queried ingredient price + MARKUP. We'd then know that everything purchased was within acceptability tolerances and we have an upper bound that can be used for sale price calculations.

The downside to this method occurs when the PREMIUM is high. Say that premium is 1000, and we've just gone through the purchasing and selling steps as described above. The current (real) ingredient prices might now be equal to the old queried price + MARKUP, due to my purchasing, but the PREMIUM will only have decreased by MARKUP. (or maybe not these numbers exactly, but something close enough) It would seem to be necessary to loop back to the acceptability code and refresh the ingredient prices with mall_price() at that point.

Further, this would lead to a series of sale price decisions, one for each loop. The first loop would output the lowest sale price (original queried costs + MARKUP) and the final loop would provide something higher (though still under the PREMIUM criteria). Which final price to use? Pro-rate it out, perhaps?


Actually... what to do with leftover offerings from previous days? Reprice them along with today's production? That could work, as long as the MARKUP can absorb the bumps in the road from daily price deviations. Also, it'd seem worthwhile to pull in shop_amount() during the production volume decisions.



Phew! I write a lot, Hope it doesn't annoy you. Not one bit of code in all of that, either. There's probably enough code here for me to begin templating off of, if you'd like. This weekend I'll find some time to sit down with the syntax and see if I can produce something.
 

heeheehee

Developer
Staff member
Regarding lotsa text: It's totally fine.

Recycled some code that I threw together for a take_shop() function and Zarqon improved for his own uses, so that didn't take too long to figure out the repricing if some of the item is left in the store (average cost per unit, so no additional change needed there).

An alternative is to set the markup equal to half of the premium. That wouldn't work as nicely with the config variables that I have set up at the top, but it's still very doable. Another option (which I'll implement for now), now that I think of it, would be to split up the markup among the ingredients.

Oh well, modified version attached for now. Possibly will get around to more later.
 

Attachments

  • wok.ash
    4.9 KB · Views: 71

Lxndr

Member
IT's been five years since this script was made.
Has there been any changes in KOL that would negatively effect this script?
 
Top