Skip to content

Commit

Permalink
fix wielding bugs
Browse files Browse the repository at this point in the history
modify tests to handle linebreak
  • Loading branch information
neph1 committed Aug 17, 2023
1 parent af22a25 commit 958be90
Show file tree
Hide file tree
Showing 8 changed files with 26 additions and 17 deletions.
4 changes: 2 additions & 2 deletions stories/prancingllama/zones/prancingllama.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def init(self):
def spawn_rat(self, ctx: Context) -> None:
rat_skull = Item("rat_skull", "giant rat skull", descr="It's a giant rat's bloody skull.")
if not self.rat or self.rat.alive == False:
self.rat = Rat("giant rat", random.choice("m"), descr="A vicious looking, giant, rat", race="rodent")
self.rat = Rat("giant rat", random.choice("m"), descr="A vicious looking, giant, rat", race="giant rat")
self.rat.init_inventory([rat_skull])
self.rat.move(self)

Expand Down Expand Up @@ -88,7 +88,7 @@ def _generate_character():

# 10 attempts to generate 2 characters
generated = 0
for i in range(10):
for i in range(5):
if _generate_character():
generated += 1
if generated == 2:
Expand Down
8 changes: 5 additions & 3 deletions tale/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
from . import combat
from . import player
from .errors import ActionRefused, ParseError, LocationIntegrityError, TaleError, UnknownVerbException, NonSoulVerb
from tale.races import UnarmedAttack

__all__ = ["MudObject", "Armour", 'Container', "Door", "Exit", "Item", "Living", "Stats", "Location", "Weapon", "Key", "Soul"]

Expand Down Expand Up @@ -907,6 +908,7 @@ def __init__(self) -> None:
self.race = "" # the name of the race of this creature
self.strength = 3
self.dexterity = 3
self.unarmed_attack = Weapon(UnarmedAttack.FISTS.name)

def __repr__(self):
return "<Stats: %s>" % vars(self)
Expand Down Expand Up @@ -1353,8 +1355,8 @@ def start_attack(self, victim: 'Living') -> None:

combat_prompt = mud_context.driver.llm_util.combat_prompt.format(attacker=attacker_name,
victim=victim_name,
attacker_weapon=self.wielding,
victim_weapon=victim.wielding,
attacker_weapon=self.wielding.name,
victim_weapon=victim.wielding.name,
attacker_msg=attacker_msg,
location=self.location.title,
location_description=self.location.short_description)
Expand Down Expand Up @@ -1464,7 +1466,7 @@ def wielding(self) -> Weapon:
def wielding(self, weapon: Optional[Weapon]) -> None:
"""Wield a weapon. If weapon is None, unwield."""
self.__wielding = weapon
self.stats.wc = self.__wielding.wc if self.__wielding else 0
self.stats.wc = weapon.wc if self.__wielding else 0


class Container(Item):
Expand Down
6 changes: 5 additions & 1 deletion tale/cmds/normal.py
Original file line number Diff line number Diff line change
Expand Up @@ -1700,7 +1700,11 @@ def do_wield(player: Player, parsed: base.ParseResult, ctx: util.Context) -> Non
weapon = str(parsed.args[0])
except ValueError as x:
raise ActionRefused(str(x))
player.wielding = weapon
result = player.locate_item(weapon, include_location=False)
if result:
player.wielding = result[0]
else:
raise ActionRefused("You don't have that weapon")

