Skip to content

Latest commit

 

History

History
82 lines (73 loc) · 19.8 KB

EXECUTION_ORDER.md

File metadata and controls

82 lines (73 loc) · 19.8 KB

SOMAS2020 Simulation Execution Order

This document is intended to help users understand the order in which things happen in the SOMAS2020 Simulation. Hopefully it clears any confusions the reader has and assists in the development of agents

For this document "you" will refer to either the person desiging an agent that takes part in the simulation or the agent itself.

Any function in bold is a client function and something that we expect you to overload.

Initial

Filename Function Description
main.go main Initialises the server with a given config and call the EntryPoint function on the server object to start the game
internal/server/server.go EntryPoint Runs a loop in which each iteration runs a turn of the game, then stores a copy of the state at the end of turn and then finally checks if the simulation can be considered over

Turns

Filename Function Description
internal/server/turn.go runTurn This function encapsulates a single turn of the simulation, what it does is as follows:
  1. Prompts the agents that a new turn has started by calling startOfTurn().
  2. Runs the IIGO, IIFO, and IITO organsisations in runOrgs()
  3. Finally runs the endOfTurn() function to process the actions an agent make take
Once the function exits the gameOver function is called to see if the simulation must halt
internal/server/turn.go gameOver Checks at least one agent is alive and we haven't reached maximum number of turns or seasons.
internal/server/turn.go startOfTurn Iterates over the alive agents and calls the StartOfTurn() function on the agent's object to notify them a turn has started
internal/server/turn.go runOrgs Calls runIIGO(), runIIFO(), runIITO() in this order. A section for each of these organisations can be found below
internal/server/turn.go endOfTurn This function performs the following actions in this order:
  1. Calls IIGOAllocations() which asks the agents how much they would like to take from the CP
  2. Calls runForage() which initiates a foraging session. This prompts the agents to make foraging decisions and returns their foraging profits
  3. Calls IITOEndOfTurn() which currently executes all gift transactions agreed upon in IITO
  4. Calls IIGOTax() which asks the agents how much they would like to contribute to the CP including their tax payment
  5. Calls probeDisaster() to checks if a disaster has occured. If a disaster has occured it notifies the agent as such
  6. Calls deductCostOfLiving() which is fairly self-explanotary
Each of these function will be explained further in the EndOfTurn section below

IIGO

All IIGO communications can be received by islands through the ReceiveCommunication function in baseclient.

