PTR Changelog 2016-09-29


  • Dev Team

    Artem, to get a sense of scale for us, what is the current average of amount of flags per GCL?

    I don’t have such a calculation at hand, but here is another one:

    1 percentile - 613 flags
    2 percentile - 312 flags
    5 percentile - 140 flags
    10 percentile - 54 flags
    20 percentile - 15 flags
    50 percentile (median) - 8 flags

    Since the new Flag() part is the problem, using a memoized getter to lazy initiate the flags could help with the CPU issue.

    This is the same CPU-cost-based approach, since the getter will be called in the user CPU space. If you iterate through all of your flags, you will be paying for this instantiation in full every tick.


  • Culture

    Another thought is that if you are limiting flags you could add another structure, called a Landmark, which is like a flag but is attached to the Room object instead of the game object.

    The landmark structures can have the CPU cost you're talking about but with no limit in number. Since we can load them per room we can spread that cost out over multiple ticks ourselves by interacting with those landmarks once every X ticks or something. 

    This would make a limit on Flags much more palatable as it would still give people who do automated layouts a way to do so. A 10k limit with the promise of landmarks on the roadmap would work. People will naturally migrate to landmarks as they get closer to the flag limit.


  • Culture

    For the record I never iterate over all the flags.


  • Culture

    Yes, it would be the same cost IF the user iterated over them all, but, if the user say, called Game.flags.xyz, it should only initiate xyz and not all of them. It would only be in cases like lookAt or iterations that would trigger them all.
    I am still all for the 50-60 char name limits, I'm just trying to help out on the related core issue

    If I'm not mistaken, this would also end up user side, but, would give the user much more controll over how much it costs.


  • Dev Team

    Another thought is that if you are limiting flags you could add another structure, called a Landmark, which is like a flag but is attached to the Room object instead of the game object.

    The landmark structures can have the CPU cost you’re talking about but with no limit in number. Since we can load them per room we can spread that cost out over multiple ticks ourselves by interacting with those landmarks once every X ticks or something.

    This would make a limit on Flags much more palatable as it would still give people who do automated layouts a way to do so. A 10k limit with the promise of landmarks on the roadmap would work. People will naturally migrate to landmarks as they get closer to the flag limit.

    Well, now you are offering an alternative, and I like it! We have to think about it a bit more though, but it might be the path that leads to the solution we’re looking for.


  • Culture

    It would be great if we had a way of iterating flags without causing the objects to instantiate. That would still disallow a few ways people tend to use them now, but would at least open up another area.

    IE: I only use a handful of flags dynamically. Most other flags are objects that really don't need to be checked every tick. Now I have to stop using flags for everything but the periodic checks because I have to pay the entire deserialization cost by touching one of them. (I don't have many flags; just planning ahead).

    IE: an iterator or array containing flag _names_, separate from a function like Game.getObjectById() that gives you the whole flag object back.

    I understand that some people are checking properties of flags on every tick and there isn't much to be done there. Caching or object reuse would help, but it seems like our instances aren't very sticky so I'm not sure how that would play out in reality.

    As an aside: It sounds like you're having a lot of systems issues in recent months. Is there any way at least one of us who does this professionally could help with a few hours of labor? I'm well familiar with being on the other side of something with performance issues and having people armchair-narrate how to fix them without a full understanding of the problem.

    However I've also been pulled in many dozens of times by random (very large) companies and made pretty large impacts by dealing with easy low hanging fruit. If it helps smooth things out I'm sure at least someone would be open to it (I could throw a few hours or days at it).

    Thanks


  • Culture

    Few notes on Landmarks-

    - They should work just like flags as far as placement and removal goes- the closer the APIs are to each other the easier it will be for people to use them with existing code.

    - Unlike flags they would require room visibility, since they are attached to the room object. 

    - They should *not* be included by default in the look* functions, since that would force them to get created each tick and the whole point is that they should allow us to only have to access them when needed.

     



  • On the bottom of page 1 of this thread, dissi suggested something I wanna repeat so it doesn't get lost:

     

    I think if we can emit events for the game to display:

    Game.rooms['someRoom'].displayIcon(SomeRoomPosition, COLOR_BLUE, COLOR_RED, "path.to.memory") // Maybe public/private? vision required!

    A lot of people would be happy. Of course you can still choose to use the flags, but at a cost.

     

    I was wondering for quite some time if this would be a possibility: adding methods that let us influence the game rendering, like drawing an icon at a certain position, a line between 2 positions, etc - just to visualize what our scripts are doing, for debug purposes or whatever. so far I've been using flags for that, but that never felt quite right. i don't need actual persistent objects there, i just want some visuals.


  • Culture

    I just want to point out how much difference there is between the reaction from players now versus when this far more drastic change happened:

    http://support.screeps.com/hc/en-us/articles/205193752-Important-change-CPU-cost-of-API-methods

     

    It seems like the increased interaction is a good thing, coming up with more ideas. Hopefully there will be many more in the future, even on not such intense changes.



  • Artem, seriously, a great big thank you for maintaining the game. I know you need to push updates and security fixes and patches for balance and sometimes it either breaks our code or breaks our style of gameplay... and it makes some of us unhappy... but I can see that you have the future of the game's security, balance, and development goals at the forefront of your mind. Even if I don't like some of the changes as they roll out now, I look forward to playing this game from now into its future.

    And thank you for noticing some peoples' utilization of flags as free memory (kilobytes per flag? wtf?) and making changes so that we don't collectively pay for those individuals' intelligent but generally taxing shortcut around memory utilization.

    And thanks to the community for helping to come up with solutions for these issues when you feel like Artem is too heavy-handed on the updates. A shout-out to tedivm for not rage quitting and even putting some good solutions out there (landmarks? I can dig it). I say thank you because I don't have any solutions to the issues of flag usage, since I don't use any flags, therefore I'll kindly bow out of this conversation!


  • Dev Team

    I was wondering for quite some time if this would be a possibility: adding methods that let us influence the game rendering, like drawing an icon at a certain position, a line between 2 positions, etc - just to visualize what our scripts are doing, for debug purposes or whatever. so far I’ve been using flags for that, but that never felt quite right. i don’t need actual persistent objects there, i just want some visuals.

    It is a whole other take on this problem. We actually debated a thing like this before, some RoomVisual layer, where you can draw lines, rectangles, icons using the SVG-based API like that:

    Game.rooms.W1N1.visual.drawLine(from, to, 'red');

    But it is just about UI representation, it will only be displayed in the game client as a separate visual layer on top of your room, your script won’t have access to this info, so it’s useless in terms of room positions markup.


  • Dev Team

    Since the new Flag() part is the problem, using a memoized getter to lazy initiate the flags could help with the CPU issue. Such as below:

    Another issue with this approach - you’re creating a separate getter function closure for each flag, so it is about creating thousands of closures, and they are also slow in V8. Our quick test shows that this approach is even slower than creating the Flag instance right away.


  • Culture

    The main reason I use flags myself is to have a point in another room, which doesn't require vision and can be gotten by a method in game using some form of ID:

     

     

    If the landmarks wont be build-able, or "visible" when not being in a room I'd have to do a lot more refactoring and would like to know this beforehand.

     

    Is the intention to remove flags completely from the game? Or just have a hard limit on 10k flags max? 

     

    > Game.rooms.W1N1.visual.drawLine(from, to, 'red');

     

    This would be good if it were private, so you can visualize stuff from/to could just be RoomPositions, and the data should only be there next tick. It doesn't solve the script access in non-visioned rooms.

     

     

     


  • Dev Team

    Is the intention to remove flags completely from the game?

    No, there is no such intention. Flags are a great tool, they just need to get revisited a bit.

    This would be good if it were private, so you can visualize stuff from/to could just be RoomPositions, and the data should only be there next tick.

    Of course, they are private, like flags.

    It doesn’t solve the script access in non-visioned rooms.

    Actually, we might be able to do something with this. It might be feasible to allow to create a Room instance explicitly and call some methods on it even without vision:

    var room = new Room('W1N1');
    room.createFlag(10, 20, 'Flag1'); // OK
    room.visual.drawLine(from, to, red); // OK
    room.find(FIND_CREEPS); // Error - no vision

  • Culture

    Is it possible to create an object buffer of sorts to store "pre-made" flag objects in? And later set the data using setters?

    This could relieve object allocation pressure. Something like a circular buffer could do the trick.

    When dealing with massive amounts of small-short-lived objects it's best to keep older ones around and re-purpose them somehow.

    Does such a system function in the engine?



  • Overall, this seems like a good change.  Anything that prevents abuse at the expense of other players is good. 

    What about creep names?  Seems like we should limit creeps to 50 characters also, else someone will just create a bunch of creeps with 50kb in the name, and just put them in a corner of their room.



  • I have another suggestion (or wondering in general) - at the moment each structure has an isActive property - if the people are so using the flags to mark locations for future buildings - just remove the limit of placing the buildings early on. If they need it to be rebuild when destroyed - that's what the Memory is for. 

    10k flags is a lot lot lot.. a limit like 1000 in total seems appropriate so that they are not used as a memory alternative even for saving locations


  • Culture

    Flag names should be at least a few characters longer than creep names, as many people use the CREEPNAME_ACTION format to order their creeps around on an individual level.


  • Dev Team

    Let's move this discussion to the follow-up thread.