Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Bug Need help with predicting story telling

Discussion in 'Scripting' started by myprivateunityaccount, Jun 23, 2023.

  1. myprivateunityaccount

    myprivateunityaccount

    Joined:
    Mar 22, 2022
    Posts:
    1
    Code (CSharp):
    1. using System;
    2. using System.Collections.Generic;
    3. using System.IO;
    4. using System.Linq;
    5.  
    6. public class StoryGenerator
    7. {
    8.     private static Random random = new Random();
    9.     private Dictionary<string, List<string>> nGrams;
    10.     private string[] sentences;
    11.     private List<string> storyWords = new List<string>();
    12.     private List<string> generatedSentenceWords = new List<string>();
    13.     private string[] nextWords;
    14.  
    15.     public void GenerateStory(string filePath)
    16.     {
    17.         if (File.Exists(filePath))
    18.         {
    19.             string input = File.ReadAllText(filePath);
    20.             sentences = SplitSentences(input);
    21.             nGrams = ProcessNGrams(sentences, 1);
    22.             var generatedSentence = GenerateSentence(sentences, nGrams, 1);
    23.             generatedSentenceWords = generatedSentence.Split(' ').ToList();
    24.  
    25.             foreach (var word in generatedSentenceWords)
    26.             {
    27.                 PostWordToTextField(word);
    28.             }
    29.         }
    30.         else
    31.         {
    32.             Console.WriteLine("Story.txt file not found!");
    33.         }
    34.     }
    35.  
    36.     private string[] SplitSentences(string input)
    37.     {
    38.         return input.Split(new[] { '.', '!', '?' }, StringSplitOptions.RemoveEmptyEntries);
    39.     }
    40.  
    41.     private Dictionary<string, List<string>> ProcessNGrams(string[] sentences, int n)
    42.     {
    43.         Dictionary<string, List<string>> nGrams = new Dictionary<string, List<string>>();
    44.  
    45.         foreach (string sentence in sentences)
    46.         {
    47.             string[] words = sentence.Split(' ');
    48.             for (int i = 0; i < words.Length - n; i++)
    49.             {
    50.                 string nGramKey = string.Join(" ", words.Skip(i).Take(n));
    51.                 string nextWord = words[i + n];
    52.          
    53.                 if (!nGrams.ContainsKey(nGramKey))
    54.                 {
    55.                     nGrams[nGramKey] = new List<string>();
    56.                 }
    57.          
    58.                 nGrams[nGramKey].Add(nextWord);
    59.             }
    60.         }
    61.  
    62.         return nGrams;
    63.     }
    64.  
    65.     private string GenerateSentence(string[] sentences, Dictionary<string, List<string>> nGrams, int n)
    66.     {
    67.         string startWord = sentences[random.Next(sentences.Length)].Split(' ')[0];
    68.         List<string> generatedWords = new List<string> { startWord };
    69.  
    70.         while (generatedWords.Count < 20)
    71.         {
    72.             string nGramKey = string.Join(" ", generatedWords.Skip(generatedWords.Count - n).Take(n));
    73.             if (nGrams.ContainsKey(nGramKey))
    74.             {
    75.                 List<string> possibleNextWords = nGrams[nGramKey];
    76.                 string nextWord = possibleNextWords[random.Next(possibleNextWords.Count)];
    77.                 generatedWords.Add(nextWord);
    78.             }
    79.             else
    80.             {
    81.                 break;
    82.             }
    83.         }
    84.  
    85.         return string.Join(" ", generatedWords);
    86.     }
    87.  
    88.     private void PostWordToTextField(string word)
    89.     {
    90.         // Code to post a word to the text field
    91.         // ...
    92.     }
    93. }
    94.  
    95. public class Program
    96. {
    97.     public static void Main(string[] args)
    98.     {
    99.         string filePath = "Story.txt";
    100.         StoryGenerator generator = new StoryGenerator();
    101.         generator.GenerateStory(filePath);
    102.     }
    103. }

    Hello everyone,

    I'm currently working on a program that automatically generates sentences based on a large database of stories I've loaded into a text file (txt format). However, I'm facing some challenges with the sentence generation process. The generated sentences lack proper punctuation and formatting, making them feel random and disconnected from the original stories.

    I'm seeking guidance on how to enhance the sentence generation algorithm to incorporate better sentence structure, encourage dialogue, and overall create a cohesive narrative that feels like a story rather than an infinite run-on sentence. What steps or techniques should I consider to achieve this goal?

    Any suggestions, code examples, or resources related to improving sentence structure, formatting, and storytelling in an automated program would be greatly appreciated.

    Thank you in advance for your assistance!
     

    Attached Files:

    Last edited: Jun 23, 2023
  2. StarBornMoonBeam

    StarBornMoonBeam

    Joined:
    Mar 26, 2023
    Posts:
    209
    Corr quite a question.
    I am not surprised by the lack of response.

    To have a coherent story you should not work with words but with full sentences. I am not sure it is a scripting issue, but more a design issue. It's much easier to create a story from preloaded sentences, instead of making a sentence from words and then trying to piece those random sentences together coherently. That, though not impossible for a human being. That is otherwise so advanced it's unlikely anyone but yourself could figure that one out.

    I made something similar once in the way described. Starter sentence welcoming to the story, then randomised sentences that could pop up in any order and would not repeat. The result was good.

    Personally I think it's a bit of a game design question.
     
  3. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,526
    Hi,

    You're trying to reinvent large language model generative pretrained transformers like ChatGPT. If that's what you really want to do, look over The Essential Skills for Large Language Model Development: What You Need to Know. Or, if it works for your project's requirements, you could train up your own LLM on your sentences using an open source system such as privateGPT.

    If you're not ready to tackle that yet, you could take a simpler, more primitive approach. Like StarBornMoonBeam suggests, tackle it at the sentence level. You could piece together prewritten sentences, or you could define a large library of generic sentence structures and fill in words at runtime Mad Libs-style.
     
    angrypenguin likes this.
  4. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,043
    Did you really think you'd get something coherent out of it?

    It certainly sounds like you'd want the computer to behave like an artificial intelligence. So go and learn how AI systems are made.

    Not a single non-AI system is capable of what you're asking for. Ordinary imperative coding is not capable of creating coherent stories and even if you managed to fudge it so that you get something that resembles proper human language, this has to come at a trade off so large that your potential narrative space is easily explored because the combinatorial space of any modular narration is tiny.

    However, from this vantage point you can perhaps realize that you can formulate your stories as cards, in an attempt to hijack the combinatorial space of a deck of cards. And this can work only if you organize your cards as separate chapters.

    If you keep such chapters vague enough, you can then think of them as functions with arguments such as characters, events, or objects. And this can help you weave these in and out of the functions, tracking their states throughout the overarching story. You can also use some other persistent ambient data to enrich, force or skip over a particular card/chapter, as well as state machines or Markov chains to select the best outcome in some sequence through set conditions and probabilities.

    This will still be highly predictable, especially after player sees all (or most of) the cards you've got. But it's the best one can do with a non-AI machine storytelling.
     
  5. zulo3d

    zulo3d

    Joined:
    Feb 18, 2023
    Posts:
    510
    You could create a 2D world with lots of items and characters that are free to move around and interact with each other. Then instead of rendering the world with sprites or polygons you describe the world with text. You could describe the world to the reader from a character's point of view.

    You need the text to actually represent something that exists and has meaning. You can't just regurgitate text from a database and expect a credible and meaningful story to unfold. Not unless your database already contains a credible and meaningful story.

    The most difficult part will be making the characters communicate with each other in interesting ways. Their conversations could only ever be as interesting as their world.