Stack overflow AND GetCharacterID [SOLVED]

Started by WHAM, Wed 23/03/2011 17:37:47

Previous topic - Next topic

WHAM

I have a struct that contains a bunch of stats for NPC characters in my game. I need to be able to track a bunch of stats (like health, ammunition etc) for each and every NPC and there can be several hundreds of these generic NPC's.

However, as I try to declare

Code: ags

function game_start() 
{
  NPChar NPC[500];
}


BOOM! I get an error:

An internal error has occurred. Please note down the following information.
If the problem persists, post the details on the AGS Technical Forum.
(ACI version 3.12.1074)

Error: Error running function 'game_start':
Error: stack overflow, attempted grow to 14404 bytes


As far as I can understand, there is some kind of limit to how many variables can be declared in a single function (search revealed a similiar issue from 2004). Any ideas as to how I can work around this? I was going to have a while loop run after this to fill in all the variables contained in this struct using some basic values as well as some random values.
Wrongthinker and anticitizen one. Utterly untrustworthy. Pending removal to memory hole.

Sephiroth

#1
Hello,

If you created a sctruct called NPChar, declared a table of struct like you did, I don't see why you'd need 500 npc in the game, if you really need that much and AGS is limiting the number then you could still split the table in two or more :

Code: ags


NPChar NPC1[100];
NPChar NPC2[100];
NPChar NPC3[100];
NPChar NPC4[100];
NPChar NPC5[100];



I don't know the max number of item for a table of struct , or maybe it is the maximum size of a single table. I used 100 but you get the idea, then use 5 loops to fill them ...

The way you coded that suggests that you'll have 500 different NPCs with distinct stats (templates). Because if not you could use only a few NPC items and recycle (re-assign) them on the fly when you need it.

WHAM

Tested, the cap is around 55 and likely has to do with the number of variables being set in each struct. I am thinking of doing like you suggested, splitting the declaration into:
Code: ags

NPChar NPCRoom1[50]
NPChar NPCRoom2[50]
NPChar NPCRoom3[50]
NPChar NPCRoom4[50]
NPChar NPCRoom5[50]
NPChar NPCRoom6[50]
NPChar NPCRoom7[50]
NPChar NPCRoom8[50]
NPChar NPCRoom9[50]
NPChar NPCRoom10[50]
NPChar NPCRoom11[50]
NPChar NPCRoom12[50]


Now I will have a set of 50 NPC's for each room of the game. This, though, requires me to add a lot of checks to the other scripts. For instance, in a script that causes damage to an enemy, I will have to check player room and then draw the stats for the NPC in question from the correct NPCRoom## array.
Wrongthinker and anticitizen one. Utterly untrustworthy. Pending removal to memory hole.

Sephiroth

An alternative would be to use only one NPChar[50]; and assign the values to it within your loop, but inside each 'room load', I dunno if it fits your game requirements tho.

WHAM

I doubt it would work, as there is a chance the player backtracks and the enemies that lost their ammunition would then regain that ammunition, as well as probably coming back to life as the arrays is recreated on room load.
Wrongthinker and anticitizen one. Utterly untrustworthy. Pending removal to memory hole.

Sephiroth

If it's about the engine limits then I can only suggest that cheap trick, sorry :p

Khris

You aren't seriously declaring the main global dataset of the game INSIDE GAME_START??

A function has only a limited amount of memory for its local variables, so reserving that kind of amount of memory of course leads to an error, but that's not a problem at all since you'll be needing those arrays after game_start has run and thus have to declare them outside anyway.

Any variable declared inside a function is destroyed after the function has finished.

What you need is:

Code: ags
// header

import NPChar NPC[500];

// top of Global.asc

NPChar NPC[500];
export NPC;

WHAM

I feel a wee bit silly now...  :P Khris, as always, is right.
I moved the declaration outside of the game start function and it no longer complains.

Well, at least now I learned something new about AGS functions.
Wrongthinker and anticitizen one. Utterly untrustworthy. Pending removal to memory hole.

Khris

Sorry for sounding condescending.

It just came as a big surprise that you wouldn't know that, having published two games already. :)

WHAM

Let's say that I forgot / got confused / was just being silly and leave it at that.  ;D

My games so far have been quite simple anyway. Just a few characters, objects, animations and regions. No structs or arrays or homemade functions used in either of the two finished games so far, and now that I'm trying to expand my horizons, I seem to get confused by the things that are new to me.

You'd laugh (and probably faint in terror) if you saw the code I used in my first draft of the Infection 2 map generation script. Stuff like that is the reason I rebooted the project and decided to have another project in between to practice arrays and structs first.
Wrongthinker and anticitizen one. Utterly untrustworthy. Pending removal to memory hole.

WHAM

Thought I'd ask this in the same thread:

Is there a way to retrieve the ID number of a character on click? There is a function that apparently retrieves the NAME of the character:
Code: ags

static Character* Character.GetAtScreenXY(int x, int y)


Is it possible to do something similiar with character ID?
Wrongthinker and anticitizen one. Utterly untrustworthy. Pending removal to memory hole.

TomatoesInTheHead

Quote from: WHAM on Thu 24/03/2011 18:07:54
Is it possible to do something similiar with character ID?

There's no own function for this, but you can do with the retrieved Character object whatever you want, for example get its ID:
Code: ags

int charid = -1;
Character* chr = Character.GetAtScreenXY(x, y);
if (chr != null) charid = chr.ID;

This should give you the idea, I mean, ID. The condition is necessary because if there's no character there, the object is null and trying to access its ID would get you a NullPointerException.

WHAM

Works like a charm! I had not realized that the scrip actually called the CHARACTER as an entity. I was under the false impression that the Character.GetAtScreenXY(x, y); function returned the NAME of the character. Now I know better! This will greatly ease my work, thank you once more!
Wrongthinker and anticitizen one. Utterly untrustworthy. Pending removal to memory hole.

SMF spam blocked by CleanTalk