Skip to content
This repository has been archived by the owner on Oct 11, 2023. It is now read-only.

Human to player #259

Merged
merged 3 commits into from
Sep 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion light/graph/builders/one_room_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ def add_new_agent_to_graph(self, g, char, room_node):
agent_node = g.add_agent(
use_desc, self._props_from_char(char), db_id=char.db_id
)
# added as a NPC Nothing needs to be done as agent is added as x._human = False
# added as a NPC
agent_node.move_to(room_node)
objs = {}
if self.suggestion_type != "model":
Expand Down
2 changes: 1 addition & 1 deletion light/graph/builders/starspace_all.py
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ def add_new_agent_to_graph(self, g, char, room_node):
agent_node = g.add_agent(
use_desc, self._props_from_char(char), db_id=char.db_id
)
# added as a NPC Nothing needs to be done as agent is added as x._human = False
# added as a NPC
agent_node.move_to(room_node)
objs = {}
if self.suggestion_type != "model":
Expand Down
2 changes: 1 addition & 1 deletion light/graph/builders/starspace_assisted.py
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ def add_new_agent_to_graph(self, g, char, room_node):
agent_node = g.add_agent(
use_desc, self._props_from_char(char), db_id=char.db_id
)
# added as a NPC Nothing needs to be done as agent is added as x._human = False
# added as a NPC
agent_node.move_to(room_node)
objs = {}
if self.suggestion_type != "model":
Expand Down
3 changes: 0 additions & 3 deletions light/graph/builders/tests/test_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,6 @@ def test_builder_adds_random_agent_to_graph_adds_another_to_some_room(self):
contained_room_1 = len(self.testGraph.get_node(gRoomId).contained_nodes)
contained_room_2 = len(self.testGraph.get_node(gRoomId2).contained_nodes)
self.assertTrue(contained_room_1 == 3 or contained_room_2 == 3)
# Trying to add again will not work, since all characters in world!
self.graphBuilder.add_random_new_agent_to_graph(self.testWorld)
self.assertEqual(len(self.testGraph.agents), 3)

def test_builder_returns_graph(self):
self.assertIsInstance(self.testGraph, OOGraph)
Expand Down
5 changes: 2 additions & 3 deletions light/graph/elements/graph_nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -588,7 +588,7 @@ def __init__(self, node_id, name, props=None, db_id=None):
self.dead = False
# Flag to resolve when a death event is in the stack, but possibly not processed
self._dying = False
self.is_player = self._props.get("is_player", False)
self.is_player = self._props.get("is_player", self._props.get("_human", False))
self.usually_npc = self._props.get("usually_npc", False)
self.pacifist = self._props.get("pacifist", False)
self.tags = self._props.get("tags", self.DEFAULT_TAGS)
Expand Down Expand Up @@ -619,7 +619,6 @@ def __init__(self, node_id, name, props=None, db_id=None):
self.mission = self._props.get("mission", "")

# Game properties to track for this agent, TODO move to other class?
self._human = False
self._current_player = None
self.clear_memory()

Expand Down Expand Up @@ -754,7 +753,7 @@ def get_observations(self):

def set_player(self, current_player):
"""Have a new player take over this agent. None returns to npc"""
self._human = current_player is not None
self.is_player = current_player is not None
self.clear_memory()
self._current_player = current_player

Expand Down
4 changes: 1 addition & 3 deletions light/graph/structured_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -318,9 +318,7 @@ def get_npcs(self):
"""Get a list of agent nodes that aren't currently being played by
a human character"""
return [
x
for x in self.agents.values()
if x._human is False and not x.is_player and not x.get_prop("dead")
x for x in self.agents.values() if x.is_player and not x.get_prop("dead")
]

