A Lua in game console.

A place for users of OGRE to discuss ideas and experiences of utilitising OGRE in their games / demos / applications.
User avatar
merlinblack
Goblin
Posts: 224
Joined: Thu Mar 15, 2007 10:05 am
Location: Sydney, Australia
x 7

A Lua in game console.

Post by merlinblack »

Hey everyone,

I've just finished writing and pasting my code into this http://www.ogre3d.org/wiki/index.php/LuaConsole

Have a look, and get back to me on any questions or perhaps edit out any spelling mistakes I've missed or whatever.

I think the code needs more comments perhaps.

I'm now off in search of food. :P

Cheers! 8)

Nigel
"He'd never realized that, deep down inside, what he really wanted to do was make things go splat."
Terry Pratchett, Reaper Man
Image
User avatar
xavier
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 9481
Joined: Fri Feb 18, 2005 2:03 am
Location: Dublin, CA, US
x 22

Re: A Lua in game console.

Post by xavier »

Right on, I expect this will be well-received. :)
Do you need help? What have you tried?

Image

Angels can fly because they take themselves lightly.
User avatar
merlinblack
Goblin
Posts: 224
Joined: Thu Mar 15, 2007 10:05 am
Location: Sydney, Australia
x 7

Blinkin curse ..... or

Post by merlinblack »

I've added some simple code for a blinking cursor to the console class. Works quite well except when using a proportional font it looks a little strange when the cursor is in the middle of the text, as the line length 'blinks' too. Nothing too serious, but it's a great improvement for so little code added. :D
"He'd never realized that, deep down inside, what he really wanted to do was make things go splat."
Terry Pratchett, Reaper Man
Image
User avatar
PJani
Gremlin
Posts: 171
Joined: Wed Dec 24, 2008 7:21 pm

Re: A Lua in game console.

Post by PJani »

I have python interpreter in ingame console(). :D Works like hell.
| Intel Dual Core 1.8Ghz, ATI Radeon Mobility X1600 256MB, 2GB RAM |
| AMD64 3000+ 1.8Ghz, 2GB RAM, GF6600 GT 128MB |
| Ogre 1.6.4 | VS C++ EE | OgreNewt + Newton 2.xx |
| Win XP || Ubuntu 9.04 | C/C++, Python, VB6, Delphi |
User avatar
merlinblack
Goblin
Posts: 224
Joined: Thu Mar 15, 2007 10:05 am
Location: Sydney, Australia
x 7

Re: A Lua in game console.

Post by merlinblack »

Yeah Python rocks. :D However I've only used it standalone so far.
"He'd never realized that, deep down inside, what he really wanted to do was make things go splat."
Terry Pratchett, Reaper Man
Image
gershon
Gnoblar
Posts: 4
Joined: Sun Mar 08, 2009 5:02 pm

Re: A Lua in game console.

Post by gershon »

