• Advertisement
Sign in to follow this  

Various things

This topic is 4929 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello, *. My name is Dan and I've been making games for ages but I've always steered clear of scripting systems. That is until I started using AngelScript. I found it (almost) compiled out of the box, and implementing it in my game has been a breeze. Having said that, I do have some issues. They are very strange to me and almost certainly my fault. I am using MSVC6 in WinXP. Problem the first: The angelscript says
void UpdateWorld(float dt) {
  // some bs here
}
and the C++ says
  asEngine->CreateContext(&context);
  int functionID = asEngine->GetFunctionIDByDecl("module_dynamo","void UpdateWorld(float)");
  assert(functionID>=0);
  assert(context->Prepare(functionID)>=0);
and the code executes without a hitch. But then I get to using the method
  // float dt=1/240th of a second
  context->SetArguments(0,(unsigned long*)&dt,sizeof(float)/sizeof(DWORD));
  assert(context->Execute()>=0);
I get an assert because Execute returns -1. If, however, I
  RunScriptMethod("UpdateWorld(0.00416f)");
then everything is ok. Why? Problem the second: When I compile and run in Release mode the script is loaded and executed without error but I do not see any results of the script. For example, the UpdateWorld() is called and returns 0 but I do not see the world being updated. I have no preprocessor directives that might be changing my execution path and that includes rendering. Problem the third: There are many many places where I would like to get more comprehensive information from AS and, having stepped through the code, I can see that the information is being sent to various print methods. Unfortunately I have no way to specify an asIOutputStream in those places. I would love to be able to attach a single global output stream that would propagate to all associated objects. Problem the fourth: I tried to comile the library and the executable that uses it as multithreaded but was told of numerous conflicts with MSVCRT. I forced MSVC to ignore MSVCRT and then was told that the system could not locate __imp__strtod() and warned that several methods like assert() were both imported and exported (LNK4049). I do not know why I was getting these messages and, in the end, the only way I could compile was to change everything to single-threaded. Problem the fifth: I would humbly suggest that in future distros the debug build of the statically linked lib have a different name from the release build to prevent problems like trying to step into a release-built module. I have made the change on my local machine and suggest others follow suite. Problem the sixth: Some parts of the overview are out of date. In "Executing a script function" there is a reference to asIContext instead of asIScriptContext. There may be others! Perhaps if these pages were made into a wiki? As I said I'm sure some of these are my fault. However, if anyone knows of what might be causing them and can lend me a hand, please do not hesitate. [Edited by - Aggrav8d on October 22, 2004 5:30:16 PM]

Share this post


Link to post
Share on other sites
Advertisement
Guest Anonymous Poster
Quote:


asEngine->CreateContext(&context);
int functionID = asEngine->GetFunctionIDByDecl("module_dynamo","void UpdateWorld(float)");
assert(functionID>=0);
assert(context->Prepare(functionID)>=0);

I have no preprocessor directives that might be changing my execution path and that includes rendering.



Yes you do. assert.

in release mode, assert(n) compiles to NOTHING

context->Prepare(functionID)>=0 will NEVER be called.

Share this post


Link to post
Share on other sites
Whoops! Well spotted. I must have been suffering a brain fart.

Well that fixes the release mode execution problem. The others are still open.

Share this post


Link to post
Share on other sites
Aaargh, I've written a long answer and the internet connection broke.

---

Hi, Dan. I remember reading some of your tutorials some years ago. Great to hear that you've found my library. I hope it will be satisfying experience for you.

Problem 1:

I can't see any direct cause of the problem (except maybe for the implementation in assert statements that AP noted).

Here's some source code that have been tested with 1.9.2a (taken from teststack.cpp in the test framework).


bool TestStack()
{
bool fail = false;

asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);

COutStream out;
engine->AddScriptSection(0, TESTNAME, script, strlen(script), 0);
int r = engine->Build(0, &out);
if( r < 0 )
{
printf("%s: Failed to build script\n", TESTNAME);
fail = true;
}

asIScriptContext *ctx = 0;
engine->CreateContext(&ctx);
// This call is not necessary
engine->SetDefaultContextStackSize(0, 128); // Minumum stack, 128 byte limit
ctx->Prepare(engine->GetFunctionIDByDecl(0, "void recursive(int)"));
int arg = 100;
ctx->SetArguments(0, (asDWORD*)&arg, 1);
r = ctx->Execute();
if( r != asEXECUTION_EXCEPTION )
{
printf("%s: Execution didn't throw an exception as was expected\n", TESTNAME);
fail = true;
}

ctx->Release();
engine->Release();

return fail;
}



Problem 2:

I understand that this was resolved already.

Problem 3:

I'm not sure I understand your question. The output stream is only used for compiler messages. The output stream can be passed to Build() and to ExecuteString(). Where else do you need messages that you say you don't receive.

Problem 4:

You need to compile both the library and the application using the same settings for C/C++ -> Code Generation -> Use run-time library, otherwise you will get linking conflicts as the AS library tries to use on RT library and the application another.

Problem 5:

Good point. I'll make sure that is made.

Problem 6:

The overview is written more to give the user a quick understanding of what can be done with the library. It's not written to be followed step-by-step as a tutorial. Still I thank you for your correction and will make sure to update it as soon as possible.

A Wiki would be an excellent resource for AngelScript, but I don't think the community is large enough for that yet. I will do what I can to make it grow though.

-----

I hope I was able to resolve some of your problems. If you need more help just let me know, as I will do what I can to make the use of AngelScript as smooth as possible.

