Thread: New Project, text game, design stage.

  1. #1
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968

    New Project, text game, design stage.

    So I posed myself a few questions, or one major question rather.

    What drives a text game? Well obviously text, but more specifically, user input.

    So that lead to more questions. Like, how do we interpret user commands?

    Well I figure the game itself decides how to respond to a command. In a text game theres only so many things you can be doing, so there must be a set of commands that correspond with whatever we're doing at the moment.

    So what systems will be at work here? Well, I guess at any given time in a text adventure game, you could be fighting a monster, talking to a character, or navigating your inventory. I figure for each "state" theres only a certain few commands that will have any meaning. for fighting we will have attack, defend, spells, etc. Something like this...

    Code:
    class GameMode
    {
    public:
    	// needs a list of valid commands
    	// needs a virtual function that compares input
    	// to the list of valid commands, when a match is made
    	// act accordingly.
    private:
    
    };
    So there we have our translator, it's pretty simple in theory. We could have a virtual function which is overridden for every type of game mode we have, be it fighting or talking to a non player character, or NPC. All game modes will have a list of commands that work in conjunction with that mode.

    So we have our flow of data. Handled by a simple user interface that accepts commands, sends it to the game logic to be interpreted, which sends back output to the interface, which displays it on the screen for us. Which we respond to, restarting the whole process.

    I guess after that we have to remember that there is more than just a text system at work here. The game modes not only have to interpret commands and send back a string to the player of the game, it has to take commands like "attack" and actually perform the logic required to do that. Maybe we can divide the chain of command up a bit more even?

    Perhaps a command is sent to the interpreter, which delegates to a script engine which then provides our text. The command could also be sent from the interpreter to various systems within the game, depending on the situation. An attack command could be sent to the scripting engine to display how much damage you've done, or taken, or whatever, while also sending it to the battle system for actual computation.

    Feedback?
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  2. #2
    Its hard... But im here swgh's Avatar
    Join Date
    Apr 2005
    Location
    England
    Posts
    1,688
    Sounds good. To save you time, i would strongly adivse any large peices of text you create to appear on the screen to tell the story for example, you erite in notepad as a txt file and use fstream to read it into the game at the point where it is needed. I created a text game called Enigma ages ago and used this principle. It saved me loads of coding time, and allowed me to concentrate on the more technical features of the game. One good thing about a text game is the fact you do not have to create a Game Engine, although a scipt engine can help
    Double Helix STL

  3. #3
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968
    I decided that I needed a working Menu class, so I write this bad boy
    Code:
    #include <list>
    
    class Menu
    {
    public:
    	Menu(std::string mSelection) 
    	{
    		mSelection = Selection;
    	}
    
    	virtual ~Menu() { Destroy(); }
    
    	// deletes self
    	void Release() { delete this; }
    
    	// call update on all children
    	virtual void Update()
    	{
    		for( std::list<Menu*>::iterator i = MenuChoices.begin();
    			i != MenuChoices.end(); i++ )
    		{
    			(*i)->Update();
    		}
    	}
    
    	// recursively destroy all children and self
    	void Destroy()
    	{
    		for( std::list<Menu*>::iterator i = MenuChoices.begin();
    			i != MenuChoices.end(); i++ )
    		(*i)->Release();
      
    		MenuChoices.clear();
    	}
    
    	// add a child
    	void MenuSelection( Menu* MenuSelection )
    	{
    		MenuSelection->SetRootMenu(this);
    	    MenuChoices.push_back(MenuSelection);
    	}
    
    	// Set the parent of the child
    	void SetRootMenu(Menu* Root)
    	{
    		RootMenu = Root;
    	}
    
    protected:
    	// list of children
    	std::list<Menu*> MenuChoices;
    	// pointer to parent
    	Menu * RootMenu;
    
    	std::string Selection;
    
    };
    I'm going to have my interpreter access a list or vector or container of some sort of root menu's, which will lead to submenus, and finally menu selections, etc..
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  4. #4
    Registered User
    Join Date
    Nov 2005
    Posts
    673
    A game engine is helpful, even if not needed. Think you may not need a graphics core, but input core, sound core, output core, message handler, and things of that nature. I am writing a engine myself. Although mine is relatively complex, with script engine, and other things such as world editor(work in progress). I guess you can say I am making the warcraft 3 of text games.

  5. #5
    Sanity is for the weak! beene's Avatar
    Join Date
    Jul 2006
    Posts
    321
    I am planning on making a text game(alot better than my previous one), i'll let you know how it goes...
    Oh yeah, whats a script engine?
    Last edited by beene; 05-22-2007 at 01:35 PM.

  6. #6
    Registered User
    Join Date
    Nov 2005
    Posts
    673
    it is a set of classes and\or functions that read a language you design to allow for adding things to your game through external sources. Almost every major game uses a script language. Warcraft 3 uses the JASS script language.

  7. #7
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968
    Right now I'm trying to figure out how I should manage and store my menu's once they're all hooked together like they should be.

    Each menu as you can see is simply a class that points to other menu's, which might have selections instead of new menu's.

    The trick is making it so only the active menu's commands are accepted at any given time. If we type in the command magic, it should open the magic menu, and also tell the interpreter what new selections are available. I'm trying to figure this out now...

    Code:
    #include <string>
    #include "Menu.h"
    #include <list>
    
    
    class Interpreter
    {
    public:
    	
    	virtual void Navigate_Menu(std::string Command)
    	{	
    		
    	}
    
    private:
    
    	std::list<std::string*> Valid_Commands;
    	
    };
    Navigate Menu has to find a menu which basically just tells the interpreter what commands are available in that menu. First of all we have to first figure out how we will store our menu classes, which are really in full construction multiple menu classes linked together.

    I guess my main problem is deciding how to store the menu's in memory.

    The process has to go like this.

    A command is given to the interpreter, the interpreter looks through sets of menu's depending on what kind of game mode is currently running. Are we fighting a monster? Talking to a NPC? Navigating our inventory, or in story mode?

    Each mode will have a set of menu's. So we're in battle mode, and we type in Talk, it obviously won't work because talk is a menu in the story mode. But, if we type in Magic, hopefully it will find magic in the battle menu's, and hopefully the magic menu will do its job and return to the interpreter a list of commands that are now valid. Now since we're in the magic menu, only the menu selections fire or ice will work.

    If we now type in Ice, the menu knows that there are no submenu's under ice, so it will return ice as the only valid selection, which will then be sent on to the battle system to be processed.

    So yeah, thats what I have in mind for my text engine.
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  8. #8
    Registered User
    Join Date
    Nov 2005
    Posts
    673
    You may want to give your engine the ability like a doubly linked list, where it can go forward or backwards. What if you typed in magic, but changed you mind, can you still go back? I guess it depends on the game rules.

  9. #9
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968
    Yeah it works like that, if you look at the menu class closely you'll notice there is a pointer to each child class, and a pointer to the parent class..

    Basically I just have to make a "selection" class that connects to the menu classes.

    My only wonder is how to organize all this data.
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  10. #10
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968
    Updated footnotes for the interpreter...

    Code:
    #include <string>
    #include "Menu.h"
    #include <list>
    
    
    class Interpreter
    {
    public:
    	
    	virtual void Navigate_Menu(std::string Command)
    	{	
    		//to first find the menu given by the command
    		//we have to find a way to organize the menus
    
    		//then
    
    		//if it is a recognized command, we delete
    		//the current list of valid commands
    
    		//then
    
    		//We make a new list of valid coimmands by
    		//inserting command strings into valid commands
    		//by looping through the selected menu's
    		//children and getting their Selection string
    	}
    
    private:
    
    	std::list<std::string*> Valid_Commands;
    	
    };
    Also an updated Menu class:

    Code:
    #ifndef MENU
    #define MENU
    
    #include <string>
    #include <list>
    
    class Menu
    {
    public:
    	
    	Menu(std::string mSelection)
    	{
    		mSelection = Selection;
    	}
    
    	virtual ~Menu() { Destroy(); }
    
    	// deletes self
    	void Release() { delete this; }
    
    	// call update on all children
    	virtual void Update()
    	{
    		for( std::list<Menu*>::iterator i = MenuChoices.begin();
    			i != MenuChoices.end(); i++ )
    		{
    			(*i)->Update();
    		}
    	}
    
    	// recursively destroy all children and self
    	void Destroy()
    	{
    		for( std::list<Menu*>::iterator i = MenuChoices.begin();
    			i != MenuChoices.end(); i++ )
    		(*i)->Release();
      
    		MenuChoices.clear();
    	}
    
    	// add a child
    	void MenuSelection( Menu* MenuSelection )
    	{
    		MenuSelection->SetRootMenu(this);
    	    MenuChoices.push_back(MenuSelection);
    	}
    
    	//Get the menu name
    	std::string Return_Selection()
    	{
    		return Selection;
    	}
    
    private:
    
    	// Set the parent of the child
    	void SetRootMenu(Menu* Root)
    	{
    		RootMenu = Root;
    	}
    
    	//menu name
    	std::string Selection;
    
    protected:
    	// list of children
    	std::list<Menu*> MenuChoices;
    	// pointer to parent
    	Menu * RootMenu;
    
    };
    
    #endif
    Hah I guess I still do know how to program a bit :d

    Some new commentary:
    Code:
    /*
      Somehow, I need to create a database of menus..
      Never done this before..  I think I don't
      actually have to store the menu objects
      in a file,  only strings for what menu's I need 
      and maybe some variables to show they connect together..
    */
    And to further the todo list:

    What exactly am I going to do with these automatically created Menu trees?

    Well I know why I need them, so I don't have to hardcode all my menus, and so all my menus are connected the way they should be. But now what? How does the interpreter access the menus? I guess I have to manage the menu classes in dynamic memory... The resource manager could easily be requested to look for a menu class by string. From finding that initial root menu I could now instead use the pointers held in the menu classes themselves to navigate around the menu's... Even if they're all in the same manager.


    O.o After afterthought!

    I don't actually have to use the pointers in the menu classes at all, all I need them for is to create a new list of valid commands, then finally I can just use a resource_manager to access the menus. Though I wonder, is all this searching through a map by comparing strings going to give alot of overhead? Not that it really matters in a text game, but for future reference, anyone have any feedback so far?

    I love it when everything works so perfectly, it's like magic.
    Last edited by Shamino; 05-23-2007 at 09:41 AM.
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. how do the game engine and the api interact?
    By Shadow12345 in forum Game Programming
    Replies: 9
    Last Post: 12-08-2010, 12:08 AM
  2. Little game project
    By Gen. in forum Projects and Job Recruitment
    Replies: 7
    Last Post: 08-19-2006, 10:29 PM
  3. C Programming 2d Array Question
    By jeev2005 in forum C Programming
    Replies: 3
    Last Post: 04-26-2006, 03:18 PM
  4. OpenGL - 2d text in 3d game
    By mikeb1986 in forum C++ Programming
    Replies: 1
    Last Post: 03-22-2006, 01:24 PM
  5. Game Engine Link Prob
    By swgh in forum Game Programming
    Replies: 2
    Last Post: 01-26-2006, 12:14 AM