kodus! this thing rocks, using luabind (followed http://www.codeproject.com/KB/graphics/ ... gre3d.aspx) gives sweet runtime scripting :D

Image
User avatar
merlinblack
Goblin
Posts: 224
Joined: Thu Mar 15, 2007 10:05 am
Location: Sydney, Australia
x 7

Re: A Lua in game console.

Post by merlinblack »

gershon wrote:kodus! this thing rocks, using luabind (followed http://www.codeproject.com/KB/graphics/ ... gre3d.aspx) gives sweet runtime scripting :D

Image
Now that's cool. I wrote that article too! I'm glad it's helping people out! I'm presently playing around with a cut down gui system, driven by Lua. So far I have two in one program. One is like a simpler version of BetaGUI bound to Lua, and the other is a one class design, where you make more specialized classes/widgets in Lua. I'm comparing the two approaches. The two represent different placement of the script/c++ divide. All this made much much easier by having the console there.

I finding some 'interesting' things out about Luabind at the same time. :roll: But I have to say, the latest one (0.9.1) totally rocks.

Nigel
"He'd never realized that, deep down inside, what he really wanted to do was make things go splat."
Terry Pratchett, Reaper Man
Image
User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
x 179

Re: A Lua in game console.

Post by jacmoe »

Very nice starting point for a console! :)

I have a small fix:

Code: Select all

        case OIS::KC_UP:
			if(!history.empty())
			{
				if( history_line == history.begin() )
					history_line = history.end();
				history_line--;
				editline.setText( *history_line );
				textChanged = true;
			}
			break;
 
        case OIS::KC_DOWN:
			if(!history.empty())
			{
				history_line++;
				if( history_line == history.end() )
					history_line = history.begin();
				editline.setText( *history_line );
				textChanged = true;
			}
If we're not checking for an empty history, it will crash when it is, ie when pressing UP in the console when nothing has been entered yet. :)
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
User avatar
merlinblack
Goblin
Posts: 224
Joined: Thu Mar 15, 2007 10:05 am
Location: Sydney, Australia
x 7

Re: A Lua in game console.

Post by merlinblack »

Cool! I'll update the wiki and my own code. Thanks!
"He'd never realized that, deep down inside, what he really wanted to do was make things go splat."
Terry Pratchett, Reaper Man
Image
User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
x 179

Re: A Lua in game console.

Post by jacmoe »

I made a console using Angelscript based on this. :)
Will make a wiki article rsn. Thanks a lot!
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
User avatar
merlinblack
Goblin
Posts: 224
Joined: Thu Mar 15, 2007 10:05 am
Location: Sydney, Australia
x 7

Re: A Lua in game console.

Post by merlinblack »

You didn't go for bash? :P
Was it just a case of writing a new interpreter class? I wrote it with that in mind. I just noticed a couple of things to tidy up in the code that's on the wiki, compared to what I now use. I'll have to have an update session. It's great to see it being useful. :)
"He'd never realized that, deep down inside, what he really wanted to do was make things go splat."
Terry Pratchett, Reaper Man
Image
User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
x 179

Re: A Lua in game console.

Post by jacmoe »

I think so, I'll check. But I am fairly sure I just hacked a new interpreter from the old one. :)
I might have made some adjustments to allow me to use it with the new OgreBites trays. But, I'll check.
A good starting point.

I chose Angelscript because it's the by far easiest scripting library to bind. :)


This is my console script functions so far:

Code: Select all

	asIScriptEngine* engine = AngelScriptInterpreter::getSingletonPtr()->getInterpreter();
	engine->RegisterObjectType("TerrainTest", 0, asOBJ_REF | asOBJ_NOHANDLE);
	engine->RegisterObjectMethod("TerrainTest", "void quit()", asMETHOD(TerrainTest, quit), asCALL_THISCALL);
	engine->RegisterObjectMethod("TerrainTest", "void saveCampos()", asMETHOD(TerrainTest, saveCampos), asCALL_THISCALL);
	engine->RegisterObjectMethod("TerrainTest", "void restoreCampos()", asMETHOD(TerrainTest, restoreCampos), asCALL_THISCALL);
	engine->RegisterObjectMethod("TerrainTest", "void setCampos(float, float, float)", asMETHOD(TerrainTest, setCampos), asCALL_THISCALL);
	engine->RegisterObjectMethod("TerrainTest", "void saveTerrain()", asMETHOD(TerrainTest, saveTerrain), asCALL_THISCALL);

	// Register the singleton's address that the script will use to access it
	engine->RegisterGlobalProperty("TerrainTest app", this);
Allows me to call 'app.quit()', 'app.saveTerrain()', etc. from the console.
That's pure Angelscript, no wrapper or anything.
Even I can figure out how to use it. :P

I plan to implement auto-complete, which is fairly simple to do using Angelscript. Just iterate the functions on the 'app' object.
(I think).

Also, I am very lazy, so I think I'll implement an auto-parenthesis function.
I find it awkward to have to write app.quit() when I can write app.quit instead. :mrgreen:
Unless it's carrying parameters, of course.
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
User avatar
merlinblack
Goblin
Posts: 224
Joined: Thu Mar 15, 2007 10:05 am
Location: Sydney, Australia
x 7