It will be great to see what you will do with AngelScript. Please let me know when I can put up a link to your project on the AngelScript users' page.

Regards,
Andreas

Share this post


Link to post
Share on other sites
Thanks for answering, Andreas. Don't sell youself short - it only takes one person at a time to improve on a wiki, and more comprehensive docs would help the community grow.

I have not had a chance yet to run your context test yet. I have been busy debugging my assumptions. Are all global variables in all modules sharing the same namespace? I thought the namespace was per- and not pan-module. What is the distinction between modules and sections, then, if there is no namespace difference? This is a real problem for me. I would like to create a series of object types, each of which has scripting hooks. Then object instances can use those types to achieve unique behaviour. For example, I might have an object type miniboss and type player. the object instance class is the same for both, but the script has changed their behaviour, their onHit() reaction, etc... The problem is that each of the script files may (or may not) have identical global variable names and this makes AS scream. As I said I have tried to load each script as a separate module but I find that the only way to make things run is to ensure that every global has a unique name.

So if there is a way to get per-script namespaces, please let me know what it is.

addendum: I realize now that the problem with the optimized script method was that I did not call Prepare() every time I called Execute(). I thought Prepare() had to be done only the one time to allocate stack space and that after that it was just Execute(). My bad. So that's problems 1 & 2 solved.

Sometimes Build() returns -1 but I get no output. When I step through the code I see that some stuff was sent to be displayed but stopped for one reason or another (such as pre=true). Net effect is that I get a -1 return code and no output message. Very annoying.

I would love to tell you about what I'm using AngelScript for but it is under wraps until I have a working demo. You'll just have to wait and see :)

[Edited by - Aggrav8d on October 24, 2004 3:34:49 PM]

Share this post


Link to post
Share on other sites
I'll investigate into some sort of Wiki software, or maybe write my own for the site. I know it must start somewhere. Thanks for getting me on this track.

The engine configuration is shared between all modules, i.e. registered object types, functions, and properties can be used by all modules.

Each script module has it's own namespace, so declarations in one module don't conflict with declarations in other modules. Script sections are only a way to help management of script files. If you add two script sections to same module it is same thing as if you had concatenated the two before adding it to the module.

It should be possible to do the following:


// AngelScript 1
// Global variable shared for all contexts using this module
int count = 0;
void function()
{
// Do something as player
count++;
}



// AngelScript 2
int count = 0;
void function()
{
// Do something as boss
count++;
}



// C++
// Compile the first script module
engine->AddScriptSection("player", ...);
engine->Build("player");

// Compile the second script module
engine->AddScriptSection("boss", ...);
engine->Build("boss");

// Execute player's function
engine->ExecuteString("player", "function()");

// Execute boss' function
engine->ExecuteString("boss", "function()");


If this doesn't work, then there is a bug somewhere in the library. Please me know if that is so.

Note, that global variables declared in a module are stored with the module and not the context. Thus if you have two contexts calling functions in the same module they will use the same global variables.

Regards,
Andreas

Share this post


Link to post
Share on other sites
I do something like that.
SoundRecording *s_onCollide;
//Texture *t_base;
Texture *t_spinner;

void InitScene() {
s_onCollide=ObtainSoundRecording("bullet.wav");
//t_base=ObtainTexture("static.tga");
t_spinner=ObtainTexture("bar.bmp");
}

void EndScene() {
ReleaseSoundRecording(s_onCollide);
//ReleaseTexture(t_base);
ReleaseTexture(t_spinner);
}

void OnCollide() {
PlaySoundNow(s_onCollide,1.0f,false);
}

I load this same code into two different modules. I also load a third module with a different script. They all run fine. Then I Discard() the two matching scripts and try to call a script method in the third module. I get a crash somewhere inside the engine exception string destructor.

...Now after typing all that I run it again and the problem has magically vanished. God, I hate that. Well, I guess that means there's no problem.

Share this post


Link to post
Share on other sites
I certainly hope that wasn't a bug in my library. I hate tracking down bugs that are not always reproducable. Let me know if the problem shows up again.

Share this post


Link to post
Share on other sites
It appears to be gone. About the linking problem:

my main executable links to fmod/fmodvc.lib glaux.lib glu32.lib opengl32.lib kernel32.lib user32.lib gdi32.lib shell32.lib and advapi32.lib and has a dependency to the angelscript library.

(note that in WIP5 the debug and release libraries still compile to the same filename)

When I compile with these libs I get many warnings about conflicts with MSVCRT*, so I forced MSVC6 to ignore MSVCRT*. Then I compile and the message is as follows:

--------------------Configuration: projectx - Win32 Debug--------------------
Linking...
Creating library Debug/projectx.lib and object Debug/projectx.exp
LINK : warning LNK4049: locally defined symbol "__assert" imported
LINK : warning LNK4049: locally defined symbol "_malloc" imported
LINK : warning LNK4049: locally defined symbol "_free" imported
LINK : warning LNK4049: locally defined symbol "__vsnprintf" imported
LINK : warning LNK4049: locally defined symbol "_strtol" imported
LINK : warning LNK4049: locally defined symbol "_strtoul" imported
angelscriptd.lib(as_string_util.obj) : error LNK2001: unresolved external symbol __imp__strtod
Debug/projectx.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.

projectx.exe - 2 error(s), 6 warning(s)


AS is being compiled as a multithreaded DLL, projectx is being compiled as multithreaded. When I compile them both as single threaded I don't get any of these errors.

So the question is: What did I miss?

Thanks!

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement