[Market] Create API method Game.market.getOrderById()
-
This way we don't have to filter all orders every time if we want to "buy out" a certain order over multiple ticks, but can quickly access it directly in O(1) fashion.
The same method like Game.getObjectById() would be recommended.
-
YES!!!!
I had this one bite me Yesterday. I was trying to finish of preparing an order for 10,000 O, only for that order to "vanish" (someone else finished it). Because of the cost of getAllOrders I wasn't able to check and see. Had I been able to detect the order not being available anymore I would have reacted, Either by picking another resource, or finding another order. The current way, I had to wait for deal() to error out, then try to find another order, only to have that one require a different cost, and then .....
Getting a single order would have enabled a per tick check (or at least a per round trip for the creep check) to see if the order I was working on was still valid, or if I needed to do something else.
-
Dissi: doesn't it works the desired way?
let order = Game.market.getAllOrders()[id];
Seems like without filtering it's possible to get cached hash-map of all orders fast enough. Moreover, u can use your own caching, smth like:
function orders() { return Memory.orders || (Memory.orders = Game.market.getAllOrders()); }
Simplified, but only fix to be implemented is checking the current tick (Game.time === update_time). Works pretty nice for huge amount of calls in the same tick.
-
It does not sadly. It returns an array, not an object. also storing them in Memory is quite a bad idea for CPU-reasons so storing a single transaction ID is definitely a plus. If I were to use a filter for the orders { id : 'someId' } it will loop over ALL orders - horrendous for CPU.
-
Oh, yep, I've missed that array is returning. Using some wrapper, so ye, my cache actually contains only bid-ask, ids and some other technical info, built only once per tick and it's about ~1Kb, but there aren't full orders here.
-
Also caching orders is a bad idea, as players can now change the order price. With a fast method to access an order by id, we could easily check whether the price is still the same.
-
@ saturn7: I think, it was meant that reducing an Game.market.getAllOrders() to hashmap takes a long time, and it can't be saved into Memory due to huge size, and it will be used several time per one tick.
@ Dissi: I've found a pretty useful solution (see below). Not sure where exactly "global" object is stored at runtime under hood, but there are some statistics: ~1.0 cpu -- first call, ~0.01 cpu -- every subsequent calls.
global.orders = function() {
if((global.__orders_update || 0) !== Game.time || !global.__orders) {
global.__orders = _.reduce(Game.market.getAllOrders(), function(res, o) {
res[o.id] = o;
return res;
},{});
global.__orders_update = Game.time;
}
return global.__orders;
}