Re: A Lua in game console.

Post by merlinblack »

Yeah, I've been thinking about auto-complete myself. I might just go for tab-complete, i.e. rather than automatic, trigger it on the tab key. I'll probably write it in Lua to start with too.

I'm using the latest luabind (.9) for most of my binding where classes are involved. Otherwise I just make a free function and use good old lua_register.

Auto parentheses make sense to me, being a game console. I think I'll do that too :D

Nigel
"He'd never realized that, deep down inside, what he really wanted to do was make things go splat."
Terry Pratchett, Reaper Man
Image
KakCAT
Gnoblar
Posts: 15
Joined: Sun Jan 24, 2010 11:40 am

Re: A Lua in game console.

Post by KakCAT »

bug... maybe

Code: Select all

        case OIS::KC_DOWN:
            if( !history.empty() )
            {
              history_line++;
shouldn't be

Code: Select all

        case OIS::KC_DOWN:
            if( !history.empty() )
            {
                if( history_line != history.end() )  history_line++;

??

I'm getting a "list iterator not incrementable" error when I press "down" just after adding an item to the history, due to

Code: Select all

void LuaConsole::addToHistory( const string& cmd )
{
   ....
    history_line = history.end();
}
Charlie111
Kobold
Posts: 26
Joined: Sun Sep 16, 2007 2:38 pm
Location: France

Re: A Lua in game console.

Post by Charlie111 »

Hi,

I'm using the lua console, it's cool :D
Only little problem : I can't get the console to be transparent.
I will not bother you with the code... but is there a classical mistake that I could have done ??
Actually, even if I change the color (not transparance), the font of the console remain white.
So I think that I don't set the material correctly...

juts a little part for fun

Code: Select all

m_TextBox = overlayManager.createOverlayElement("TextArea","ConsoleText");
m_TextBox->setMetricsMode(GMM_RELATIVE);
m_TextBox->setPosition(0,0);
m_TextBox->setParameter("font_name","Console");
m_TextBox->setParameter("colour_top","0 0 0");
m_TextBox->setParameter("colour_bottom","0 0 0");
m_TextBox->setParameter("char_height","0.03");

m_Panel = static_cast<OverlayContainer*>(overlayManager.createOverlayElement("Panel", "ConsolePanel"));
m_Panel->setMetricsMode(Ogre::GMM_RELATIVE);
m_Panel->setPosition(0, 0);
m_Panel->setDimensions(1, 0);
m_Panel->setMaterialName("console/background");

m_Panel->addChild(m_TextBox);

m_Overlay = overlayManager.create("Console");
m_Overlay->add2D(m_Panel);
m_Overlay->show();
The material

Code: Select all

material console/background 
{ 
	technique 
	{ 
		pass 
		{ 
			scene_blend alpha_blend
			diffuse 0 0.3 1 0.5 
		}
	} 
} 
Thanks !

++
User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
x 179

Re: A Lua in game console.

Post by jacmoe »

To be honest, that console material has me baffled as well, so I just ended up using a real texture! :)
KakCAT wrote:

Code: Select all

if( history_line != history.end() )  history_line++;
Thanks for the fix!
Feel free to update the wiki - I tried pressing down with only one entry, and it did crash thoroughly. :)
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
User avatar
merlinblack
Goblin
Posts: 224
Joined: Thu Mar 15, 2007 10:05 am
Location: Sydney, Australia
x 7

Re: A Lua in game console.

Post by merlinblack »

I'm just using a texture for the console background.

Code: Select all

material console/background
{
	technique
	{
		pass
		{
			scene_blend modulate
         texture_unit
			{
			    texture console.png
			}
		}
	}
}


Now I think about it, I'm not sure where that material on the wiki came from. I must have pasted the wrong one!!! :oops:

My code isn't crashing after adding a line to the history, and pressing DOWN. :? Huh? My code seems the same as on the wiki...

