Chronos - mapto/sprks GitHub Wiki
Introduction
Chronos is the mechanism which governs gameplay-related communications between the server and the client. Instead of being turn-based, this mechanism is designed to allow the user to perceive the game in real-time, while handling the data transmission and synchronization in the background. Its primary implementation is through its exposure as a REST API.
Assuming that the game starts on 6th Jan 2014 (first Monday of 2014), by default, when the user commits the policies and presses play, the server will return the risk metrics and based on the probabilities calculated, devise a calendar until the end of the month. This calendar will then be stored in a journal on the server and pushed to the client. The calendar will then be parsed through, such that the client can progress game time at their own pace. Fast forwarding simulation time would simply mean that the client parses through the calendar at a faster rate, since the actual execution of the simulation is completely decoupled from the computation. If, at any point, the user pauses the game to review and change his policies, the same process occurs, except that the server will only compute the calendar for the remaining days of the month.
Sync
This is an opportunity for the client to update any changed policies they may have, their current progressed date, and for the server to recompute (if required) the scores, risks, and costs etc. There are typically 3 types of syncs:
- Monthly Syncs occur at the end of the month, and simulate an organization's monthly reviews of policies. At the end of every month in the game, the user is obliged to review (and update) their policy. From a technical perspective, this guarantees a minimum frequency which a sync occurs.
- Event Syncs occur whenever the user encounters an event which will have an impact on the risk.
- Data Syncs are user triggered on certain actions (such as login/out). Its purpose is to tell the server the current in-game date of the client, which the server compares (or appends as appropriate) to its own records, and to notify the client the correct date which the server has previously tracked the client on.
A sync typically comprises of a number of actions which it can perform:
- Sync History - notify the server of the date which the client has progressed to, so the certain events can be marked as occurred.
- Update Policies - update the database to store new policies. This should typically only be done at the end of the month.
- Prophesize - generate a new calendar of events based on the current policy and events, and write to journal.
- Sync Prophecy - download a calendar of events (from the journal) to the client for the remainder of the month.
Action\Sync Type | Monthly | Event | Data |
---|---|---|---|
Sync History | X | X | X |
Update Policies | X | ||
Prophesize | X | X | |
Sync Prophecy | X | X | Optional |
A special case is at the end of the month (technically 0000h of the first day of the next month), if the client has to submit both new event and new policy data. The server should reflect this, by reading the journal of events and checking for the days in the month, and look for both new policy and event data.
Calendar
This method allows the calendar to store events based on multiple risk dimensions. A sample data set (computed by server based on calculated risks) would therefore be as follows:
| Cracked Password | Stolen Password | Virus Outbreak | Physical Intrusion --- | --- | --- | --- | --- 1st Jan | 2nd Jan | Office worker password cracked. No financial loss. 3rd Jan | | Low level employee spotted stealing password. Was promptly fired. | Technician's laptop infected with virus. 4th Jan | | | 5 computers infected. £400 required to remove virus. 5th Jan | | | 2 computers infected by USB key. £300 required to remove virus. 6th Jan | | | | Man spotted tailgating. Senior management orders review. 7th-31st | ... | ... | ... | ...
This method allows a maximum of 31 days in the calendar (since at the end of the month, the client has to complete a sync to continue). It also allows an unrestricted number of risk dimensions (types), potentially a substantial amount more than the 4 risks in the example above. Each risk type can have an unrestricted number events happening per day, though this may be restricted on the server side.
Incidents
see also Events
An incident is an event that is not driven by the user. Incident events have a statically defined component that contains textual context that cannot be generated/randomized by the server. In the context of this specification, an instance of an incident (an occurrence for a user) is called an event. For convenience in this text with incidents will be referred the static description of the event. At the start of the game, a list of all possible incidents will be loaded to the client side. Whenever new calendar is loaded, only the IDs of the incidents need to be noted, along with any variable/randomization factor.
The method of storage of an incident is exemplified by two incidents (check demonstrator-1july branch):
It's attribute definition is (roughly) as follows:
- id
- This is primarily to identify the incident so it can be referenced when making the AJAX call to fetch new events.
- name (description)
- This is a textual description of the event, e.g. the_building_burnt_down
- cost
- This is the cost that can be incurred.
- it can return either a number (constant) or a compound object a distribution function for possible costs (e.g. normal, described by mean and deviation; and flat, described by min/max).
- type (risk type)
- This is the associated risk type which caused the event. This could potentially change in the future, to take into account multiple risk factors. However this currently involves just one risk, e.g. 'risk of fire'.
- other content (see definition in links above)
The purpose of the cost distribution function is to provide some variability in the costs that can arise from events. The controller will calculate a value within this range e.g. if min_cost was £5m and max_cost was £10m, then the final cost (at computation time) could be £7m, the building requiring £7m to be rebuilt (for this event). Variation is a topic of research for all of the following:
- game studies (http://www.citeulike.org/user/mapto/article/7043187)
- usability (http://www.citeulike.org/user/mapto/article/7529810)
- educational studies (http://www.citeulike.org/user/mapto/article/8067991, http://www.citeulike.org/user/mapto/article/7756882, http://www.citeulike.org/user/mapto/article/7529827)
It provides a more realistic aspect within the game, modeling the fact that similar real life events may not always have the same monetary cost/impact (e.g. the losses due to different fires will not incur the same losses).
Sync History
This process first involves a single request noting the current date that the client has progressed to, the costs that should have been incurred since the last sync point. This will be matched to a particular point in the server journal, so the server can identify which days have elapsed and can be committed permanently to the history timeline.
User ID | Date | Incident ID | Cost |
---|---|---|---|
1 | 2014-02-01 | 2 | 5000 |
1 | 2014-02-06 | 5 | 3000 |
1 | 2014-02-08 | 4 | 400 |
In this example of the journal table, the client may send a JSON string as in the sample request below. The server then looks for all the dates up to but not including the date specified. While the events in the database are assumed to occur in the middle of the day, dates always specify 00:00h when it refers to a moment in time.
Where discrepancies occur, all values on the server journal take precedence. Such rows are then 'made permanent', either by modifying a flag or moving to separate table. The remaining rows are deleted.
The data read from the journal will determine which type of sync it is. For example, if the submitted date matches a date in the journal with events, the server will look for intervention data in the JSON object. Similarly, if the date is the first day of the month, the server will look for new policy data. If intervention data isn't found, the server will return an error message and notify the client to move back one day (to allow the game to run through the event and interventions again). If policy is absent, the server assumes that the policy hasn't changed. In cases where policy/intervention data are submitted but not required, they are ignored by the server.
To allow the client to just synchronize the history (without returning the calendar), an optional flag can be set as in the sample below, such that the new calendar will not be generated and included in the JSON response. If this flag is not explicitly defined, it is assumed to be false, i.e. the calendar will be returned by default.
Partial Sample
{
...
'date': '2014-02-08',
...
}
Calendar (Prophecy) Generation
The client's policies configuration are kept in sync with the server by a different mechanism, triggered whenever he changes its settings. Hence to compute the dates, the server only needs to fetch the most recent policy configuration for the user from the database to compute the upcoming calendar.
Although this area of the internals are yet to be finalized, the current model for calendar generation is as follows:
- For each risk type, the controller sends a request to the simulation with the risk type as parameter.
- For that risk type, the simulation will then return an array (currently of size one, but potentially more; it should also be able to handle empty arrays) of type Incident. This will contain specifications for the incident, as outlined above, including the max and min costs, as well as the incident's computed probability for the given policy settings. Note that each incident can only be caused by one risk type; there are currently no plans to account for multiple risk factors for each incident. In case similar incidents are caused by different risks, they will be described differently (e.g. intrusion caused by cracked password vs intrusion caused by unsecured ports).
- With the aid of a random number, the generator will then loop through the remaining days of the month, and determine whether or not each incident will occur on each day based on the probability. We assume that each day takes the form of a Bernoulli experiment for each incident, the probability is fixed, and each day is independent from each other. The result will be similar to the table shown above in the Calendar section.
- Also with the aid of a random number, the associated cost of each event will be determined, with upper and lower bounds at the predefined max_cost and min_cost values.
- This table will then be encoded and stored in the journal table, with a copy sent to the client in a similar fashion to the sample below.
On eventless dates, the JSON will either include an object with an empty 'events' array (may contain other attributes), or the absence of an object for that they altogether. Consumers of this API are expected to be able to handle both cases.
The JSON response will contain recent history within the calendar (i.e. dates and events in the past and future). This is used to assist with the synchronization on the client side, ensuring that all recent events are kept track of, and to allow error recovery, such as when time has not elapsed properly, and certain intervention choices were not made. It contains all events that's occurred in that same month. After a sync at the end of a month, it's assumed that the time has passed to 00:00h of the first day of the new month, hence this array should be empty.
A 'date' attribute will also be returned, to maintain synchronization. This should be the same value as what was sent to the server to initiate the sync in the first place. If it is different from the original request value, the client should set the game clock to the returned date.
'policyAccept' and 'eventAccept' are used to denote whether a policy or event update was written to the database.
Partial Sample
{
...
'date': 'YYYY-MM-DD',
'policyAccept': true,
'eventAccept': true,
'calendar': [
...
],
...
}