PTR Changelog 2018-08-13: room event log


  • Dev Team

    This post describes changes on the Public Test Realm.

    Commits on GitHub:

    Currently Screeps has no API to track what actions have been succesfully performed, or what creeps have made certain actions to which targets. This is especially important in battles, when your creep receives damage, you can't determine the actual attacker. This patch introduces a new system called room event log.

    New method is added: Room.getEventLog (see documentation). It returns an array containing event items that describe most actions that have taken place in this room on the last tick:

    [{
      event: EVENT_ATTACK,
      objectId: '54bff72ab32a10f73a57d017',
      data: {
        targetId: '54bff74fb32a10f73a57d018',
        attackType: EVENT_ATTACK_TYPE_MELEE,
        damage: 20
      }
    },
    {
      event: EVENT_HEAL,
      objectId: '54bff72ab32a10f73a57d017',
      data: {
        targetId: '54bff72ab32a10f73a57d017',
        amount: 10,
        healType: EVENT_HEAL_TYPE_RANGED
      }
    },
    {
      event: EVENT_HARVEST,
      objectId: '54bff72ab32a10f73a57d017',
      data: {
        targetId: '54bff74fb32a10f73a57d018',
        amount: 50
      }
    },
    {
      event: EVENT_REPAIR,
      objectId: '54bff72ab32a10f73a57d017',
      data: {
        targetId: '54bff74fb32a10f73a57d018',
        amount: 1000,
        energySpent: 10
      }
    },
    {
      event: EVENT_UPGRADE_CONTROLLER,
      objectId: '54bff72ab32a10f73a57d017',
      data: {
        targetId: '54bff74fb32a10f73a57d018',
        amount: 10,
        energySpent: 5
      }
    },
    {
      event: EVENT_TRANSFER,
      objectId: '54bff72ab32a10f73a57d017',
      data: {
        targetId: '54bff74fb32a10f73a57d018',
        resourceType: RESOURCE_ENERGY,
        amount: 200
      }
    },
    {
      event: EVENT_EXIT,
      objectId: '54bff72ab32a10f73a57d017',
      data: {
        room: 'W18N23',
        x: 0,
        y: 28
      }
    }]
    

    Events last only one tick, so if you need to track event logs for a longer period, you have to store them on your own. Every room has its own eventLog array. You can track events performed by a particular creep like this:

    _.filter(creep.room.getEventLog(), {objectId: creep.id});
    

    Or you can find all hostile actions against your creeps and structures:

    _.forEach(Game.rooms, room => {
      let eventLog = room.getEventLog();
      let attackEvents = _.filter(eventLog, {event: EVENT_ATTACK});
      attackEvents.forEach(event => {
        let target = Game.getObjectById(event.targetId);
        if(target && target.my) {
          console.log(event);
        }
      });
    });
    

    Even when the creep object is gone (being killed or leaving the room), the attacking event is still recorded to the log, so you are able to reason on what's happened.

    Not only hostile actions are recorded, but you can also use the events log to track effectiveness of your harvest, upgrade and repair operations.

    Since these JSON arrays can become quite big, they are stored and fetched by the engine as raw strings, and deserialized using JSON.parse when you call the Room.getEventLog() method for the first time. Thus, if you opt-in to use this feature, it will incur some CPU cost depending on the number of actions in this particular room in the given tick. You can retrieve raw JSON in string format using Room.getEventLog(true).

    See previous discussion in this forum thread.

    This feature is supported in private server ptr branch:

    npm install screeps@ptr
    
    👍


  • Looks awesome. Thanks, Artem.



  • A really cool and useful feature. Thank you! I like it!


  • Dev Team

    Another idea how to implement access: we can replace the Room.eventLog property with the Room.getEventLog() method and its variant Room.getEventLog(true) to get raw unparsed data to store in a memory segment and parse it later. What do you think?

    👍


  • I would prefer an option to parse it myself. I can see a few uses were autoparsing isn't ideal:

    1. If I'm looking for a particular event type it will probably be faster to extract the data myself rather than parse->filter.
    2. I can imagine a case where I want event information a few ticks ago, but I didn't know I wanted it until now. Without autoparsing I can store it then dump it if I don't need it for nearly free. With autoparsing I'm stuck. I don't have a concrete use case for that though.


  • @artch Having access to the raw text is more flexible and sounds better. May I propose that we don't have a boolean argument that distinguishes the two options as it's hard work to read the code and know what that argument does without having to consult the API. Three alternative approaches that I think would all be better for different reasons:

    1. use constants instead of true/false - e.g. Room.getEventLog(EVENT_LOG_OBJECT) and Room.getEventLog(EVENT_LOG_RAW)

    2. 2 different functions - e.g. getRawEventLog() and getEventLog()

    3. Rather than a function with options or 2 functions, why not just provide a single function. This function provide the raw JSON text and force us to parse it ourselves if we want it in object format? Maybe that's a bit user-hostile, on the other hand, we're mostly programmers so we're used this that...


  • Dev Team

    @wtfrank Neither of these three options looks better to me. It is not true/false, it is undefined/truthy, i.e. an optional parameter which in 90% cases will be used simply as Room.getEventLog() by most players.


  • Dev Team

    Room.eventLog changed to Room.getEventLog() on the PTR. The documentation and the first post are updated.


  • Dev Team

    This feature is now supported in private server ptr branch:

    npm install screeps@ptr