{"action":"created","comment":{"url":"https://api.github.com/repos/evennia/ainneve/pulls/comments/46097511","id":46097511,"diff_hunk":"@@ -0,0 +1,330 @@\n+\"\"\"\n+Races module.\n+\n+This module contains data and functions relating to Races and Focuses. Its\n+public module functions are to be used primarily during the character\n+creation process.\n+\n+Classes:\n+\n+    `Race`: base class for all races\n+    `Human`: human race class\n+    `Elf`: elf race class\n+    `Dwarf`: dwarf race class\n+    `Focus`: class representing a character's focus; a set of bonuses\n+\n+Module Functions:\n+\n+    - `load_race(str)`:\n+\n+        loads an instance of the named Race class\n+\n+    - `load_focus(str)`:\n+\n+        loads an instance of the named Focus class\n+\n+    - `apply_race(char, race, focus)`:\n+\n+        have a character \"become\" a member of the specified race with\n+        the specified focus\n+\"\"\"\n+\n+from evennia.utils import fill\n+from world.archetypes import Archetype\n+\n+\n+class RaceException(Exception):\n+    \"\"\"Base exception class for races module.\"\"\"\n+    def __init__(self, msg):\n+        self.msg = msg\n+\n+ALL_RACES = ('Human', 'Elf', 'Dwarf')\n+_ALL_FOCI = {\n+    'agility':\n+        {'desc': 'The Agility focus represents an increase in nimbleness, '\n+                 'flexibility, and balance. Characters with the agility '\n+                 'focus have trained their body to become more acrobatic, '\n+                 'and therefore stronger.',\n+         'bonuses':\n+             {'STR': 1, 'DEX': 2, 'REFL': 2}},\n+    'alertness':\n+        {'desc': 'The Alertness focus represents increased senses, awareness, '\n+                 'and insight. Characters with the alertness focus are keenly '\n+                 'aware of their surroundings and possible dangers.',\n+         'bonuses':\n+             {'PER': 2, 'CHA': 1, 'REFL': 2}},  # +2 language\n+    'brawn':\n+        {'desc': 'The Brawn focus is for characters with exceptionally '\n+                 'strong bodies. Constant training has earned characters with '\n+                 'the brawn focus large muscles and great physical power.',\n+         'bonuses':\n+             {'STR': 2, 'VIT': 1, 'FORT': 1}},\n+    'cunning':\n+        {'desc': 'The Cunning focus represents intelligent, clever, and '\n+                 'quick-witted characters. Characters with the cunning focus '\n+                 'are extremely bright and spend much of their time studying '\n+                 'and developing new skills.',\n+         'bonuses':\n+             {'PER': 1, 'INT': 2, 'WILL': 3}},\n+    'prestige':\n+        {'desc': 'The Prestige focus symbolizes characters who are great '\n+                 'speech givers, negotiators, and magnetic personalities. '\n+                 'Characters with the prestige focus can win the hearts and '\n+                 'minds of their peers and pull strings for favors.',\n+         'bonuses':\n+             {'INT': 1, 'CHA': 2}},  # + 3 language\n+    'resilience':\n+        {'desc': 'The Resilience focus is for characters with naturally '\n+                 'strong constitutions and fortitudes. Characters with the '\n+                 'resilience focus tend to have longer life spans and live '\n+                 'healthier lives.',\n+         'bonuses':\n+             {'DEX': 1, 'VIT': 2, 'FORT': 3, 'WILL': 2}},\n+    'spirit': {\n+        'desc': 'The Spirit focus symbolizes an abundance in mystical powers '\n+                'swirling with mana. Characters with the spirit focus are '\n+                'naturally gifted to channelling the magical powers of spells.',\n+        'bonuses':\n+            {'VIT': 1, 'MAG': 2, 'FORT': 1, 'REFL': 1, 'WILL': 1}}  # +2 language\n+}\n+_ARC = Archetype()\n+\n+\n+def load_race(race):\n+    \"\"\"Returns an instance of the named race class.\n+\n+    Args:\n+        race (str): case-insensitive name of race to load\n+\n+    Returns:\n+        (Race): instance of the appropriate subclass of `Race`\n+    \"\"\"\n+    race = race.capitalize()\n+    if race in ALL_RACES:\n+        return globals()[race]()\n+    else:\n+        raise RaceException(\"Invalid race specified.\")\n+\n+\n+def load_focus(focus):\n+    \"\"\"Retrieve an instance of a Focus class.\n+\n+    Args:\n+        focus (str): case insensitive focus class name\n+\n+    Returns:\n+        (Focus): instance of the named Focus\n+    \"\"\"\n+    focus = focus.lower()\n+    if focus in _ALL_FOCI:\n+        return Focus(name=focus, **_ALL_FOCI[focus])\n+    else:\n+        raise RaceException('Invalid Focus name.')\n+\n+\n+def apply_race(char, race, focus):\n+    \"\"\"Causes a Character to \"become\" the named race.\n+\n+    Args:\n+        char (Character): the character object becoming a member of race\n+        race (str, Race): the name of the race to apply, or the\n+        focus (str, Focus): the name of the focus the player has selected\n+    \"\"\"\n+    # if objects are passed in, reload Race and Focus objects\n+    # by name to ensure we have un-modified versions of them\n+    if isinstance(race, Race):\n+        race = race.name\n+\n+    race = load_race(race)\n+\n+    if isinstance(focus, Focus):\n+        focus = focus.name\n+\n+    focus = load_focus(focus)\n+\n+    # make sure the focus is allowed for the race\n+    if focus.name not in (f.name for f in race.foci):\n+        raise RaceException(\n+            'Invalid focus specified. '\n+            'Focus {} not available to race {}.'.format(focus.name, race.name)\n+        )\n+\n+    # set race and related attributes on the character\n+    char.db.race = race.name\n+    char.db.focus = focus.name\n+    char.db.slots = race.slots\n+\n+    # apply race-based bonuses\n+    for trait, bonus in race.bonuses.iteritems():\n+        char.traits[trait].mod += bonus\n+    # apply focus-based bonuses\n+    for trait, bonus in focus.bonuses.iteritems():\n+        char.traits[trait].mod += bonus\n+\n+\n+def _format_bonuses(bonuses):\n+    \"\"\"Formats a dict of bonuses to base traits as a string.\"\"\"\n+    traits = bonuses.keys()\n+    if len(bonuses) > 2:\n+        output = \", \".join(\n+                    \"{{w{:+1}{{n to {{C{}{{n\".format(bonuses[t],\n+                                                     _ARC.traits[t]['name'])\n+                    for t in traits[:-1])\n+        output += \", and {{w{:+1}{{n to {{C{}{{n\".format(\n+                      bonuses[traits[-1]],\n+                      _ARC.traits[traits[-1]]['name'])\n+    else:\n+        output = \" and \".join(\n+                    \"{{w{:+1}{{n to {{C{}{{n\".format(bonuses[t],\n+                                                     _ARC.traits[t]['name'])\n+                    for t in traits)\n+    return output\n+\n+\n+class Race(object):\n+    \"\"\"Base class for race attributes\"\"\"\n+    def __init__(self):\n+        self.name = \"\"\n+        self.plural = \"\"\n+        self.size = \"\"\n+        self._desc = \"\"\n+        self.slots = [\n+            'wield1',\n+            'wield2',\n+            'armor',\n+        ]\n+        self.foci = []\n+        self.bonuses = {}\n+\n+    @property\n+    def desc(self):\n+        \"\"\"Returns a formatted description of the Race.\n+\n+        Note:\n+            The setter for this property only modifies the content\n+            of the first paragraph of what is returned.\n+        \"\"\"\n+        desc = \"{{g{}{{n\\n\".format(self.name)\n+        desc += fill(self._desc)\n+        desc += '\\n\\n'\n+        desc += fill(\"{} have a \".format(self.plural) +\n+                     \"{{y{}{{n body type and can \".format(self.size) +\n+                     \"select a {{wfocus{{n from among {}\".format(\n+                         self._format_focus_list(self.foci)\n+                     ))\n+        if len(self.bonuses) > 0:\n+            desc += '\\n\\n'\n+            desc += fill(\"{} also gain {} of {}\".format(\n+                        self.plural,\n+                        'bonuses' if len(self.bonuses) > 1 else 'a bonus',\n+                        _format_bonuses(self.bonuses))\n+                    )\n+        desc += '\\n\\n'\n+        return desc\n+\n+    @desc.setter\n+    def desc(self, value):\n+        self._desc = value\n+\n+    def _format_focus_list(self, items):\n+        \"\"\"Returns a comma separated list of items with \"or\" before the last.\"\"\"\n+        if len(items) > 2:\n+            output = \", \".join([\"{{b{}{{n\".format(i.name) for i in items[:-1]])\n+            output += \", or {{b{}{{n\".format(items[-1].name)\n+        else:\n+            output = \" or \".join([\"{{b{}{{n\".format(i.name) for i in items])\n+        return output\n+\n+\n+class Focus(object):\n+    \"\"\"Represents a Focus, which is a group of bonuses available to a race.\n+\n+    Args:\n+        name (str): display name for the focus\n+        desc (str): description for the focus\n+        bonuses (dict): bonuses for the focus in {'trait': bonus} format\n+    \"\"\"\n+    def __init__(self, name, desc, bonuses):\n+        self.name = name.capitalize()\n+        self._desc = None\n+        self.desc = desc\n+        self.bonuses = bonuses\n+\n+    @property\n+    def desc(self):\n+        \"\"\"Returns a formatted description of the Focus.\n+\n+        Note:\n+            The setter for this property only modifies the content\n+            of the first paragraph of what is returned.\n+        \"\"\"\n+        desc = \"{{b{}{{n\\n\".format(self.name)\n+        desc += fill(self._desc)\n+        desc += \"\\n\\n\"\n+        desc += fill(\"Adventurers with the {{b{}{{n focus gain {}.\".format(\n+                    self.name,\n+                    _format_bonuses(self.bonuses)\n+                ))\n+        desc += \"\\n\\n\"\n+        return desc\n+\n+    @desc.setter\n+    def desc(self, value):\n+        self._desc = value\n+\n+\n+class Human(Race):\n+    \"\"\"Class representing human attributes.\"\"\"\n+    def __init__(self):\n+        super(Human, self).__init__()\n+        self.name = \"Human\"\n+        self.plural = \"Humans\"\n+        self.size = \"medium\"\n+        self.desc = (\"Humans are the most wide-spread of all the races. The \"","path":"world/races.py","position":283,"original_position":283,"commit_id":"e6539709f20a602815750f374764ef31153abab9","original_commit_id":"e6539709f20a602815750f374764ef31153abab9","user":{"login":"ergodicbreak","id":3825386,"avatar_url":"https://avatars.githubusercontent.com/u/3825386?v=3","gravatar_id":"","url":"https://api.github.com/users/ergodicbreak","html_url":"https://github.com/ergodicbreak","followers_url":"https://api.github.com/users/ergodicbreak/followers","following_url":"https://api.github.com/users/ergodicbreak/following{/other_user}","gists_url":"https://api.github.com/users/ergodicbreak/gists{/gist_id}","starred_url":"https://api.github.com/users/ergodicbreak/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ergodicbreak/subscriptions","organizations_url":"https://api.github.com/users/ergodicbreak/orgs","repos_url":"https://api.github.com/users/ergodicbreak/repos","events_url":"https://api.github.com/users/ergodicbreak/events{/privacy}","received_events_url":"https://api.github.com/users/ergodicbreak/received_events","type":"User","site_admin":false},"body":"wide-spread s/b widespread","created_at":"2015-11-29T20:29:11Z","updated_at":"2015-11-29T20:29:11Z","html_url":"https://github.com/evennia/ainneve/pull/49#discussion_r46097511","pull_request_url":"https://api.github.com/repos/evennia/ainneve/pulls/49","_links":{"self":{"href":"https://api.github.com/repos/evennia/ainneve/pulls/comments/46097511"},"html":{"href":"https://github.com/evennia/ainneve/pull/49#discussion_r46097511"},"pull_request":{"href":"https://api.github.com/repos/evennia/ainneve/pulls/49"}}},"pull_request":{"url":"https://api.github.com/repos/evennia/ainneve/pulls/49","id":52021860,"html_url":"https://github.com/evennia/ainneve/pull/49","diff_url":"https://github.com/evennia/ainneve/pull/49.diff","patch_url":"https://github.com/evennia/ainneve/pull/49.patch","issue_url":"https://api.github.com/repos/evennia/ainneve/issues/49","number":49,"state":"open","locked":false,"title":"Races","user":{"login":"feend78","id":317047,"avatar_url":"https://avatars.githubusercontent.com/u/317047?v=3","gravatar_id":"","url":"https://api.github.com/users/feend78","html_url":"https://github.com/feend78","followers_url":"https://api.github.com/users/feend78/followers","following_url":"https://api.github.com/users/feend78/following{/other_user}","gists_url":"https://api.github.com/users/feend78/gists{/gist_id}","starred_url":"https://api.github.com/users/feend78/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/feend78/subscriptions","organizations_url":"https://api.github.com/users/feend78/orgs","repos_url":"https://api.github.com/users/feend78/repos","events_url":"https://api.github.com/users/feend78/events{/privacy}","received_events_url":"https://api.github.com/users/feend78/received_events","type":"User","site_admin":false},"body":"This PR addresses Issue #32 and fleshes out a bit more of the functionality that will be needed for chargen.\r\n\r\n_Summary of changes:_\r\n\r\n- Created a world/races.py module, replacing the previous deeper package structure\r\n- Removed `become_race` from the `Character` typeclass.\r\n- Replaced it with `apply_race` module function, which applies racial and focus bonuses to the character's traits.\r\n- Filled out Race classes with descriptive text from the OA basic manual.\r\n- Created a `Focus` class and a dict of Focus data used by the `load_focus` factory function.\r\n- Docs and tests\r\n\r\n_Testing_\r\n\r\nTesting this is a little tedious, as this is still just pieces of the chargen toolkit. To see race descriptions:\r\n    \r\n    @py from world.races import load_race; r=load_race('human'); me.msg(r.desc)\r\n\r\nTo see Focus descriptions:\r\n\r\n    @py from world.races import load_focus; f=load_focus('agility'); me.msg(f.desc)\r\n\r\nTo see the effects of assigning a race and focus:\r\n\r\n    # reset any existing traits by calling with reset=True\r\n    @py from world.archetypes import apply_archetype; apply_archetype(me, 'warrior', reset=True)\r\n    sheet\r\n    @py from world.races import apply_race; apply_race(me, 'human', 'agility')\r\n    sheet\r\n","created_at":"2015-11-27T19:58:56Z","updated_at":"2015-11-29T20:29:11Z","closed_at":null,"merged_at":null,"merge_commit_sha":"6c37d22e5053170471cc54632ae9f411d4705a82","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/evennia/ainneve/pulls/49/commits","review_comments_url":"https://api.github.com/repos/evennia/ainneve/pulls/49/comments","review_comment_url":"https://api.github.com/repos/evennia/ainneve/pulls/comments{/number}","comments_url":"https://api.github.com/repos/evennia/ainneve/issues/49/comments","statuses_url":"https://api.github.com/repos/evennia/ainneve/statuses/e6539709f20a602815750f374764ef31153abab9","head":{"label":"feend78:races","ref":"races","sha":"e6539709f20a602815750f374764ef31153abab9","user":{"login":"feend78","id":317047,"avatar_url":"https://avatars.githubusercontent.com/u/317047?v=3","gravatar_id":"","url":"https://api.github.com/users/feend78","html_url":"https://github.com/feend78","followers_url":"https://api.github.com/users/feend78/followers","following_url":"https://api.github.com/users/feend78/following{/other_user}","gists_url":"https://api.github.com/users/feend78/gists{/gist_id}","starred_url":"https://api.github.com/users/feend78/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/feend78/subscriptions","organizations_url":"https://api.github.com/users/feend78/orgs","repos_url":"https://api.github.com/users/feend78/repos","events_url":"https://api.github.com/users/feend78/events{/privacy}","received_events_url":"https://api.github.com/users/feend78/received_events","type":"User","site_admin":false},"repo":{"id":45631652,"name":"ainneve","full_name":"feend78/ainneve","owner":{"login":"feend78","id":317047,"avatar_url":"https://avatars.githubusercontent.com/u/317047?v=3","gravatar_id":"","url":"https://api.github.com/users/feend78","html_url":"https://github.com/feend78","followers_url":"https://api.github.com/users/feend78/followers","following_url":"https://api.github.com/users/feend78/following{/other_user}","gists_url":"https://api.github.com/users/feend78/gists{/gist_id}","starred_url":"https://api.github.com/users/feend78/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/feend78/subscriptions","organizations_url":"https://api.github.com/users/feend78/orgs","repos_url":"https://api.github.com/users/feend78/repos","events_url":"https://api.github.com/users/feend78/events{/privacy}","received_events_url":"https://api.github.com/users/feend78/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/feend78/ainneve","description":"A full example game created in Evennia","fork":true,"url":"https://api.github.com/repos/feend78/ainneve","forks_url":"https://api.github.com/repos/feend78/ainneve/forks","keys_url":"https://api.github.com/repos/feend78/ainneve/keys{/key_id}","collaborators_url":"https://api.github.com/repos/feend78/ainneve/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/feend78/ainneve/teams","hooks_url":"https://api.github.com/repos/feend78/ainneve/hooks","issue_events_url":"https://api.github.com/repos/feend78/ainneve/issues/events{/number}","events_url":"https://api.github.com/repos/feend78/ainneve/events","assignees_url":"https://api.github.com/repos/feend78/ainneve/assignees{/user}","branches_url":"https://api.github.com/repos/feend78/ainneve/branches{/branch}","tags_url":"https://api.github.com/repos/feend78/ainneve/tags","blobs_url":"https://api.github.com/repos/feend78/ainneve/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/feend78/ainneve/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/feend78/ainneve/git/refs{/sha}","trees_url":"https://api.github.com/repos/feend78/ainneve/git/trees{/sha}","statuses_url":"https://api.github.com/repos/feend78/ainneve/statuses/{sha}","languages_url":"https://api.github.com/repos/feend78/ainneve/languages","stargazers_url":"https://api.github.com/repos/feend78/ainneve/stargazers","contributors_url":"https://api.github.com/repos/feend78/ainneve/contributors","subscribers_url":"https://api.github.com/repos/feend78/ainneve/subscribers","subscription_url":"https://api.github.com/repos/feend78/ainneve/subscription","commits_url":"https://api.github.com/repos/feend78/ainneve/commits{/sha}","git_commits_url":"https://api.github.com/repos/feend78/ainneve/git/commits{/sha}","comments_url":"https://api.github.com/repos/feend78/ainneve/comments{/number}","issue_comment_url":"https://api.github.com/repos/feend78/ainneve/issues/comments{/number}","contents_url":"https://api.github.com/repos/feend78/ainneve/contents/{+path}","compare_url":"https://api.github.com/repos/feend78/ainneve/compare/{base}...{head}","merges_url":"https://api.github.com/repos/feend78/ainneve/merges","archive_url":"https://api.github.com/repos/feend78/ainneve/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/feend78/ainneve/downloads","issues_url":"https://api.github.com/repos/feend78/ainneve/issues{/number}","pulls_url":"https://api.github.com/repos/feend78/ainneve/pulls{/number}","milestones_url":"https://api.github.com/repos/feend78/ainneve/milestones{/number}","notifications_url":"https://api.github.com/repos/feend78/ainneve/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/feend78/ainneve/labels{/name}","releases_url":"https://api.github.com/repos/feend78/ainneve/releases{/id}","created_at":"2015-11-05T18:41:38Z","updated_at":"2015-11-06T16:00:30Z","pushed_at":"2015-11-29T06:07:12Z","git_url":"git://github.com/feend78/ainneve.git","ssh_url":"git@github.com:feend78/ainneve.git","clone_url":"https://github.com/feend78/ainneve.git","svn_url":"https://github.com/feend78/ainneve","homepage":null,"size":199,"stargazers_count":1,"watchers_count":1,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":1,"default_branch":"master"}},"base":{"label":"evennia:master","ref":"master","sha":"cfa03b8c6d1c8613230f4449fbec9dbb1d44e185","user":{"login":"evennia","id":1036382,"avatar_url":"https://avatars.githubusercontent.com/u/1036382?v=3","gravatar_id":"","url":"https://api.github.com/users/evennia","html_url":"https://github.com/evennia","followers_url":"https://api.github.com/users/evennia/followers","following_url":"https://api.github.com/users/evennia/following{/other_user}","gists_url":"https://api.github.com/users/evennia/gists{/gist_id}","starred_url":"https://api.github.com/users/evennia/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/evennia/subscriptions","organizations_url":"https://api.github.com/users/evennia/orgs","repos_url":"https://api.github.com/users/evennia/repos","events_url":"https://api.github.com/users/evennia/events{/privacy}","received_events_url":"https://api.github.com/users/evennia/received_events","type":"Organization","site_admin":false},"repo":{"id":37817547,"name":"ainneve","full_name":"evennia/ainneve","owner":{"login":"evennia","id":1036382,"avatar_url":"https://avatars.githubusercontent.com/u/1036382?v=3","gravatar_id":"","url":"https://api.github.com/users/evennia","html_url":"https://github.com/evennia","followers_url":"https://api.github.com/users/evennia/followers","following_url":"https://api.github.com/users/evennia/following{/other_user}","gists_url":"https://api.github.com/users/evennia/gists{/gist_id}","starred_url":"https://api.github.com/users/evennia/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/evennia/subscriptions","organizations_url":"https://api.github.com/users/evennia/orgs","repos_url":"https://api.github.com/users/evennia/repos","events_url":"https://api.github.com/users/evennia/events{/privacy}","received_events_url":"https://api.github.com/users/evennia/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/evennia/ainneve","description":"A full example game created in Evennia","fork":false,"url":"https://api.github.com/repos/evennia/ainneve","forks_url":"https://api.github.com/repos/evennia/ainneve/forks","keys_url":"https://api.github.com/repos/evennia/ainneve/keys{/key_id}","collaborators_url":"https://api.github.com/repos/evennia/ainneve/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/evennia/ainneve/teams","hooks_url":"https://api.github.com/repos/evennia/ainneve/hooks","issue_events_url":"https://api.github.com/repos/evennia/ainneve/issues/events{/number}","events_url":"https://api.github.com/repos/evennia/ainneve/events","assignees_url":"https://api.github.com/repos/evennia/ainneve/assignees{/user}","branches_url":"https://api.github.com/repos/evennia/ainneve/branches{/branch}","tags_url":"https://api.github.com/repos/evennia/ainneve/tags","blobs_url":"https://api.github.com/repos/evennia/ainneve/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/evennia/ainneve/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/evennia/ainneve/git/refs{/sha}","trees_url":"https://api.github.com/repos/evennia/ainneve/git/trees{/sha}","statuses_url":"https://api.github.com/repos/evennia/ainneve/statuses/{sha}","languages_url":"https://api.github.com/repos/evennia/ainneve/languages","stargazers_url":"https://api.github.com/repos/evennia/ainneve/stargazers","contributors_url":"https://api.github.com/repos/evennia/ainneve/contributors","subscribers_url":"https://api.github.com/repos/evennia/ainneve/subscribers","subscription_url":"https://api.github.com/repos/evennia/ainneve/subscription","commits_url":"https://api.github.com/repos/evennia/ainneve/commits{/sha}","git_commits_url":"https://api.github.com/repos/evennia/ainneve/git/commits{/sha}","comments_url":"https://api.github.com/repos/evennia/ainneve/comments{/number}","issue_comment_url":"https://api.github.com/repos/evennia/ainneve/issues/comments{/number}","contents_url":"https://api.github.com/repos/evennia/ainneve/contents/{+path}","compare_url":"https://api.github.com/repos/evennia/ainneve/compare/{base}...{head}","merges_url":"https://api.github.com/repos/evennia/ainneve/merges","archive_url":"https://api.github.com/repos/evennia/ainneve/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/evennia/ainneve/downloads","issues_url":"https://api.github.com/repos/evennia/ainneve/issues{/number}","pulls_url":"https://api.github.com/repos/evennia/ainneve/pulls{/number}","milestones_url":"https://api.github.com/repos/evennia/ainneve/milestones{/number}","notifications_url":"https://api.github.com/repos/evennia/ainneve/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/evennia/ainneve/labels{/name}","releases_url":"https://api.github.com/repos/evennia/ainneve/releases{/id}","created_at":"2015-06-21T17:06:19Z","updated_at":"2015-11-24T23:59:31Z","pushed_at":"2015-11-29T06:07:13Z","git_url":"git://github.com/evennia/ainneve.git","ssh_url":"git@github.com:evennia/ainneve.git","clone_url":"https://github.com/evennia/ainneve.git","svn_url":"https://github.com/evennia/ainneve","homepage":null,"size":233,"stargazers_count":21,"watchers_count":21,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":13,"mirror_url":null,"open_issues_count":15,"forks":13,"open_issues":15,"watchers":21,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/evennia/ainneve/pulls/49"},"html":{"href":"https://github.com/evennia/ainneve/pull/49"},"issue":{"href":"https://api.github.com/repos/evennia/ainneve/issues/49"},"comments":{"href":"https://api.github.com/repos/evennia/ainneve/issues/49/comments"},"review_comments":{"href":"https://api.github.com/repos/evennia/ainneve/pulls/49/comments"},"review_comment":{"href":"https://api.github.com/repos/evennia/ainneve/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/evennia/ainneve/pulls/49/commits"},"statuses":{"href":"https://api.github.com/repos/evennia/ainneve/statuses/e6539709f20a602815750f374764ef31153abab9"}}}}