Filename Function Description
internal/server/iigo.go runIIGO Updates the alive islands variables in the rules. Then runs RunIIGO but in the iigointernal package
internal/server/iigointernal/orchestration.go RunIIGO Calls GetClientROLEPointer() (ROLE = Speaker, Judge and President) to initialise the legislative, judicial and executive branches with the client Speaker, Judge and President objects and then orchestrates the IIGO session.
internal/server/iigointernal/judiciary.go loadSanctionConfig Calls GetRuleViolationSeverity() and GetSanctionThresholds() on the island holding the role of Judge and broadcasts this information to all islands.
internal/server/iigointernal/judiciary.go inspectHistory Calls InspectHistory on the island holding the role of Judge. If the island chooses to do this action (returns success = true) sanctions are applied to islands that are found to be in violation of the rules. The sanction tier of islands breaking the rules is broadcasted to all islands. The penalty is sent only to the island who broke the rule.
internal/server/iigointernal/monitoring.go monitorRole The President island has the option to monitor the Judge using MonitorIIGORole() and then optionally broadcast the result to all the islands using DecideIIGOMonitoringAnnouncement().
internal/server/iigointernal/orchestration.go RunIIGO Calls ResourceReport() on each island to get each island's self reported resources. This is passed to the island holding the role of President in the function SetTaxationAmount where the President decides a tax for each island.
internal/server/iigointernal/executive.go broadcastTaxation Sends a message to each island with their tax (minimum contirbution) to be put into the common pool.
internal/server/iigointernal/executive.go requestAllocationRequest Calls CommonPoolResourceRequest() on each island to get every islands request of resources from the common pool. This is passed to the island holding the role of President in the function EvaluateAllocationRequests where the President decides an allocation for each island.
internal/server/iigointernal/executive.go replyAllocationRequest A message is sent to each island containing the President's decided allocation (the amount they are permitted to take from the common pool).
internal/server/iigointernal/executive.go requestRuleProposal RuleProposal is called on every island to get a rule proposal to vote on. This list of rule proposals is passed to the island holding the role of President in the function PickRuleToVote where the President picks a rule for the Speaker to hold a vote on.
internal/server/iigointernal/monitoring.go monitorRole The Speaker island has the option to monitor the President using MonitorIIGORole() and then optionally broadcast the result to all the islands using DecideIIGOMonitoringAnnouncement().
internal/server/iigointernal/legislature.go setRuleToVote This calls the function DecideAgenda on the island holding the role of Speaker where the island can decide to vote on the rule the President chose, or a different rule.
internal/server/iigointernal/legislature.go setVotingResult This calls the function DecideVote on the island holding the role of Speaker to set which islands are allowed to vote. Through the voting object this calls GetVoteForRule on each island to get a vote in favour/against the proposed rule.
internal/server/iigointernal/legislature.go announceVotingResult This calls the function DecideAnnouncement on the island holding the role of Speaker to decide the result of the vote and whether to broadcast this result to the islands. This also updates the ruleset depending on the result decided by the Speaker.
internal/server/iigointernal/monitoring.go monitorRole The Judge island has the option to monitor the Speaker using MonitorIIGORole() and then optionally broadcast the result to all the islands using DecideIIGOMonitoringAnnouncement().
internal/server/iigointernal/orchestration.go RunIIGO Calls PayROLE (ROLE = Speaker, President, Judge) on the islands holding the role of Speaker, President and Judge to decide the amount that the ROLE should get as a reward for doing their job.
internal/server/iigointernal/legislature.go appointNextJudge This calls the CallJudgeElection function on the island holding the role of Speaker to decide whether to hold an election for a new Judge. If an election is held GetVoteForElection is called on every island.
internal/server/iigointernal/executive.go appointNextSpeaker This calls the CallSpeakerElection function on the island holding the role of President to decide whether to hold an election for a new President. If an election is held GetVoteForElection is called on every island.
internal/server/iigointernal/judiciary.go appointNextPresident This calls the CallPresidentElection function on the island holding the role of Judge to decide whether to hold an election for a new President. If an election is held GetVoteForElection is called on every island.

IIFO

Filename Function Description
internal/server/iifo.go runIIFO
  1. Calls runPredictionSession() which prompts agents to share disaster prediction information if they wish to
  2. Calls runForageSharing() which allows agents to share foraging information if they wish to
The structs refernced below can be found in internal/common/shared/foraging.go and internal/common/shared/predictions.go
internal/server/iifo.go runPredictionSession
  1. Calls getPredictions() to get the predictions from each agents
  2. Calls distributePredictions() to then send those predictions to the intended agents
internal/server/iifo.go getPredictions Asks each alive agent to compile a DisasterPredictionInfo struct, which contains an agents guess at when, where and how bad the next disaster will be, by calling the MakeDisasterPrediction() on the agent.
  • The struct also contains a confidence level allowing you to indicate how confident you are in this prediciton and a list of ClientID's indicating who you wish to share this prediction with.
  • You are under no obligation to be truthful with the returned data
internal/server/iifo.go distributePredictions Using the predictions compiled in getPredictions() this function then compiles a map for each agent with the key being which agent created this prediction and the value being the prediction information. The respective map is then passed onto each agent by calling the ReceiveDisasterPredictions(), in this function you are free to do anything with the map.
internal/server/iifo.go runForageSharing This function works very similarly to the runPredictionSession() function.
  1. Calls getForageSharing() to get the foraging info from each agents
  2. Calls distributeForageSharing() to then send the information to the intended agents