I'll have to check that out! Because I'm using gcc on Linux? Just lucky. Who knows. :?

EDIT: I checked it out. Using "g++ (Ubuntu 4.4.1-4ubuntu9) 4.4.1", the following prints the message....

Code: Select all

iter = mylist.end();
iter++;
if( iter == mylist.begin() )
    cout << "Well that's interesting!!!" << endl;
END EDIT

I'll up date the wiki with your fix. Thanks!

On another note, I've implemented "auto-parenthesis" but its a little ...... hacky. It works however and is really cool. Thanks Jacmoe for the idea! :D

I'm wondering if to update the wiki page, or perhaps make an 'additions page'. I have other things, like a simple binding of console functions to Lua, that I could add.
Last edited by merlinblack on Sun Feb 07, 2010 11:42 pm, edited 2 times in total.
"He'd never realized that, deep down inside, what he really wanted to do was make things go splat."
Terry Pratchett, Reaper Man
Image
User avatar
merlinblack
Goblin
Posts: 224
Joined: Thu Mar 15, 2007 10:05 am
Location: Sydney, Australia
x 7

Re: A Lua in game console.

Post by merlinblack »

Here's my changes to luainterpreter.cpp to give you "auto-parenthesis".

Code: Select all

// Insert (another) line of text into the interpreter.
LuaInterpreter::State LuaInterpreter::insertLine( std::string& line, bool fInsertInOutput )
{
    if( fInsertInOutput == true )
    {
        mOutput += line;
        mOutput += '\n';
    }

    if( mFirstLine && line.substr(0,1) == "=" )
    {
        line = "return " + line.substr(1, line.length()-1 );
    }

    mCurrentStatement += " ";
    mCurrentStatement += line;
    mFirstLine = false;

    mState = LI_READY;

    if( luaL_loadstring( mL, mCurrentStatement.c_str() ) )
    {
        string error( lua_tostring( mL, -1 ) );
        lua_pop( mL, 1 );

        // If the error is not a syntax error cuased by not enough of the
        // statement been yet entered...
        if( error.substr( error.length()-6, 5 ) != "<eof>" )
        {
            mOutput += error;
            mOutput += "\n";
            mOutput += LI_PROMPT;
            mCurrentStatement.clear();
            mState = LI_ERROR;

            return mState;
        }
        // Otherwise...
        else
        {
            // Try putting "()" on the end.  This allows commands such as 'quit' to invoke 'quit()'
            if( luaL_loadstring( mL, (mCurrentStatement + "()").c_str() ) )
            {
                // Didn't work.  Remove error message.
                lua_pop( mL, 1 );

                // Secondary prompt
                mPrompt = LI_PROMPT2;

                mState = LI_NEED_MORE_INPUT;

                return mState;
            }
        }
    }

    // The statment compiled correctly, now run it.

    if( ! lua_pcall( mL, 0, LUA_MULTRET, 0 ) )
    {
        // The error message (if any) will be added to the output as part
        // of the stack reporting.
        lua_gc( mL, LUA_GCCOLLECT, 0 );     // Do a full garbage collection on errors.
        mState = LI_ERROR;
    }

    mCurrentStatement.clear();
    mFirstLine = true;

    // Report stack contents
    if ( lua_gettop(mL) > 0)
    {
      lua_getglobal(mL, "print");
      lua_insert(mL, 1);
      lua_pcall(mL, lua_gettop(mL)-1, 0, 0);
    }

    mPrompt = LI_PROMPT;

    // Clear stack
    lua_settop( mL, 0 );

    return mState;
}
Basically if the code fails to compile due to there being not enough yet entered, "()" is added to the end and compiling it tried again. So at the console "quit" becomes "quit()" for example. It adds more "exits" from the function than I would like, but it seems to work. 8)

And here is a superior alternate to the output stuff in luainterpreter.cpp

Code: Select all

