Advertisement
Guest User

Untitled

a guest
Apr 2nd, 2020
465
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 17.40 KB | None | 0 0
  1. Social Gaming Platform
  2. This semester, you will create a platform for developing social games that can be played amongst friends or strangers. Your focus is on creating the engine that allows users to easily and simply develop social games that are highly customizable. Those of you familiar with video game collections like the Jackbox Party Pack or social games like Coup, Werewolf, Loveletter, or Citadels will already be acquainted with the basic idea.
  3.  
  4. You will create a game server that can be configured by the person running the server to allow games to be played. The configuration of the server will be specified in JSON. Similarly, the specification for a single game will be in JSON. A game specification will define the state that a game must maintain as well as the rules of the game. You may think of the specifications as being written in a domain specific programming language that your game server will interpret.
  5.  
  6. When a user connects to the game server, they may either join a game or create a new game amongst those served. When a new game is created, it may be configured by the creating player, who is designated as the “owner” of the game session and will have admin controls over the game. The owner may configure the game and create it, after which they will receive an “invite code”. Other players connecting to the game server may join the game by specifying the invite code. Note, the owner of the game is not a player. If they wish to play the game, they must also join.
  7.  
  8. You may imagine that a typical session works as follows. Several friends get together and decide to play a game. One person connects to the game server via their computer and configures and then starts the game. The game runs on that main computer, with the primary screen observable by all players. Separately, each player may log into the server and join the game on their phones. Each individual player can interact with the game solely through their phones. Any player specific instructions or actions will be sent to specific players on their phones, while any global information will be displayed to all players on the main game screen.
  9.  
  10. To start, this is all you are given. More details on the exact nature of, e.g., the domain specific language for specifying games and other details will be provided over time. Some will be provided sooner, some will be provided later. All may even be incorrect.
  11.  
  12. Implementation Constraints
  13. The core project including all business logic will run on a server and be written in C++. Users will be able to access the system via web applications that present a simple interactive view. One example of a simple chat room that already provides this behavior has been provided for you. Following this design, matters of presentation are handled on the client. You may be asked to contruct another (different) client as a requirement.
  14.  
  15. Does this page define your project requirements?
  16. In short, no. This page provides initial directions that should be helpful in planning the first iteration.
  17.  
  18. The description of the project as presented here is incomplete. It is not intended to be complete. In fact, it may not even be correct or stable. You should expect the requirements of the project to be flexible and change over time as you interact with the customer. If there are deficiencies in your design, your requirements may even change to make the deficiencies hurt more.
  19.  
  20. Remember that you should iterate toward a solution, demonstrating your progress and asking for concrete feedback about current behavior of the system and desired behavior of the system. In order to do that, you always need a running system. Make that a priority. You can also identify core abstract behaviors and design your system such that concrete changes can be made with marginal burden.
  21.  
  22. Game Specification Structure
  23. A game specification is defined in a standard JSON formatted file. The top level will always be a map containing six elements that define the general configuration of the game, the constant data used by the game, the global variable state of the game, per player state, per audience member state, and the actual rules of the game. Thus, the simplest possible valid game specification is:
  24.  
  25. {
  26. "configuration": {
  27. "name": "Zen Game",
  28. "player count": {"min": 0, "max": 0},
  29. "audience": false,
  30. "setup": { }
  31. },
  32. "constants": {},
  33. "variables": {},
  34. "per-player": {},
  35. "per-audience": {},
  36. "rules": {}
  37. }
  38. This defines a game with no players, no audience, no state, and no rules that does nothing. The configuration contains enough information that the game could be selected and started by a game owner, and it would promptly end.
  39.  
  40. Configuration
  41. The configuration of a game controls general settings that may assist in game creation and game management for the owner. This includes such things as (1) the name of the game type to show when selecting the type of game to create (2) specifying any data that may be uploaded by the owner, e.g. for quiz based games, (3) specifying minima and maxima for the number of players, and (4) specifying whether additional game joiners beyond the players can participate as audience members.
  42.  
  43. "setup" names a map of settings that can or must be configured by the owner of the game upon game creation. This can include such things as the numbers specifying the number of rounds to play. If the value for a setting is an integer, boolean, or string literal then that value constitutes the default value. These need not be changed by the owner upon creation but can be. Otherwise, the value must be a map of the form:
  44.  
  45. {
  46. "kind": <<data kind>>,
  47. "prompt": <<Description of what data the owner should provide>>
  48. }
  49. Here "kind" may map to "integer", "string", "boolean", "question-answer", "multiple-choice". The latter two indicate JSON file formats whose data can be uploaded by the game owner upon creation.
  50.  
  51. Constants, Variables, Players, and the Audience
  52. The constants, variables, per-player, and per-audience sections define state that may be accessed by the game rules during play. The constants and variables sections contain maps from names to values. The per-player and per-audience sections define maps that exist for each player of a game and each audience member. Top level names must be unique. Values may themselves be (1) maps from names to values, (2) lists of values, or (3) literal strings, numbers, or booleans. New top level names/keys within these sections cannot be added by rules. They must be predetermined within the specification.
  53.  
  54. Note that some additional forms of game state must be accessible via rules, as well. In particular, the "players" name specifies a list of the player data maps, and the "audience" name specifies a list of audience data maps. Every player map also implicitly has a "name" key that maps to the unique name that the player selected upon joining the game.
  55.  
  56. Rules
  57. Most of the actual game behavior is controlled by the rules section and the semantics of the rules therein. Essentially, these rules define a custom embedded domain specific language for actions that may be taken within a game. Note that it may be possible to validate some basic correctness properties of rules. These rules are subject to change and will be refined via discussion. They do, however, provide an appropriate jumping off point for planning and designing a good solution.
  58.  
  59. Each individual rule is a map of attributes describing the rule. Lists of rules define a sequence of operations in which each rule must be performed in sequential order. Note that apparent parallelism will exist, but no use of explicit parallelism or threads is required as a part of this project. The different forms of rules are explored within the remaining sections of this document.
  60.  
  61. Control Structures
  62. Control structures determine when and how different groups of instructions may execute. This includes concepts like sequencing, branching, and parallelism. Note that parallelism in this project is only from the perspective of the players. No parallel control structures actually require hardware level parallelism in software design or concurrency level primitives like threads.
  63.  
  64. Foreach
  65. { "rule": "foreach",
  66. "list": <<list, list expression, or name of a list object>>,
  67. "element": << name for list element object within the rules below >>
  68. "rules": [
  69. << Rules to execute on every element of the given list >>
  70. ]
  71. }
  72. Loop
  73. { "rule": "loop",
  74.  
  75. "until": << Condition that may fail >>,
  76. OR
  77. "while": << Condition that may fail >>,
  78.  
  79. "rules": [
  80. << Rules to execute on every element of the given list >>
  81. ]
  82. }
  83. Inparallel
  84. { "rule": "inparallel",
  85. "rules": [
  86. << Rules to execute *in parallel* rather than *in sequence* >>
  87. ]
  88. }
  89. Note that this creates the potential for bugs even in a single threaded scenario depending on your design. It may be refined in the future.
  90.  
  91. Parallelfor
  92. { "rule": "parallelfor",
  93. "list": <<name of a list object>>,
  94. "element": << name for list element object within the rules below >>,
  95. "rules": [
  96. << Rules to execute on every element of the given list. The list is executed sequentially, but each element is processed "in parallel">>
  97. ]
  98. }
  99. Switch
  100. { "rule": "switch",
  101. "value": << value to switch upon >>,
  102. "list": << name of a constant list of allowable values >>,
  103. "cases": [
  104. { "case": << value >>, "rules": [ << Rules to execute when the value and case match >> ] },
  105. ...
  106. ]
  107. }
  108. When
  109. A when construct is analogous to if-then-else. The first case with a condition that evaluates to true has its rule list evaluated.
  110.  
  111. { "rule": "when",
  112. "cases": [
  113. { "condition": << Boolean guard for rules >>,
  114. "rules": [ << Rules to execute when the value and case match >> ]
  115. },
  116. ...
  117. ]
  118. }
  119. List Operations
  120. Extend
  121. { "rule": "extend",
  122. "target": << variable name of a list to extend with another list >>
  123. "list": << either an immediate list or a name of a constant variable or list >>
  124. }
  125. Reverse
  126. { "rule": "reverse",
  127. "list": << variable name of a list to reverse >>
  128. }
  129. Shuffle
  130. { "rule": "shuffle",
  131. "list": << variable name of a list to shuffle >>
  132. }
  133. Sort
  134. { "rule": "sort",
  135. "list": << variable name of a list to sort >>,
  136.  
  137. OPTIONALLY
  138. "key": << Attribute of list elements to use for comparison.
  139. Only valid when the list contains maps. >>
  140. }
  141. Sorts a list in ascending order
  142.  
  143. Deal
  144. { "rule": "deal",
  145. "from": << variable name of a list to deal from >>,
  146. "to": << variable name of a list or list attribute to deal to >>,
  147. "count": << number of elements to deal >>
  148. }
  149. Discard
  150. { "rule": "discard",
  151. "from": << variable name of a list to discard from >>,
  152. "count": << number of elements to discard >>
  153. }
  154. List Attributes
  155. When given a list name, attributes of a list can be referred to and elements of a list can be sliced to represent new lists. For example, suppose that the following list is defined in the constants:
  156.  
  157. "roles": [
  158. { "name": "Duke", "action": "Tax. The duke may take 3 coins from the treasury."},
  159. { "name": "Assassin", "action": "Assassinate. The assassin may force another player to give up an influence."},
  160. ...
  161. ]
  162. The name of the list is "roles" and can be referred to within the rules. The size of the list may be accessed through the attribute "roles.size". Lists may be implicitly created, as well. If the elements of the list are maps, then the keys of the maps define additional lists. For instance, "roles.elements.name" defines the list of names contained within the above list. Additional useful attributes are "contains" and "collect".
  163.  
  164. Arithmetic Operations
  165. Add
  166. { "rule": "add",
  167. "to": << variable name of an integer to add to >>,
  168. "value": << integer literal or name of a variable or constant containing the value to add >>,
  169. }
  170. Numerical Attributes
  171. Given a number, I can access attributes of the number similar to attributes of a list. For instance, I can treat a number as a list by saying "count.upfrom(1)". That defines the list of numbers 1, 2, …, count.
  172.  
  173. Timing
  174. Timer
  175. { "rule": "timer",
  176. "duration": << seconds >>,
  177. "mode": "exact" OR "at most" OR "track",
  178. "rules": [
  179. << sequence of rules to execute with respect to the timer.
  180. An "at most" timer will stop executing and time out input requests.
  181. An "exact" timer will pad the execution time to the given duration.
  182. A "track" timer will continue executing but set a flag. >>
  183. ],
  184.  
  185. OPTIONAL
  186. "flag": << variable that evaluates to false when a "track" timer has not expired and false afterward. >>
  187. }
  188. Human Input
  189. Input choice
  190. { "rule": "input-choice",
  191. "to": << a single player or audience member >>,
  192. "prompt": << Message to send with request, as in "output" below >>,
  193. "choices": << list or name of a list to choose from >>
  194. "result": << variable name in which to store the response >>
  195.  
  196. OPTIONAL
  197. "timeout": << duration to wait for a response >>
  198. }
  199. This allows the player to make a multiple choice selection.
  200.  
  201. Input text
  202. { "rule": "input-text",
  203. "to": << a single player or audience member >>,
  204. "prompt": << Message to send with request, as in "output" below >>,
  205. "result": << variable name in which to store the response >>
  206.  
  207. OPTIONAL
  208. "timeout": << duration to wait for a response >>
  209. }
  210. Input vote
  211. { "rule": "input-vote",
  212. "to": << a list of players and/or audience members >>,
  213. "prompt": << Message to send with request, as in "output" below >>,
  214. "choices": << list or name of a list to choose from >>
  215. "result": << variable name in which to store a map from choices to vote counts >>
  216.  
  217. OPTIONAL
  218. "timeout": << duration to wait for a response >>
  219. }
  220. Output
  221. Message
  222. { "rule": "message",
  223. "to": << list of recipients or a single player or audience member >>,
  224. "value": << Message to send. Python style {} variable accesses are permitted.
  225. E.g. "Great job, {player.name}!" >>
  226. }
  227. Globalmessage
  228. { "rule": "global-message",
  229. "value": << Message to send. Python style {} variable accesses are permitted.
  230. E.g. "Great job, {player.name}!" >>
  231. }
  232. This sends a message to the main screen of the game instead of any player.
  233.  
  234. Scores
  235. { "rule": "scores",
  236. "score": << Numerical attribute of players to use as score >>,
  237. "ascending": << boolean attribute. True when the scores run from low to high >>
  238. }
  239. Prints a scoareboard on the global display using the given attribute of each player.
  240.  
  241. Scores are sorted ascending or descenfing as specified.
  242.  
  243. Example
  244. This demonstrates a simple rock paper scissors game. It is a good place to aim initially. Several smaller portions capture individual goals that may be risky for each group.
  245.  
  246. {
  247. "configuration": {
  248. "name": "Rock, Paper, Scissors",
  249. "player count": {"min": 2, "max": 4},
  250. "audience": false,
  251. "setup": {
  252. "Rounds": 10
  253. }
  254. },
  255.  
  256. "constants": {
  257. "weapons": [
  258. { "name": "Rock", "beats": "Scissors"},
  259. { "name": "Paper", "beats": "Rock"},
  260. { "name": "Scissors", "beats": "Paper"}
  261. ]
  262. },
  263.  
  264. "variables": {
  265. "winners": []
  266. },
  267.  
  268. "per-player": {
  269. "wins": 0
  270. },
  271.  
  272. "per-audience": {},
  273.  
  274. "rules": [
  275. { "rule": "foreach",
  276. "list": "configuration.Rounds.upfrom(1)",
  277. "element": "round",
  278. "rules": [
  279.  
  280. { "rule": "global-message",
  281. "value": "Round {round}. Choose your weapon!"
  282. },
  283.  
  284. { "rule": "parallelfor",
  285. "list": "players",
  286. "element": "player",
  287. "rules": [
  288.  
  289. { "rule": "input-choice",
  290. "to": "player",
  291. "prompt": "{player.name}, choose your weapon!",
  292. "choices": "weapons.name",
  293. "result": "player.weapon",
  294. "timeout": 10
  295. }
  296.  
  297. ]
  298. },
  299.  
  300. { "rule": "discard",
  301. "from": "winners",
  302. "count": "winners.size"
  303. },
  304.  
  305. { "rule": "foreach",
  306. "list": "weapons",
  307. "element": "weapon",
  308. "rules": [
  309.  
  310. { "rule": "when",
  311. "cases": [
  312. { "condition": "!players.elements.weapon.contains(weapon.name)",
  313. "rules": [
  314.  
  315. { "rule": "extend",
  316. "target": "winners",
  317. "list": "players.elements.collect(player, player.weapon == weapon.beats)"
  318. }
  319.  
  320. ]
  321. }
  322. ]
  323. }
  324.  
  325. ]
  326. },
  327.  
  328. { "rule": "when",
  329. "cases": [
  330. { "condition": "winners.size == players.size",
  331. "rules": [
  332. { "rule": "global-message",
  333. "value": "Tie game!"
  334. }
  335. ]
  336. },
  337. { "condition": "winners.size == 0",
  338. "rules": [
  339. { "rule": "global-message",
  340. "value": "Tie game!"
  341. }
  342. ]
  343. },
  344. { "condition": true,
  345. "rules": [
  346. { "rule": "global-message",
  347. "value": "Winners: {winners.elements.name}"
  348. },
  349. { "rule": "foreach",
  350. "list": "winners",
  351. "element": "winner",
  352. "rules": [
  353. { "rule": "add",
  354. "to": "winner.wins",
  355. "value": 1
  356. }
  357. ]
  358. }
  359. ]
  360. }
  361. ]
  362. }
  363.  
  364. ]
  365. },
  366.  
  367. { "rule": "scores",
  368. "score": "wins",
  369. "ascending": false
  370. }
  371. ]
  372. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement