sort systems into folders
This commit is contained in:
parent
37ef494796
commit
205d6923b3
63
README.md
63
README.md
|
@ -5,6 +5,21 @@ TaleWeave AI is an open-source game engine designed for creating rich, immersive
|
|||
|
||||
![TaleWeave AI logo with glowing sunrise over angular castle](https://docs-cdn.taleweave.ai/taleweave-github-1280.png)
|
||||
|
||||
## Contents
|
||||
|
||||
- [TaleWeave AI](#taleweave-ai)
|
||||
- [Contents](#contents)
|
||||
- [Features](#features)
|
||||
- [Game Actions](#game-actions)
|
||||
- [Game Systems](#game-systems)
|
||||
- [Requirements](#requirements)
|
||||
- [Recommended](#recommended)
|
||||
- [Setup](#setup)
|
||||
- [Documentation](#documentation)
|
||||
- [Contributing](#contributing)
|
||||
- [Support and Community](#support-and-community)
|
||||
- [License](#license)
|
||||
|
||||
## Features
|
||||
|
||||
TaleWeave AI is meant for gamers, developers, and researchers. It is a:
|
||||
|
@ -26,7 +41,7 @@ TaleWeave AI does a few things out of the box:
|
|||
- Generate a world from a brief text prompt
|
||||
- Simulate the actions of characters in that world
|
||||
- Allow humans to interact with each other and with NPCs
|
||||
- Track detailed status for each entity: mood, hunger, thirst, hygiene, time of day, weather, etc
|
||||
- Track detailed status for each entity: mood, hunger, thirst, hygiene, weather, and more
|
||||
- Summarize the environment into LLM prompts
|
||||
- Foster emergent behavior through action digests, shared environment, and note taking
|
||||
|
||||
|
@ -35,27 +50,45 @@ TaleWeave AI can:
|
|||
- Be modified in almost every way - everything is a plugin, including the planning and action stages that drive the simulation
|
||||
- Be run locally - does not require any cloud services, but does play nicely with them
|
||||
- Connect to your data - game systems can fetch data for RAG, making responses richer and more consistent
|
||||
- Export training data - for analysis and fine tuning of character models
|
||||
- Export training data - for analysis, visualization, and fine tuning of character models
|
||||
- Plug in to your workflow - run the simulation step by step in Jupyter notebooks using the TaleWeave AI engine as a Python library
|
||||
- Connect to your server and vice versa - the Discord bot is a plugin and can be replaced with your favorite chat platform
|
||||
|
||||
## Contents
|
||||
### Game Actions
|
||||
|
||||
- [TaleWeave AI](#taleweave-ai)
|
||||
- [Features](#features)
|
||||
- [Contents](#contents)
|
||||
- [Requirements](#requirements)
|
||||
- [Recommended](#recommended)
|
||||
- [Setup](#setup)
|
||||
- [Documentation](#documentation)
|
||||
- [Contributing](#contributing)
|
||||
- [Support and Community](#support-and-community)
|
||||
- [License](#license)
|
||||
TaleWeave AI has in-game actions for:
|
||||
|
||||
| Core | Life Sim | RPG |
|
||||
| ------------ | --------------- | --------- |
|
||||
| Planning | Hunger & Thirst | Combat |
|
||||
| Conversation | Hygiene | Crafting |
|
||||
| Movement | Sleeping | Magic |
|
||||
| Exploration | | Movement* |
|
||||
| | | Writing |
|
||||
|
||||
1. The core exploration actions provide ways for characters to expand the world by finding new rooms and items.
|
||||
2. The RPG movement actions provide additional situational movement like crawling, climbing, and jumping.
|
||||
|
||||
### Game Systems
|
||||
|
||||
TaleWeave AI has game systems for:
|
||||
|
||||
| Core | Life Sim | RPG | Environment |
|
||||
| -------- | --------------- | ------ | ----------- |
|
||||
| Acting | Hunger & Thirst | Health | Humidity |
|
||||
| Planning | Hygiene | Quests | Temperature |
|
||||
| Summary | Mood | | Time of day |
|
||||
| | Sleeping | | Weather |
|
||||
|
||||
1. The core summary system provides character with a summary of actions taken by other characters in between turns.
|
||||
|
||||
All of the game systems are optional, including the core systems, so you can configure a world where characters only
|
||||
plan and never act, or vice versa.
|
||||
|
||||
## Requirements
|
||||
|
||||
- Python 3.10
|
||||
- Ollama, vLLM, or another OpenAI-compatible LLM API (including OpenAI)
|
||||
- Python 3.10+
|
||||
- Ollama or an OpenAI-compatible LLM API like llama.cpp, vLLM, or OpenAI
|
||||
|
||||
While TaleWeave AI can be run entirely on CPU, one or more GPUs are highly recommended.
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ from taleweave.context import (
|
|||
world_context,
|
||||
)
|
||||
from taleweave.errors import ActionError
|
||||
from taleweave.systems.action import ACTION_SYSTEM_NAME
|
||||
from taleweave.systems.core.action import ACTION_SYSTEM_NAME
|
||||
from taleweave.utils.conversation import loop_conversation
|
||||
from taleweave.utils.search import (
|
||||
find_character_in_room,
|
|
@ -1,5 +1,4 @@
|
|||
from logging import getLogger
|
||||
from typing import Callable, List
|
||||
|
||||
from packit.agent import Agent, agent_easy_connect
|
||||
|
||||
|
@ -22,7 +21,7 @@ from taleweave.generate import (
|
|||
generate_room,
|
||||
link_rooms,
|
||||
)
|
||||
from taleweave.systems.action import ACTION_SYSTEM_NAME
|
||||
from taleweave.systems.core.action import ACTION_SYSTEM_NAME
|
||||
from taleweave.utils.effect import apply_effects, is_effect_ready
|
||||
from taleweave.utils.search import find_character_in_room
|
||||
from taleweave.utils.string import normalize_name
|
||||
|
@ -254,7 +253,7 @@ def action_use(item: str, target: str) -> str:
|
|||
return outcome
|
||||
|
||||
|
||||
def init_optional() -> List[Callable]:
|
||||
def init():
|
||||
"""
|
||||
Initialize the custom actions.
|
||||
"""
|
||||
|
|
|
@ -8,7 +8,7 @@ from taleweave.context import (
|
|||
)
|
||||
from taleweave.errors import ActionError
|
||||
from taleweave.models.planning import CalendarEvent
|
||||
from taleweave.systems.planning import PLANNING_SYSTEM_NAME
|
||||
from taleweave.systems.core.planning import PLANNING_SYSTEM_NAME
|
||||
from taleweave.utils.planning import get_recent_notes
|
||||
from taleweave.utils.template import format_prompt
|
||||
|
||||
|
|
|
@ -60,8 +60,8 @@ if True:
|
|||
from taleweave.models.prompt import PromptLibrary
|
||||
from taleweave.plugins import load_plugin
|
||||
from taleweave.state import save_world_state
|
||||
from taleweave.systems.action import init_action
|
||||
from taleweave.systems.planning import init_planning
|
||||
from taleweave.systems.core.action import init_action
|
||||
from taleweave.systems.core.planning import init_planning
|
||||
|
||||
|
||||
def int_or_inf(value: str) -> float | int:
|
||||
|
|
|
@ -159,7 +159,7 @@ def init():
|
|||
subscribe(GameEvent, digest_listener)
|
||||
return [
|
||||
GameSystem(
|
||||
"digest",
|
||||
"summary",
|
||||
format=format_digest,
|
||||
generate=generate_digest,
|
||||
initialize=initialize_digest,
|
|
@ -0,0 +1,24 @@
|
|||
from os import path
|
||||
|
||||
from taleweave.systems.generic.logic import load_logic
|
||||
|
||||
|
||||
def logic_path(system: str) -> str:
|
||||
return path.join(".", "taleweave", "systems", "environment", system, "logic.yaml")
|
||||
|
||||
|
||||
SYSTEM_NAMES = [
|
||||
"humidity",
|
||||
"temperature",
|
||||
"weather",
|
||||
]
|
||||
|
||||
|
||||
def init_logic():
|
||||
systems = []
|
||||
for system_name in SYSTEM_NAMES:
|
||||
logic_file = logic_path(system_name)
|
||||
if path.exists(logic_file):
|
||||
systems.append(load_logic(logic_file))
|
||||
|
||||
return systems
|
|
@ -0,0 +1,40 @@
|
|||
rules:
|
||||
# wet/dry logic
|
||||
- group: environment-moisture
|
||||
match:
|
||||
type: character
|
||||
wet: true
|
||||
chance: 0.1
|
||||
set:
|
||||
wet: false
|
||||
|
||||
- group: environment-moisture
|
||||
match:
|
||||
type: character
|
||||
wet: true
|
||||
temperature: hot
|
||||
chance: 0.2
|
||||
set:
|
||||
wet: false
|
||||
|
||||
- group: environment-temperature
|
||||
match:
|
||||
type: room
|
||||
temperature: hot
|
||||
chance: 0.2
|
||||
trigger: [taleweave.systems.sim.environment_triggers:hot_room]
|
||||
|
||||
- group: environment-temperature
|
||||
match:
|
||||
type: room
|
||||
temperature: cold
|
||||
chance: 0.2
|
||||
trigger: [taleweave.systems.sim.environment_triggers:cold_room]
|
||||
|
||||
labels:
|
||||
- match:
|
||||
type: character
|
||||
wet: true
|
||||
backstory: You are soaking wet.
|
||||
description: They are soaking wet and dripping water.
|
||||
# false intentionally omitted
|
|
@ -10,14 +10,14 @@ from taleweave.context import get_dungeon_master
|
|||
from taleweave.game_system import GameSystem
|
||||
from taleweave.models.base import dataclass
|
||||
from taleweave.models.entity import Room, World, WorldEntity
|
||||
from taleweave.systems.logic import load_logic
|
||||
from taleweave.systems.generic.logic import load_logic
|
||||
from taleweave.utils.string import or_list
|
||||
|
||||
logger = getLogger(__name__)
|
||||
|
||||
|
||||
LOGIC_FILES = [
|
||||
"./taleweave/systems/weather/weather_logic.yaml",
|
||||
"./taleweave/systems/environment/weather/logic.yaml",
|
||||
]
|
||||
|
||||
|
|
@ -1,21 +1,51 @@
|
|||
from .crafting_actions import action_craft
|
||||
from .language_actions import action_read
|
||||
from .magic_actions import action_cast
|
||||
from .movement_actions import action_climb
|
||||
from os import path
|
||||
|
||||
from taleweave.systems.generic.logic import load_logic
|
||||
|
||||
from .crafting.actions import action_craft
|
||||
from .magic.actions import action_cast
|
||||
from .movement.actions import action_climb
|
||||
from .quest.actions import accept_quest, submit_quest
|
||||
from .writing.actions import action_read, action_write
|
||||
|
||||
|
||||
def logic_path(system: str) -> str:
|
||||
return path.join(".", "taleweave", "systems", "rpg", system, "logic.yaml")
|
||||
|
||||
|
||||
SYSTEM_NAMES = [
|
||||
"combat",
|
||||
"crafting",
|
||||
"health",
|
||||
"magic",
|
||||
"movement",
|
||||
"quest",
|
||||
"writing",
|
||||
]
|
||||
|
||||
|
||||
def init_actions():
|
||||
return [
|
||||
# crafting
|
||||
action_craft,
|
||||
# language
|
||||
action_read,
|
||||
# magic
|
||||
action_cast,
|
||||
# movement
|
||||
action_climb,
|
||||
# quest
|
||||
accept_quest,
|
||||
submit_quest,
|
||||
# writing
|
||||
action_read,
|
||||
action_write,
|
||||
]
|
||||
|
||||
|
||||
def init_logic():
|
||||
return []
|
||||
systems = []
|
||||
for system_name in SYSTEM_NAMES:
|
||||
logic_file = logic_path(system_name)
|
||||
if path.exists(logic_file):
|
||||
systems.append(load_logic(logic_file, name_prefix=system_name))
|
||||
|
||||
return systems
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
from taleweave.context import action_context, get_system_data
|
||||
from taleweave.errors import ActionError
|
||||
from taleweave.systems.quest import (
|
||||
from taleweave.utils.search import find_character_in_room
|
||||
from taleweave.utils.template import format_prompt
|
||||
|
||||
from .system import (
|
||||
QUEST_SYSTEM,
|
||||
complete_quest,
|
||||
get_active_quest,
|
||||
get_quests_for_character,
|
||||
set_active_quest,
|
||||
)
|
||||
from taleweave.utils.search import find_character_in_room
|
||||
from taleweave.utils.template import format_prompt
|
||||
|
||||
|
||||
def accept_quest(character: str, quest: str) -> str:
|
|
@ -15,7 +15,7 @@ from taleweave.models.entity import (
|
|||
World,
|
||||
WorldEntity,
|
||||
)
|
||||
from taleweave.systems.logic import match_logic
|
||||
from taleweave.systems.generic.logic import match_logic
|
||||
from taleweave.utils.search import (
|
||||
find_entity_reference,
|
||||
find_item_in_container,
|
|
@ -19,3 +19,21 @@ def action_read(item: str) -> str:
|
|||
return str(action_item.attributes["text"])
|
||||
|
||||
return f"The {item} has nothing to read."
|
||||
|
||||
|
||||
def action_write(item: str, text: str) -> str:
|
||||
"""
|
||||
Write on an item like a book or a sign.
|
||||
|
||||
Args:
|
||||
item: The name of the item to write on.
|
||||
text: The text to write.
|
||||
"""
|
||||
with action_context() as (_, action_character):
|
||||
action_item = find_item_in_character(action_character, item)
|
||||
if not action_item:
|
||||
return f"You do not have a {item} to write on."
|
||||
|
||||
action_item.attributes["text"] = text
|
||||
broadcast(f"{action_character.name} writes on {item}")
|
||||
return f"You write on the {item}."
|
|
@ -1,15 +1,21 @@
|
|||
from taleweave.systems.logic import load_logic
|
||||
from os import path
|
||||
|
||||
from .hunger_actions import action_cook, action_eat
|
||||
from .hygiene_actions import action_wash
|
||||
from .sleeping_actions import action_sleep
|
||||
from taleweave.systems.generic.logic import load_logic
|
||||
|
||||
LOGIC_FILES = [
|
||||
"./taleweave/systems/sim/environment_logic.yaml",
|
||||
"./taleweave/systems/sim/hunger_logic.yaml",
|
||||
"./taleweave/systems/sim/hygiene_logic.yaml",
|
||||
"./taleweave/systems/sim/mood_logic.yaml",
|
||||
"./taleweave/systems/sim/sleeping_logic.yaml",
|
||||
from .hunger.actions import action_cook, action_eat
|
||||
from .hygiene.hygiene_actions import action_wash
|
||||
from .sleeping.actions import action_sleep
|
||||
|
||||
|
||||
def logic_path(system: str) -> str:
|
||||
return path.join(".", "taleweave", "systems", "sim", system, "logic.yaml")
|
||||
|
||||
|
||||
SYSTEM_NAMES = [
|
||||
"hunger",
|
||||
"hygiene",
|
||||
"mood",
|
||||
"sleeping",
|
||||
]
|
||||
|
||||
|
||||
|
@ -26,4 +32,10 @@ def init_actions():
|
|||
|
||||
|
||||
def init_logic():
|
||||
return [load_logic(filename) for filename in LOGIC_FILES]
|
||||
systems = []
|
||||
for system_name in SYSTEM_NAMES:
|
||||
logic_file = logic_path(system_name)
|
||||
if path.exists(logic_file):
|
||||
systems.append(load_logic(logic_file, name_prefix=system_name))
|
||||
|
||||
return systems
|
||||
|
|
Loading…
Reference in New Issue