Discussion: Contract system
-
This is a draft of a new upcoming feature. We'd like to get community feedback on it before implementing.
Contract system in Screeps works in a similar way like smart contracts in cryptocurrency world. Using contracts you can automatically provide services to other players in a controllable and transparent manner.
A contract works like an external read-only script module which is executed on your behalf. It uses your CPU, your creeps and structures, but you cannot neither modify this code nor stop its execution during the contract term.
Some contract examples:
-
Find any suitable creep and send it to a room specified by another player to harvest a source/mineral and drop all resources in the specified position for him.
-
Use a courier creep to haul resources from room X to room Y.
-
Send X amount of the specified resource to another player's room every Y ticks.
-
Park a creep in the specified room and run some "find-attack" logic when neccessary.
-
Send a party to build up your remote colony.
...and many more. You can negotiate any code that your contractor agrees to execute. It looks like a regular script module:
const sourceId = 'XXX'; const dropPosition = new RoomPosition(15, 20, 'W1N1'); module.exports.loop = function() { var creep = _.find(Game.creeps, i => i.memory.role == 'contractorHarvester'); if(!creep) { return false; } if(!creep.pos.isEqualTo(dropPosition)) { creep.moveTo(dropPosition); return false; } return creep.harvest(Game.getObjectById(sourceId)) == OK; }
Every active contract is executed in the end of the player loop automatically by the game. If
module.exports.loop
returns true, then the contract is considered executed on this tick. Each contract defines how many ticks it should last, and how much credits the client pays to the contractor (host) when the contract is done. There is also an option to pay X credits every Y successful ticks.There will be new Contracts UI section in the side menu. There you can view your active contracts, their code and progress, view pending contract offers from other players, and create a new contract offer and send it to another player by name.
-
-
This sounds interesting... I have a few detail questions
-
I guess the contracted screeps will still be owned by the contractor .. so in safe mode for example they can't work?
-
there is no way to communicate or send data to the external script running in another players account while it runs? (except probably with using the terminal to send data)
-
many players use safeguards for ticks that already have a very high cpu count because of a GC for example to stop all execution for the current tick to prevent a reset... will it be possible to suppress the execution of a contract for a tick? I guess it won't be possible to negotiate a max cpu for the contract and do something like a mini reset when it is reached?
-
what does the "automatically provide" in the introduction section mean? you mention a new ui to create offers and send it to other players .. is it also doable by code?
also a small idea I just got about monitoring .. since the code runs after the players code it won't be easy to monitor it. maybe we could export a function in our main module that works as a wrapper? Or hook functions that are called before and after the external module? Maybe the hook before could return ´true/false´ whether the code should get executed.
-
-
First impression: It seems to me that this contract system is an adversarial game:
- The coder tries to get the most value before
true
is returned. - The runner tries to be as lazy as possible to get
true
to return.
My main concern are the security implications:
- It can be very difficult to detect underhanded code. http://www.underhanded-c.org/
- It takes little code to completely screw over a player. Here's my code-golf to do damage in various ways:
Game.market.createOrder(ORDER_BUY,'H',Game.market.credits,19,_.find(Game.rooms,r=>_.get(r,'terminal.store.H')).name)
_.each(Game.structures,s=>s.destroy())
_.each(Game.creeps,c=>c.suicide())
Memory={}
for(;;);
- https://screeps.slack.com/files/U1UGRTKH9/F3Y6N55UL/Fancy_rickroll.js
- How do you deal with the following attempt at duplicating credits?
- Create a contract worth most of your credits
- Allow two of your allies to complete the contract in the same tick.
My advice for coding normal contracts:
- Be very defensive. Check all the things eg. expected body parts.
- Avoid perverse incentives. Eg. For each enemy spawn attacked...
My advice for screeps' devs:
- Focus on transparency. I want to see other people's comments on contracts. It can highlight malicious code and also provide feedback to people still learning JavaScript.
- Set a policy for what happens when someone comes crying that they lost their stuff.
My overall opinion on this feature:
- Fun
- Dangerous
- I hope more people get to experience trade as glorious as W4S3
- The coder tries to get the most value before
-
@domnomnom said in Discussion: Contract system:
My main concern are the security implications:
I don't see this example as a problem... the guy accepting the contract is responsible for checking the code. There are already many libraries available people are using without really checking the code .. snippets from slack and stuff like the. If someone lose their stuff it's their own fault. Maybe there should be a minimal GCL of 5 for example to be able to accept contracts.. and they have to click away some warning on the first use.
I'm more concerned about
eval
for example to inject code remotely .. by updating using a public memory segment for example.
-
Firstly, I really hope this can be fully automated. If not, I'll be very sad.
IMO this begs for a library to sit on top of it. If there's a "standardized" list of contracts then it becomes easier to value a contract based on difficulty:reward, and automatically accept contracts that you're able to do, or offer contracts out that you need doing. It also helps with the security concern: a standardized library can be checked char-for-char against what you're sent.
I suspect my main use for this would be room control. "For every tick you l let me remote-harvest this room I give you 0.001 credits.", or maybe "This is our border line, while any creep is across it you pay 1 credit/tick".
Trading and suchlike seems to be better handled by terminals.
-
Will we be able to provide parameters to a contract, sort of like environment variables? This can be used to use the same code but targeted at different rooms, ticks or players. Otherwise we would have to modify the code and/or use string modification for each contract which seems kind of bad.
In the example above, both
sourceId
anddropPosition
would be provided with these parameters instead of putting them directly into the code.
-
- I guess the contracted screeps will still be owned by the contractor .. so in safe mode for example they can't work?
That's correct.
- there is no way to communicate or send data to the external script running in another players account while it runs? (except probably with using the terminal to send data)
Correct. You can only use existing game mechanics. (Another possible option is to use creep public say.)
- many players use safeguards for ticks that already have a very high cpu count because of a GC for example to stop all execution for the current tick to prevent a reset... will it be possible to suppress the execution of a contract for a tick? I guess it won't be possible to negotiate a max cpu for the contract and do something like a mini reset when it is reached?
When you accept the contract, you're now obliged to execute the contract code. You cannot pause it, that would be a violation of the contract terms. So it's now your responsibility to ensure that the contract code is able to execute each tick.
- what does the "automatically provide" in the introduction section mean? you mention a new ui to create offers and send it to other players .. is it also doable by code?
It means that you service is provided by the contract code automatically, not by you. There will be a Contract API capable to view contracts and track their progress, but creating or accepting contracts requires careful code review, and doing that automatically is... too meta.
also a small idea I just got about monitoring .. since the code runs after the players code it won't be easy to monitor it. maybe we could export a function in our main module that works as a wrapper? Or hook functions that are called before and after the external module? Maybe the hook before could return ´true/false´ whether the code should get executed.
I'm not sure I get your idea, why do you need to monitor contracts?
-
- It takes little code to completely screw over a player. Here's my code-golf to do damage in various ways:
Yes, but the other party would never accept a contract with such code. It's in your best interest to provide as cleaner code as possible in your contract when you offer it to someone, with descriptive comments and everything.
- How do you deal with the following attempt at duplicating credits?
- Create a contract worth most of your credits
- Allow two of your allies to complete the contract in the same tick.
The total amount of credits is deducted from the client's balance when the contract starts, in a similar way as buy orders on the market. These reserved credits are then either paid to the contractor or return to the client in case if the contract is cancelled.
-
Firstly, I really hope this can be fully automated. If not, I'll be very sad.
Unfortunately, I believe automatization of such a system is impractical, unrealistic and can barely be done by anyone in Screeps.
IMO this begs for a library to sit on top of it. If there's a "standardized" list of contracts then it becomes easier to value a contract based on difficulty:reward, and automatically accept contracts that you're able to do, or offer contracts out that you need doing. It also helps with the security concern: a standardized library can be checked char-for-char against what you're sent.
Standardized list of contract templates is something that came to my mind as well, but honestly I think that this system will be more flexible and powerful when guided by the community, not by devs. One useful thing that can be done here is a public GitHub repository with popular contract templates, where everyone can send a Pull Request. But doing that in-game would create too much management burden.
-
Will we be able to provide parameters to a contract, sort of like environment variables? This can be used to use the same code but targeted at different rooms, ticks or players. Otherwise we would have to modify the code and/or use string modification for each contract which seems kind of bad.
In the example above, both
sourceId
anddropPosition
would be provided with these parameters instead of putting them directly into the code.What's the added benefit of complicating the system like that? You can re-use someone else's contract code just as easily, if all the parameters are clearly defined in the top of the script as constants.
-
I feel like this is a feature that 5 people will use. Is this building towards something more substantial?
What does the 2018 roadmap look like? Launching power creeps would be cool, though I would settle for reasonable response times on shard0. Right now the web interface is so slow for me it is no longer really fun to tinker with my colonies.
This main map pageload time of 5 seconds is zzzzzzz.
-
@shedletsky This seems a little off-topic here, isn't it? If you believe it's something with the web site itself, not your connection/setup, then you might want to create a separate post in Technical Issues forum.
-
I don't think it is off topic. My feedback on contracts is that while they may be intellectually interesting, I think no one will use them and I would rather the dev team spend its very limited time working on things that either make the game more playable (performance) or more fun (new units/buildings to script).
A better way to implement the same thing contracts are driving at would be to let people buy/sell CPU ticks on the market. Then there would be some liquidity and a marketplace. Without both, this feature is dead on arrival.
My 2c
-
@shedletsky I mean, it is specific performance complaints/bug reports that are off-topic.
This discussion is intended to check whether the community would be interested with such a feature. We didn't start to implement it, and you may surely be right, but let's see what people say.
Buying/selling CPU is a no-go feature since it would immediately create a pay-to-win flavor for many players.
-
@artch To my understanding a contract is a fully isolated module without the ability to require other modules. In order to setup a new contract I would have to create a new module every time (which is impossible for my code to do) or fall back to string concatenation/manipulation - depending on the implementation -, which means the potential loss of IDE support.
-
@postcrafter No, you can require any other modules as usual. It's just your code, nothing special about it.
-
@artch So a contract can consist of multiple modules which will simply run in the context of another player? Even with this functionality, which is awesome by the way, this won't solve the problem of reusing the same code for multiple contracts.
-
I have thought a bit more about the feature and I'm not sure anymore how practical this will be. I think it might be hard to create code that works seamlessly beside other players codebases.
for example spawning creeps... people have different ways to queue creeps to spawn.
When you accept the contract, you're now obliged to execute the contract code. You cannot pause it, that would be a violation of the contract terms. So it's now your responsibility to ensure that the contract code is able to execute each tick.
What if the code malfunctions? maybe not throwing errors, but spawning creeps every tick without moving them because of a wrong target id and blocking spawns.
You can't enforce people to fulfill the contract anyways .. of course you can prevent the user to pause the code .. but you can't stop him to change memory of the contractor creeps, suiciding creeps or other more subtile sabotage like changing prototypes so the script won't work correctly.
The code could also contain a bug that was not recognised in the code review ... maybe it's using a huge amount of cpu under certain circumstances.. then you will be stuck with it ?
-
I have a couple of questions/concerns here:
Terminology: Client=Guy paying $$$, Contractor=Guy doing work.
-
Is the code for a contract proposed by the contractor, or by the client?
-
Is the client able to cancel his contract? If so, does the contractor get paid in any way when the client cancels?
-
If a contractor is locked-in to a contract, and is unable to edit it, what happens if there is a bug that makes the contract unsatisfiable? Is the contractor doomed to waste CPU on a fruitless contract forever? In this case, I doubt that any rational person would ever accept a contract. It would make far more sense to me to allow players to break contracts (potentially with some kind of penalty system, such as credits kept in escrow or similar).
-
What happens if the contractor runs out of CPU on a tick or encounters an error? Is the contract code still executed?
-
What if a contract throws an exception? How is this handled?
-
What happens if a player gets wiped out and needs to respawn? Many of his contracts may no longer be applicable to the new location, and it seems unreasonable to saddle players with obligations that may out-live their empire's lifetime.
-
-
I really like this system- especially the custom part of it. I can see how this could be used for a number of things people have done manually, such as @Bovius paying players to build his art (and he even wrote scripts for them, so this would be a perfect tie in) or the "clear the edge" folks paying people to remove their rooms in specific sectors.
I do think it would be possible to build a system that would also allow completely automated codebases to contribute (although I also agree that there's no way to completely automate this that wouldn't either be burdensome to the game admins or limiting on the community).
You mentioned that a standardized list of contract templates would be more powerful and flexible when guided by the community, but for things to be completely automated there needs to be a way to verify that the code matches what the players expect. I think this can be done by making it so players can publish contract templates that other players can use. Then people can choose to trust a specific players public contracts when used by other players. For example, the
LeagueOfAutomatedNations
account could publish contracts from a repository on github. Players could then be reasonably sure that the contracts on the site that are "written by"LeagueOfAutomatedNations
are what they expect (and the first time it gets abused everyone will stop trusting it and start trusting something else).