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.
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 |
Filename | Function | Description |
---|---|---|
internal/server/turn.go | runTurn | This function encapsulates a single turn of the simulation, what it does is as follows:
|
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:
|
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. |
Filename | Function | Description |
---|---|---|
internal/server/iifo.go | runIIFO |
|
internal/server/iifo.go | runPredictionSession |
|
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.
|
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.
|
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.
|
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. |
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()
|
internal/server/iito.go | runGiftSession | runGiftSession has 4 steps taken in this order:
|
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.
|
internal/server/iito.go | getGiftResponses | Pass all offers made to an agent by calling the GetGiftResponses() on the agent.
|
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.
|
internal/server/iito.go | executeResources | This function is where the exchange of resources actually happens.
|
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.
|
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().
|
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.
|
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() |