@cmd("unwield")
def do_unwield(player: Player, parsed: base.ParseResult, ctx: util.Context) -> None:
Expand Down
8 changes: 4 additions & 4 deletions tale/llm_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ DEFAULT_BODY: '{"stop_sequence": "", "max_length":500, "max_context_length":4096
ANALYSIS_BODY: '{"banned_tokens":"\n\n", "stop_sequence": "\n\n\n", "max_length":500, "max_context_length":4096, "temperature":0.15, "top_k":120, "top_a":0.0, "top_p":0.85, "typical_p":1.0, "tfs":1.0, "rep_pen":1.2, "rep_pen_range":256, "mirostat":2, "mirostat_tau":5.0, "mirostat_eta":0.1, "sampler_order":[6,0,1,3,4,2,5], "seed":-1}'
MEMORY_SIZE: 512
PRE_PROMPT: 'Below is an instruction that describes a task, paired with an input that provides further context. Write a response that appropriately completes the request.\n\n'
BASE_PROMPT: "[Story context: {story_context}]; [History: {history}]; ### Instruction: Rewrite the following Text in your own words using the supplied Context and History to create a background for your text. Use about {max_words} words. Text:\n\n [{input_text}] \n\nEnd of text.\n\n### Response:\n"
ACTION_PROMPT: "[Story context: {story_context}]; [History: {history}]; The following Action is part of a roleplaying game. ### Instruction: Rewrite the Action, and nothing else, in your own words using the supplied Context and Location. History is what happened before. Use less than {max_words} words. Text:\n\n [{input_text}] \n\nEnd of text.\n\n### Response:\n"
BASE_PROMPT: "[Story context: {story_context}]; [History: {history}]; ### Instruction: Rewrite the following Text in your own words using the supplied Context and History to create a background for your text. Use about {max_words} words. [Text:{input_text}] \n\nEnd of text.\n\n ### Instruction: Rewrite [Text] in your own words. ### Response:\n"
ACTION_PROMPT: "[Story context: {story_context}]; [History: {history}]; The following Action is part of a roleplaying game. ### Instruction: Rewrite the Action, and nothing else, in your own words using the supplied Context and Location. History is what happened before. Use less than {max_words} words. [Text: {input_text}] \n\nEnd of text.\n\n### Response:\n"
DIALOGUE_PROMPT: '[Story context: {story_context}]; [Location: {location}]; The following is a conversation between {character1} and {character2}; {character1}:{character1_description}; character2:{character2_description}; [Chat history: {previous_conversation}]\n\n [{character2}s sentiment towards {character1}: {sentiment}]. ### Instruction: Write a single response for {character2} in third person pov, using {character2} description.\n\n### Response:\n'
ITEM_PROMPT: 'Items:[{items}];Characters:[{character1},{character2}] \n\n ### Instruction: Decide if an item was explicitly given, taken, dropped or put somewhere in the following text:[Text:{text}]. Insert your thoughts about whether an item was explicitly given, taken, put somewhere or dropped in "my thoughts", and the results in "item", "from" and "to", or make them empty if . Insert {character1}s sentiment towards {character2} in a single word in "sentiment assessment". Fill in the following JSON template: {{ "thoughts":"my thoughts", "result": {{ "item":"", "from":"", "to":""}}, {{"sentiment":"sentiment assessment"}} }} End of example. \n\n Write your response in valid JSON\n\n### Response:\n'
COMBAT_PROMPT: 'Rewrite the following combat between user {attacker}, wielding:{attacker_weapon} and {victim}, wielding:{victim_weapon} into a vivid description in less than 300 words. Location: {location}, {location_description}. ### Instruction: Rewrite the following combat result in about 150 words. Combat Result: {attacker_msg} ### Response:\n\n'
COMBAT_PROMPT: 'Rewrite the following combat between user {attacker}, weapon:{attacker_weapon} and {victim}, weapon:{victim_weapon} into a vivid description in less than 300 words. Location: {location}, {location_description}. ### Instruction: Rewrite the following combat result in about 150 words, using the characters weapons . Combat Result: {attacker_msg} ### Response:\n\n'
CREATE_CHARACTER_PROMPT: '### Instruction: For a low-fantasy roleplaying game, create a diverse character with rich personality that can be interacted with using the story context and keywords. Do not mention height. Money as int value. Story context: {story_context}; keywords: {keywords}. Fill in this JSON template and write nothing else: {{"name":"", "description": "", "appearance": "", "personality": "", "money":"", "level":"", "gender":"", "age":"", "race":""}} ### Response:\n'
CREATE_ROOM_PROMPT: 'Story context: {story_context}. Exit template: {"name" : "connected room", "short_desc":"description visible to use", "long_desc":"detailed description", "enter_msg":"message when using exit"}; Item template: {"name":"", "type":""}, type can be "weapon", "armor", "other"; Character template: {"name":"", "type":""}, type can be "friendly", "neutral", "hostile" ### Instruction: Existing connected room: {room_desc}. For a {story_type} roleplaying game, create a single new, intriguing, room connected to {room_name}. Include at least one exit leading to an additional room. Fill in this JSON template and do not write anything else: {"name":"", "description": "", "exits": [], "items":[], "npcs":[]} ### Response:\n'
CREATE_ROOM_PROMPT: 'Story context: {story_context}. Exit template: {"name" : "connected room", "short_desc":"description visible to use", "long_desc":"detailed description", "enter_msg":"message when using exit"}; Item template: {"name":"", "type":""}, type can be "weapon", "armor", "other"; Character template: {"name":"", "type":""}, type can be "friendly", "neutral", "hostile" ### Instruction: Existing room connected to the generated room: {room_desc}. For a {story_type} roleplaying game, create a single new, intriguing, room connected to {room_name}. Include at least one exit leading to an additional room. Add items and characters if if seems fitting. Fill in this JSON template and do not write anything else: {"name":"", "description": "", "exits": [], "items":[], "npcs":[]} ### Response:\n'
9 changes: 6 additions & 3 deletions tale/llm_ext.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ class LivingNpc(Living):
"""An NPC with extra fields to define personality and help LLM generate dialogue"""