internal/server/iifo.go getForageSharing Askes each alive agent to compile a ForagingShareInfo struct which contains information about the agents foraging attempt last turn. This is done by calling MakeForageInfo() on each agent.
  • The ForagingShareInfo contains the decisions you made to forage, how many resources you got out(ideally total and not net profit but this isn't enforced), and a list representing the agents you wish to share this information with
  • You are under no obligation to be truthful about the data in the returned struct
  • If you do not wish to share any data, just return an empty struct
internal/server/iifo.go distributeForageSharing Similar to distributePredictions this function compiles a map for each agent containing the forage information that other agents have decided to share with it. Once again the key in this map represents who created this info, and the data is the foraging information they have created. The function ReceiveForageInfo() is called on each agent and the map intended for them is passed in.

IITO

Filename Function Description
internal/server/iito.go runIITO Currently IITO runs a gift session where agents may make agreements with each other to gift resources. runGiftSession() is called and the agreements are stored in the game state to be later executed in runIITOEndOfTurn()
  • Just to make sure this is understood. Any agreements made in runIITO() do not affect your resources as soon as the deal is accepted. Once in runIITOEndOfTurn() you will be prompted to complete your agreement and resources will be taken from or given to you
internal/server/iito.go runGiftSession runGiftSession has 4 steps taken in this order:
  1. getGiftRequests(): Allows agents to request gifts from other agents
  2. getGiftOffers(): Takes in the requests as input. Asks each agent who they wish to offer a gift to and the amount
  3. getGiftResponses(): Notifies any agents of gift offers towards them and prompts them to respond to the offers.
  4. distributeGiftHistory(): Updates any agent who offered a gift about the response of the recipient.
internal/server/iito.go getGiftRequests Asks each alive agent if to compile a GiftRequestDict object. This agent is prompted to do this by having the GetGiftRequests() called on them and the return should be this map. They key for this map must be the ID of the agent you wish to request a gift from, and the value is the amount you want.
internal/server/iito.go getGiftOffers Ask each alive agent to create a GiftOfferDict object by calling the GetGiftOffers() function on the agent.
  • When this function is called on you, you will be supplied a map of requests to you, where the key is the ID of the agent requsting the gift and the value is the amount they want.
  • You must return a GiftOfferDict map where the the key represents the ID of the agent you wish to the gift to and the value is the amount you wish to give
  • You are under no obligation to use the list of requests passed to you
  • When making offers take care not to offer more than the current amount of resources you have, if you do the server will remove offers until the total amount is brought below your current resource count
internal/server/iito.go getGiftResponses Pass all offers made to an agent by calling the GetGiftResponses() on the agent.
  • When this function is called you will be passed a map, where the key contains the ID of the agent offering you a gift and the value is the amount they wish to give you.
  • You must return a GiftResponseDict object which is a map where the key is the ID of the agent whose offer you wish to repond to and the value is a struct containing a reason and the amount you wish to accept.
  • The reason field is an enum and represents why you made the decision you did, you can either Accept, Decline because you dont need the gift, or Decline because you do not want a gift from that agent. You can find the enum in internal/common/shared/gifts.go.
  • You can accept any amount up to the offered value. You cannot take more than what is offered the server will simply reduce it to offered amount. If you reject an offer set this field to 0.
  • Any offer you fail to respond to will be marked as ignored by the server
internal/server/iito.go distributeGiftHistory This function calls UpdateGiftInfo() on all alive agents and informs on whether or not any offers they made were accepted, rejected or ignored. When this function is called on you, you will be passed a map where the key represents the ID of the agent who responded to your offer and the value is a struct containing the reason for their decision and the amount they have accepted.
  • You are not obligated to do anything with this map
internal/server/iito.go executeResources This function is where the exchange of resources actually happens.
  1. The server goes through every accepted offer and asks the amount of resources the offering agent wants to give by calling DecideGiftAmount() on the agent. For this function call you are told which team you will be sending resources to and the amount they accepted.
  2. The server then attempts to take the resources from you and if it succeeds it prompts you by calling SentGift(). It also prompts the reciever that the resources have been added to their pool by calling ReceivedGift()
  3. In the SentGift() & ReceivedGift() function you are meant use the ServerReadHandle to get the exact amount of resources you have, while the inputs to function merely tell you the resources lost/gained from that transaction.

End of Turn

Filename Function Description
internal/server/iigo.go runIIGOAllocations Asks all alive agents how much they wish to take from the CP by calling RequestAllocation() on them. The return of this should just a number representing how much you want to take. If there isn't enough if the common pool to fulfull your request nothing happens.
  • The amount you are meant to take here should be equal to the allocation given to you by the president. However this only holds if you wish to follow the rules. You may take as much as you want with the reprucussions being the judge sanctioning you.
  • If the request is successful, currently there is no function to notify you of this. The next best option is to check your resources using the ServerReadHandle in DecideForage() which should be the next function called on your client.
internal/server/forage.go runForage In this function all alive clients are asked to make a foraging decision by having DecideForage() called on them. The return of this function should be a ForagingDecision struct which contains the type of foraging you want to do and how much you wish to invest. Once all decisions are collected some maths is done and then ForageUpdate() is called on all the agents tell them how much they have recieved from foraging. This function also provides you with the decision you made in DecideForage().
  • If you input 0 resources in foraging ForageUpdate() will not be called on you.
internal/server/iito.go runIITOEndOfTurn This function called executeTransactions() which is explained in the IITO section above.
internal/server/iigo.go runIIGOTax Asks all alive agents how much they wish to contribute to the common pool.
  • GetTaxContribution() will be called on all agents and the amount returned will be how many resources are given from that agent to the common pool. Note that this says tax because the contribution should also include, but not be limited to, the amount of tax you need to pay as issued by the President in IIGO.
  • GetSanctionPayment() is also called on the agent here to determine how much you need to pay for sanction //TODO: Why do you need to pay for actions? Ask neelesh he is charge of them.
  • The server will attempt to take the resources from you if you have enough it will deduct them and then the function TaxTaken() will be called on you notifying that the resources have been taken.
  • The server then tries to take the resources you gave for GetSanctionPayment() however no update function has been implemented to notify the client.
  • In the future there will be two opportunities to contribute the the CP, one for tax and another for general contributions. However when it comes to paying Tax to follow the rules you must use GetTaxContribution(),
internal/server/turn.go probeDisaster Checks if a disaster has occured this turn. Should be noted currently in main disasters do not take away any resources however that will be changed soon.
internal/server/turn.go incrementTurnAndSeason The turn counter is incremented and if a disaster has happened the season counter is also incremented
internal/server/turn.go notifyClientsOfDisaster If a disaster has happened all alive agents are notified through the DisasterNotification() function being called on them. In this disaster you are given a copy of the disaster report and how much of an effect it had on you. Note: this effect will not be reflected in the game state as of yet.
internal/server/turn.go deductCostOfLiving Here the server deducts the "cost of living" from all agents, currently this a static value set by the config. You are not notified of this during this function, but the next agent function call would be StartOfTurn(). In here you can check you're amount of resources. However, potentially you may be dead before that.
internal/server/turn.go updateIslandLivingStatus Here the server checks if any agents must have their life status changed. You start at Alive, and if you fall below the critical threshold for resources, which is a game config parameter, you are moved into Critical. If you stay in Critical for a number turns equal to the parameter "MaxCriticalConsecutiveTurns" in the config you are considered Dead. You are not notified of the status change but you may check your status by using the ServerReadHandle the next time a function is called on you which is StartOfTurn()