Microsoft TextWorld

repository·main·Indexed 23 days ago

https://github.com/microsoft/textworld

A text-based game generator and extensible sandbox environment designed for training and testing reinforcement learning (RL) agents. It includes a Gym-like Python API for agent interaction, tools for generating custom games via tw-make, and a system for creating game 'flavours' using context-free grammars (.twf files). Supports Python 3.9 through 3.12 on Linux and macOS, with Docker support for Windows users.

Tokens
10.9K
Snippets
38
Records
72
Agent score
81%

What's inside TextWorld

  1. What is TextWorld?

    main

    TextWorld is a sandbox learning environment designed for training and testing reinforcement learning (RL) agents using text-based games.

    Key capabilities include:

    • Game Generation: You can generate games from a distribution parameterized by factors such as map size, number of objects, quest length, quest complexity, and richness of text descriptions.
    • Sampling: You can sample specific games from a defined distribution.
    • Game Play: TextWorld can be used to play existing text-based games.
  2. Create instructions and handle object groups

    main

    Instructions typically require one symbol per action (e.g., take, insert, put, open, unlock). You can refer to objects involved in an action using parentheses, such as (k) for a key.

    Object Groups in Instructions

    To handle actions that apply to different types of objects (like a door vs. a container), use the (c|d) syntax. This tells the generator to replace the symbol with either the container or the door depending on the context.

    Common group symbols:

    • (c|d): Container or door.
    • (o|k|f|b): All objects that can be in containers or on shelves (used for take, insert, and put).
  3. How TextWorld flavours and context-free grammars work

    main

    A TextWorld 'flavour' is a set of text descriptions that realize the underlying world structure (e.g., a modern house vs. a fantasy castle) without changing the game logic. Flavours are implemented using context-free grammars saved with the .twf extension.

    Grammar Syntax

    • Rules: Defined as nonterminal: option1 ; option2 ; etc.. Options are chosen with equal likelihood.
    • Non-terminals: Embed a symbol by enclosing it in # (e.g., #greeting#). The grammar will recursively expand these symbols.
    • Comments: Any line starting with # is a comment.
    • Spacing: Spacing is preserved during expansion. Symbols cannot contain spaces.

    Required Files for a New Flavour

    To create a complete flavour, you must author four separate .twf files:

    1. [flavour]_obj.twf: Object name generation.
    2. [flavour]_room.twf: Room description generation.
    3. [flavour]_instruction.twf: Instructions.
    4. [flavour]_question.twf: Questions.
    # Example grammar syntax
    food: apple; lettuce; cheese
    
    introduction: Hello, #greeting#
    greeting:nice to meet you!;how are you?;have we met?
    
    # Recursive expansion
    introduction: Hello, #greeting#
    greeting:#greet_how# to meet you!;how are you?;have we met?
    greet_how:nice;great;wonderful
  4. Handle multiple objects in room descriptions

    main

    TextWorld supports grouping objects in room descriptions using the room_desc_group symbol. This allows the generator to group objects by shared adjectives or nouns.

    To implement this, you must define:

    • room_desc_group: The main grouping sentence.
    • room_desc_(type)_multi_noun: For objects grouped by noun (e.g., multiple chests).
    • room_desc_(type)_multi_adj: For objects grouped by adjective (e.g., multiple red things).

    room_desc_group uses special quantifiers and placeholders:

    • (^): A quantifier that converts the count to text (1 = "one", 2 = "two", >2 = "several").
    • (val): Represents the grouping factor (the plural noun or adjective, e.g., "chests" or "red things").
    • (name): A list of the grouped objects (e.g., "a chest and a box").

    Example:

    room_desc_group:There are (^) (val) here, (name).

    Expands to: There are two red things here, a chest and a box.

  5. Define room descriptions in TextWorld CFGs

    main

    When generating a game, room descriptions follow a specific pattern: a description of the room object, a list of visible objects (containers and supporters), and a list of exits.

    To define a room, you must provide the dec symbol for the initial description. You should also define room_desc_(c) for containers and room_desc_(s) for supporters to describe objects immediately visible in the room. You can use (name), (name-adj), and (name-n) to refer to the object being described.

    Example pattern:

    1. dec: Describes the room itself.
    2. room_desc_(c) / room_desc_(s): Describes visible containers or supporters.
    3. Exits: Describes available exits.
    room_desc_group:There are (^) (val) here, (name).
  6. Install TextWorld

    main

    TextWorld supports Python 3.9, 3.10, 3.11, and 3.12 on Linux and macOS. Windows users should use Docker.

    System Requirements

    Debian/Ubuntu:

    sudo apt update && sudo apt install build-essential libffi-dev python3-dev curl git

    macOS:

    brew install libffi curl git

    Python Installation

    Install via pip:

    pip install textworld

    Or install from a cloned repository:

    pip install .
    pip install textworld
  7. Use Inform 7 functions for dynamic descriptions

    main

    When writing grammars, you can use Inform 7 built-in functions to dynamically list contents or check object states.

    Listing Contents

    Use [a list of things in the <object>] for containers or [a list of things on the <object>] for supporters. This ensures the description updates automatically as items are moved.

    Example:

    • The chest has [a list of things in the chest] in it.
    • On the shelf [is-are a list of things on the shelf].

    Conditional State Descriptions

    You can use [if x is open][else if x is locked][otherwise][end if] to modify sentences based on an object's state (open, locked, or closed).

    Example: The chest is [if chest is open]open[else if chest is locked]locked[otherwise]closed[end if].

    # Containers
    In the chest [is-are a list of things in the chest]. -> In the chest are a pen and an apple.
    The chest has [a list of things in the chest] in it. -> The chest has a pen and an apple in it.
    
    # Supporters
    On the shelf [is-are a list of things on the shelf]. -> On the shelf are a pen and an apple.
    The shelf has [a list of things on the shelf]. -> The shelf has a pen and an apple in it.
    
    # State checking
    The chest is [if chest is open]open[else if chest is locked]locked[otherwise]closed[end if].
  8. Run TextWorld using Docker

    main

    You can run TextWorld in a pre-configured Docker container which includes a Jupyter notebook environment. This is useful for accessing the text-based game generator and sandbox environment without local installation.

    1. Pull the image: docker pull marccote19/textworld
    2. Run the container: docker run -p 8888:8888 -it --rm marccote19/textworld
    3. Access the environment: Look at the terminal output for a Jupyter notebook link (e.g., http://127.0.0.1:8888/?token=...) and navigate to it in your browser.
    docker pull marccote19/textworld
    docker run -p 8888:8888 -it --rm marccote19/textworld
  9. Set a random seed in the Frotz interpreter for Zork1

    main

    When using the frotz interpreter to play Zork1, you can provide a specific random seed as a parameter. This is useful for ensuring deterministic behavior (removing stochasticity) during testing or walkthroughs. Use the -s flag followed by the seed value.

    Example command:

    ./frotz/dfrotz -s 1 zork1.z5