[Market] Create API method Game.market.getOrderById()


  • Culture

    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.


  • Culture

    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;
    }