int LuaConsole_print( lua_State *L )
{
    int i;
    int nArgs = lua_gettop(L);
    std::string output;

    lua_getglobal( L, "tostring" );

    for( i = 1; i <= nArgs; i++ )
    {
        const char *s;
        lua_pushvalue( L, -1 );
        lua_pushvalue( L, i );
        lua_pcall( L, 1, 1, 0 );
        s = lua_tostring( L, -1 );
        if( ! s )
            return luaL_error( L, LUA_QL("tostring") " must return a string to ", LUA_QL("print"));

        output += s;

        if( i < nArgs )
            output += "\t";

        lua_pop( L, 1 );    // Pop return value of "tostring"
    }

    LuaConsole::getSingleton().print( output );

    return 0;
}
It prints straight to the console class, so you see the result as soon as it happens without having to press enter to see new output. Also handles anything that "tostring()" handles, since that's what it uses! As per usual, I wrote it, then found something almost identical on the net. So it's got the good bits of that added too. :)
"He'd never realized that, deep down inside, what he really wanted to do was make things go splat."
Terry Pratchett, Reaper Man
Image
User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
x 179

Re: A Lua in game console.

Post by jacmoe »

My solution for the auto-parenthesis is here:

Code: Select all

			std::string sought = "(";
			int pos = mCurrentStatement.find(sought);
			if(pos == std::string::npos)
			{
				mCurrentStatement += std::string("()");
			}
			execString(mCurrentStatement);
Seems to work! :)
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
User avatar
merlinblack
Goblin
Posts: 224
Joined: Thu Mar 15, 2007 10:05 am
Location: Sydney, Australia
x 7

Re: A Lua in game console.

Post by merlinblack »

Hey Jacmoe,
Do you with your Anglescript interpreter support splitting a 'statement' across lines? I studied how it was done in lua.c, so I could enter for example:

Code: Select all

function test() <enter>
print 'Hello' <enter> 
end <enter>
On previous attempts, I didn't do this, and had to enter functions on a single line, which sucked! :P
"He'd never realized that, deep down inside, what he really wanted to do was make things go splat."
Terry Pratchett, Reaper Man
Image
User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
x 179

Re: A Lua in game console.

Post by jacmoe »

I am using a Angelscript executeString helper function at the moment which does the final wrapping, but without using that: yes, it would support multiple lines.
But then you would need either a end-of-script indicator, or a button ('Compile and Run').
I think as a simple console, the simple executeString function does the job.
Let's see. :)
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
User avatar
merlinblack
Goblin
Posts: 224
Joined: Thu Mar 15, 2007 10:05 am
Location: Sydney, Australia
x 7

Re: A Lua in game console.

Post by merlinblack »

You can't do something similar to how my Lua one works? Basically it tries to execute what's entered so far, and if it fails with a "end of file" error, it gives you the chance to add more. (Also now tries sticking "()" on the end as well.
"He'd never realized that, deep down inside, what he really wanted to do was make things go splat."
Terry Pratchett, Reaper Man
Image
User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
x 179

Re: A Lua in game console.

Post by jacmoe »

I can probably do that - haven't looked at it much, to be honest. :)
Tdev from RoR can probably answer your question as he's got a fullblown Angelscript console going.
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
x 179

Re: A Lua in game console.

Post by jacmoe »

I am working on a Lisp in game console :)
Will post code when it's done.
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
x 179

Re: A Lua in game console.

Post by jacmoe »

lispConsole.jpg
:)

Turned out to be simple enough, using ECL.
You have to use C though, but that's not a problem (for me):

Code: Select all

void eclInitCallbacks()
{
	eclCall("(in-package user)");
	cl_def_c_function(c_string_to_object("quit"), (cl_objectfn_fixed)cbQuit, 0);
	eclCall("(in-package user)");
}

cl_object cbQuit()
{
	eclTest::getSingleton().shutdown();

	return Ct;
}
Singletons are really handy when using C code for interfacing.

I'll post some code if someone is interested (and probably after working with it a bit more), but it seems to work nicely. :wink:
You do not have the required permissions to view the files attached to this post.
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.