CGamesPlay

@CGamesPlay

Posts made by CGamesPlay

I think the value add to the game is less than some of the other ideas I've heard, e.g. power creeps.

Unbreakable contracts seem to go against the idea of a war game, where you can breach contract and then get punished using whatever means your opponent has (including in the metagame, convincing other players to not trust you).

The most interesting nugget of this idea to me is the idea of programmatically executing code on behalf of another user, but this is actually implementable using terminal messages and public memory segments, plus if I breach the contract people can "hold me accountable" however they want.

@artch Throttling would be ideal. A token bucket controlling the maximum amount of data that can be sent is probably easiest to implement. From my limited memory of the socket endpoints, I think dropping messages that would overflow the bucket is reasonable (I don't think any client will get confused if messages were dropped since they are all named ws events). You could even send a console message describing that you are being rate limited.

Do you have anything you can share about the impact these proposed limits would have on current usage patterns? Perhaps it would be good to turn on these rate limits in "warning mode" for a few weeks to gather feedback on what reasonable limits feel like?

The websockets endpoint specifically I wish would be rate limited on bandwidth rather than on connection duration. My external console takes effectively no bandwidth but stays connected for hours, even a 0.25 KB/s bandwidth limit would be completely acceptable to me.

As far as the UI-less reCAPTCHA page to clear the rate limits: I actually think this is pretty fine. I'm imagining the deploy script would catch an error and print out a link for the user to click, then just keep refreshing in the background until the user did it.

Sounds like stats are a problem for you guys, so the rate limits on that make sense. I do wish it were more usage-based, like e.g. maybe these endpoints have a CPU cost associated with them that drain directly from your bucket. This creates an incentive for users to optimize their stats collection, and you can adjust the CPU cost of the endpoint as required.

As someone who enjoys making tooling for the screeps ecosystem, I'm pretty excited about this new feature, but wanted to come in to express my concerns about the rate limits. Since you've already said that the values will likely be changed, I'll just ask one question: Why do the rate limits exist? Here are my thoughts on potential answers to this:

The rate limits are intended to reduce demand on Screeps infrastructure.

In this case the limits should very likely be set so high that only problematic scripts would ever trigger them. For example, requesting a memory segment (100 KB) from each shard (3) once per tick (~.3 Hz) would round out to about 100 KB/s of bandwidth. If supporting that is tenable, the limit should be .3Hz (or 1080 / hour).

For an even more stark example, the code upload limit should likely be closer to 720 / hour or more, given that the "baseline" is users editing code in the online editor might save every 5 seconds during active development, and we know the infrastructure can support this.

The rate limits are intended to increase the challenge of the game.

This seems less likely to me, but if this is the case then browser and steam clients should be rate limited as well. If you don't rate limit that authentication mechanism, then the external tooling will just find ways to use it so it can bypass the rate limits. For example, instead of the tool saying "go here to get an API token", it would say "go here to log in, then run this user script to produce a cookie you can use to log in". It's also worth pointing out that the API method of accessing memory/market/map is emulatable using the console API.

Regardless of the motivation for rate limiting, I'd like to request that a few specific ones be increased to specific values:

POST /api/user/code should have a rate limit of at least 12 / minute = 720 / hour. This lets you update code every 5 seconds, which I bet an active coder on the site would be updating at during active development.

GET /api/user/memory-segment should have a rate limit of at least 1080 / hour. This will allow a script to collect per-tick stats from each shard in realtime.

The respawn delay after being wiped feels like an odd barrier to getting back into the game. I get that my controllers were taking up space until I pressed that button, so me pressing the button did have some in-game effect, but it seems like a sad choice to punish a dead player who wants to start back up.

A Power Creep is a particular (named) creep with skills that you've personally selected and levelled up over time. If it dies, you can reincarnate it with the same skills it had previously (subject to the cooldowns, resources required, etc).

As currently designed, you can do this at any PowerSpawn. The idea is to instead "dedicate" a PowerSpawn to a creep.

A Power Creep can only be reincarnated at a PowerSpawn dedicated to it.

Only one PowerSpawn can be dedicated to a single Power Creep.

Once a PowerSpawn has been dedicated, it cannot be changed (though you can destroy the PowerSpawn and recreate it in the same place or elsewhere).

A Power Creep can only have a PowerSpawn dedicated to it once every few weeks (or some other large cooldown).

The cooldown for respawning a Power Creep should be low or nonexistent to help compensate for the additional restrictions placed on their spawning.

Motivation

This change makes PowerSpawns a critical structure for a player, since it takes a very long time to be able to dedicate a new one. The impact of taking out a power spawn extends even beyond being able to seize a room; it's a major blow to the player's entire army.

This pushes PowerSpawns back away from the front lines, because a player worried about losing a room won't dedicate the PowerSpawn in that room. This is why the reincarnation timer is lowered or removed.

The purpose of showing these is to highlight the difficulty in locking down the prototype object. For body, you have to freeze the property definition, the body part array itself, and all of the objects within the body array. This extends across exposed object in the game, and just feels like a losing proposition compared to the sure-fire way of preventing cheating, which is to validate outside of the client sandbox.

So, a recent change made Creep.getActiveBodyparts non-configurable. Presumably, this was to prevent people from being able to exploit bugs like the claimController one. I'd like to open up a discussion about the role of client-side validation versus server-side.

I propose that client-side validations should be advisory only and we should be allowed to "break" the implementation of these as we wish. In this particular case, this method can be overridden to be more performant by using a cache of the body parts. If you don't choose to make the validations advisory (but rather mandatory), you will reach one of two outcomes.

The first option is to prevent configurability on all methods that may need to be called from any intent validation code. If you do this as a blanket block on the prototype object you effectively prevent prototype extension and if you do it on an ad hoc basis you will repeatedly break user code with each new modification. These options are undesirable because prototype extension is one of the primary mechanisms for adding high-level behavior to creeps.

The second option is to discontinue using the prototype chain for client-side validation. This would basically change all calls in the form of this.getActiveBodyParts() to calls in the form of storedGetActiveBodyParts.call(this). This would prevent any prototype modifications from affecting the validation code. This option is undesirable because overriding prototype methods to be more efficient is currently a viable strategy in the game. It would be a shame to force players to effectively "open source" some of their proprietary performance enhancements.

My proposal is to treat client-side validation as advisory/optional. If I choose to bypass certain validation checks, it should be a waste of my CPU because the actual intent processor should disallow the intent from going through. Taken to the extreme, you could even publish unvalidated methods like `Creep.unsafe_claimController` which would completely bypass validations and not return any error code. This could reduce CPU usage a hair for players who are really grinding on it.

If something is standing on a construction site for OBSTACLE_OBJECT_TYPES and you call Creep.build on the site, it returns OK despite the fact that the build will fail when the intent is resolved. This PR fixes that.