def set_desc(self, id, desc):
Expand Down
6 changes: 2 additions & 4 deletions light/world/content_loggers.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,6 @@ def __init__(
for node_id in self.graph.all_nodes[self.room_id].contained_nodes:
if self.graph.all_nodes[node_id].agent and (
self.graph.all_nodes[node_id].is_player
or self.graph.all_nodes[node_id]._human
):
self._add_player()

Expand Down Expand Up @@ -406,7 +405,6 @@ def observe_event(self, event):

def human_controlled(self, event):
"""
Determines if an event is controlled by a human or not -
need ._human for legacy (web)
Determines if an event is controlled by a human or not
"""
return event.actor.is_player or event.actor._human
return event.actor.is_player
2 changes: 1 addition & 1 deletion light/world/souls/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ When a `Soul`'s time is up, either due to the `GraphAgent` being removed from th
Some `Soul`'s set flags on `GraphAgent`'s to be able to be interpreted by other `Soul`'s or elements of the world. These generally should be prepended with an `_` such that they don't get compressed into the saved formats.

Current flags:
- `is_human`: Set by `PlayerSoul` to designate `GraphAgent`'s that are inhabited by a real player. Used by the world to ensure we don't doubly assign a `GraphAgent` to two different players, and by `ModelSoul`'s to differentiate between inter-model chat and chat with a human.
- `is_player`: Set by `PlayerSoul` to designate `GraphAgent`'s that are inhabited by a real player. Used by the world to ensure we don't doubly assign a `GraphAgent` to two different players, and by `ModelSoul`'s to differentiate between inter-model chat and chat with a human.
4 changes: 2 additions & 2 deletions light/world/souls/models/generative_heuristic_model_soul.py
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ def npc_dialogue(self, obs=None):
self.dialogue_switch_partner(agent, partner)

# TODO refactor with is_human when human flag is refactored
if not ALLOW_INTERBOT_CHAT and not partner._human:
if not ALLOW_INTERBOT_CHAT and not partner.is_player:
return

quest_txt = None
Expand All @@ -422,7 +422,7 @@ def npc_dialogue(self, obs=None):
event.skip_safety = True
event.execute(self.world)
return

# Send to model to process
msg = {"text": context, "episode_done": True}
self.npc_dialog_model.observe(msg)
Expand Down
15 changes: 8 additions & 7 deletions light/world/souls/player_soul.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import random
import time
from light.graph.events.graph_events import SystemMessageEvent

if TYPE_CHECKING:
from light.graph.elements.graph_nodes import GraphAgent
from light.world.world import World
Expand Down Expand Up @@ -43,9 +43,7 @@ def __init__(
"""
super().__init__(target_node, world)
assert not target_node.is_player, "Cannot have two players in the same agent!"
# TODO merge these flags across LIGHT
target_node.is_player = True
target_node._human = True
target_node._last_action_time = time.time()
self.player_id = player_id
self.provider = provider # TODO link with real provider
Expand Down Expand Up @@ -78,7 +76,12 @@ def handle_act(self, act_text, event_id: Optional[str] = None):
# print debug information about humans playing instead
humans = self.world.oo_graph.get_humans()
num = len(humans)
txt = "There are " + str(num) + " LIGHT denizen(s) from your world on this plane: " + str(humans)
txt = (
"There are "
+ str(num)
+ " LIGHT denizen(s) from your world on this plane: "
+ str(humans)
)
event = SystemMessageEvent(self.target_node, [], text_content=txt)
event.skip_safety = True
event.execute(self.world)
Expand All @@ -87,8 +90,7 @@ def handle_act(self, act_text, event_id: Optional[str] = None):
actor = self.target_node
actor._last_action_time = time.time()
self.world.parse_exec(self.target_node, act_text, event_id=event_id)



def new_quest(self):
if random.random() > 0.01:
# Turn these mostly off for now.
Expand Down Expand Up @@ -139,7 +141,6 @@ def reap(self):
"""
super().reap()
self.target_node.is_player = False
self.target_node._human = False
self.target_node.persona = self.target_node.persona.split(QUEST_TEXT)[0]
self.world.oo_graph.room_id_to_loggers[
self.target_node.get_room().node_id
Expand Down
2 changes: 1 addition & 1 deletion light/world/souls/repeat_soul.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ async def observe_event(self, event: "GraphEvent"):
"""
if event.actor == self.target_node:
return
if not (event.actor.is_player or event.actor._human):
if not (event.actor.is_player):
return
if self.target_node.is_dying():
return # Going to die, can't do anything
Expand Down
71 changes: 0 additions & 71 deletions light/world/world.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,77 +252,6 @@ def node_contains(self, id):
# TODO deprecate calls here, go to oo_graph
return [x.node_id for x in self.oo_graph.get_node(id).get_contents()]

def get_available_actions_fast(self, agent_id):
"""Get available actions quickly, some of these may not be possible.
NOTE: Jack can clean up later, but this seems to do everything need for NPCs
right now. Essentially I think such a function shouldn't be using strings
at all during reasoning, only ids all the way down until the last conversion
to action strings, which the existing code didn't seem to do..?
NOTE2: I've only included here actions actually in the LIGHT Turked dataset.
Easy to add more of course, such as wield.
This code is fairly fast (i measured like 10,000 calls in 0.8 secs).
"""
# TODO improve with graphs
acts = []
room_id = self.room(agent_id)
nearby_ids = self.node_contains(room_id)
carrying_ids = self.node_contains(agent_id)
container_ids = []

for id in nearby_ids:
if id == agent_id:
continue
id_txt = self.node_to_desc(id).lower()
if self.has_prop(id, "agent"):
acts.append("hit " + id_txt)
acts.append("hug " + id_txt)
acts.append("examine " + id_txt)
for id2 in carrying_ids:
id2_txt = self.node_to_desc(id2).lower()
acts.append("give " + id2_txt + " to " + id_txt)
neighbor_carrying_ids = self.node_contains(id)
for id2 in neighbor_carrying_ids:
id2_txt = self.node_to_desc(id2).lower()
acts.append("steal " + id2_txt + " from " + id_txt)
if self.has_prop(id, "object"):
if not self.has_prop(id, "not_gettable"):
acts.append("get " + id_txt)
if not self.has_prop(id, "not_gettable") or self.has_prop(id, "human"):
# objects are examinable,
# except for non-gettable by NPCs, as it's boring.
acts.append("examine " + id_txt)
if self.has_prop(id, "container"):
container_ids.append(id)

for id in carrying_ids:
if self.has_prop(id, "container"):
container_ids.append(id)

for id in carrying_ids:
id_txt = self.node_to_desc(id).lower()
acts.append("examine " + id_txt)
acts.append("drop " + id_txt)
if self.has_prop(id, "equipped"):
acts.append("remove " + id_txt)
elif self.has_prop(id, "wearable"):
acts.append("wear " + id_txt)
if self.has_prop(id, "food"):
acts.append("eat " + id_txt)
if self.has_prop(id, "drink"):
acts.append("drink " + id_txt)
for id2 in container_ids:
id2_txt = self.node_to_desc(id2).lower()
acts.append("put " + id_txt + " in " + id2_txt)

for id in container_ids:
id_txt = self.node_to_desc(id).lower()
inside_ids = self.node_contains(id)
for id2 in inside_ids:
id2_txt = self.node_to_desc(id2).lower()
acts.append("get " + id_txt + " from " + id2_txt)

return acts

@deprecated
def desc_to_nodes(self, desc, nearbyid=None, nearbytype=None):
"""Get nodes nearby to a given node from that node's perspective"""
Expand Down