def __init__(self, name: str, gender: str, *,
title: str="", descr: str="", short_descr: str="", age: int, personality: str, occupation: str=""):
super(LivingNpc, self).__init__(name=name, gender=gender, title=title, descr=descr, short_descr=short_descr)
title: str="", descr: str="", short_descr: str="", age: int, personality: str, occupation: str="", race: str=""):
super(LivingNpc, self).__init__(name=name, gender=gender, title=title, descr=descr, short_descr=short_descr, race=race)
self.age = age
self.personality = personality
self.occupation = occupation
Expand Down Expand Up @@ -46,14 +46,17 @@ def notify_action(self, parsed: ParseResult, actor: Living) -> None:

def do_say(self, what_happened: str, actor: Living) -> None:
self.update_conversation(f'{actor.title}:{what_happened}\n')
max_length = False if isinstance(actor, Player) else True

response, item_result, sentiment = mud_context.driver.llm_util.generate_dialogue(
conversation=self.conversation,
character_card = self.character_card,
character_name = self.title,
target = actor.title,
target_description = actor.short_description,
sentiment = self.sentiments.get(actor.title, ''),
location_description=self.location.look(exclude_living=self))
location_description=self.location.look(exclude_living=self),
max_length=max_length)

self.update_conversation(f"{self.title} says: \"{response}\"")
if len(self.conversation) > self.memory_size:
Expand Down
2 changes: 1 addition & 1 deletion tests/files/test_character.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"alternate_greetings": [], "avatar": "none", "character_version": "", "creator": "", "creator_notes": "", "description": "test description", "appearance": "test appearance", "aliases":["alias1", "alias2"], "age": "30", "occupation":"test occupation", "extensions": {"chub": {"alt_expressions": [], "expressions": null, "full_path": "", "id": "", "related_lorebooks": []}, "fav": true, "talkativeness": "0.5", "world": ""}, "first_mes": "", "mes_example": "", "name": "test character", "personality": "test personality", "post_history_instructions": "", "scenario": "", "system_prompt": "", "tags": []}
{"alternate_greetings": [], "avatar": "none", "character_version": "", "creator": "", "creator_notes": "", "description": "test description", "appearance": "test appearance", "aliases":["alias1", "alias2"], "age": "30", "race":"human", "occupation":"test occupation", "extensions": {"chub": {"alt_expressions": [], "expressions": null, "full_path": "", "id": "", "related_lorebooks": []}, "fav": true, "talkativeness": "0.5", "world": ""}, "first_mes": "", "mes_example": "", "name": "test character", "personality": "test personality", "post_history_instructions": "", "scenario": "", "system_prompt": "", "tags": []}
4 changes: 2 additions & 2 deletions tests/test_mudobjects.py
Original file line number Diff line number Diff line change
Expand Up @@ -441,9 +441,9 @@ def test_go_through_exit(self):
self.assertEqual(0, len(hall.livings))
self.assertEqual(3, len(attic.livings))
self.assertEqual(["entering the attic via exit 1", "\n", "<location>[attic]</>"], collector_j.messages[0:3])
self.assertEqual(["Julie leaves towards attic.", "<location>[attic]</>, Julie is here."], collector_p.messages[0:2]) # changed so that livings are included
self.assertEqual(["Julie leaves towards attic.", "<location>[attic]</>\nJulie is here."], collector_p.messages[0:2]) # changed so that livings are included
self.assertEqual(["Julie leaves towards attic.", "Peter leaves towards attic.", "entering the attic via door",
"\n", "<location>[attic]</>, Julie and Peter are here."], collector_s.messages[0:5])
"\n", "<location>[attic]</>\nJulie and Peter are here."], collector_s.messages[0:5])

def test_bind_exit(self):
class ModuleDummy:
Expand Down
2 changes: 1 addition & 1 deletion tests/test_player.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ def test_look_brief(self):
self.assertEqual(self._concat_list(["[Attic]", "A dark attic.", "Julie is here.\n"]), player.test_get_output_paragraphs())

def _concat_list(self, input):
return [', '.join(input)]
return ['\n'.join(input)]

def test_others(self):
attic = Location("Attic", "A dark attic.")
Expand Down

0 comments on commit 958be90

Please sign in to comment.