How can I pass updated variables to different classes?

Some background: I have an NPC Spawner creative device with four instances, with two NPCs assigned to each (8 NPCs in total). Depending on a random number (0, 1), the corresponding NPC will be spawned. For example, if “0” is generated, the NPC at index 0 will be spawned. Here’s the array generation:

# Array Control
SpawnerData := class(creative_device):
    var RandomArray :[]int = array{}

    GenerateRandomArray(): void =
        for (i : int = 0 .. 3):
            NewValue : int = GetRandomInt(0,1)
            set RandomArray += array{NewValue}
            Print ("RandomArray[{i}] is now {NewValue}")

This successfully generates four random integers and appends them to RandomArray. However, when I try to reference the updated RandomArray in different classes, I realize that I’m actually referencing the initial empty RandomArray array. Here’s what my NPC spawners are doing:

# NPC Spawner Control (4 Instances)
npc_spawner := class(creative_device):

    @editable
    SpawnerArrayDataRef : SpawnerData = SpawnerData{}
    
    @editable
    NPCSpawners : []npc_spawner_device = array{} # Two NPCs per instances

    @editable
    InstanceID: int = 0

    # Code to enable spawner
    EnableSpawner(Spawner : npc_spawner_device): void =
        Spawner.Enable() 

    # Spawns corresponding NPC
    SpawnNPC() : void =
        for (i := 0 .. SpawnerArrayDataRef.RandomArray.Length - 1):
            if (i = InstanceID):
                if (Spawner := NPCSpawners[SpawnerArrayDataRef.RandomArray[i]]):
                    EnableSpawner(Spawner)
                    Print("Enabling Spawner {i}")

    # Debug
    CheckRandomArray (): void =
        Print("{SpawnerArrayDataRef.RandomArray.Length}")

InstanceID is manually edited in the editor to distinguish between each instance of npc_spawner. The code to call all functions is in a separate manager class:

# RUNS THE GAME
GameManager := class(creative_device):

    @editable
    SpawnerArrayDataRef : SpawnerData = SpawnerData{}

    @editable
    NPCSpawnerRef : npc_spawner = npc_spawner{}

    OnBegin<override>()<suspends>: void =
        SpawnerArrayDataRef.GenerateRandomArray()
        NPCSpawnerRef.SpawnNPC()

On start, SpawnerArrayDataRef.GenerateRandomArray() runs fine, but NPCSpawnerRef.SpawnNPC() does not. After some looking, I realized it was because the functions are referencing the initial RandomArray variable, and not the updated one with values in it. How can I rewrite this so functions reference the new variable?

I’m new to Verse (and programming in general), so this might not be the most optimized way to do things. Any help is appreciated!

Hi,

From what I can tell here’s what’s happening (maybe :slight_smile: ).

In GameManager you have an instance of SpawnerData called SpawnerArrayDataRef.

In npc_spawner you have an instance of SpawnerData also called SpawnerArrayDataRef.

These are two separate instances of SpawnerData, changing one does not affect the other.

in GameManager you initialize it’s SpawnerData instance with a call to SpawnerArrayDataRef.GenerateRandomArray(), but in npc_spawner the code uses the npc_spawner local instance of SpawnerData which is not initialized.

That’s why it’s getting the unchanged array, that instance was never changed.

A solution I think could be to remove “SpawnerArrayDataRef : SpawnerData = SpawnerData{}” from npc_spawner.

Then in GameManager where the code calls NPCSpawnerRef.SpawnNPC() pass in the SpawnerArrayDataRef as a parameter in the SpawnNPC() call.

Hope it helps.

In case you’re not sure how to pass it as a parameter, here’s what I think it would look like.

I didn’t try compiling this, if it doesn’t work let me know and I can try.

First, change SpawnNPC() function so it has a parameter. You probably want to call it something better than ‘Param’. :slight_smile:

    # Spawns corresponding NPC
    SpawnNPC(Param : SpawnerData) : void =
        for (i := 0 .. Param.RandomArray.Length - 1):
            if (i = InstanceID):
                if (Spawner := NPCSpawners[Param.RandomArray[i]]):
                    EnableSpawner(Spawner)
                    Print("Enabling Spawner {i}")

Then, pass the parameter in the call to SpawnNPC().

 OnBegin<override>()<suspends>: void =
        SpawnerArrayDataRef.GenerateRandomArray()
        NPCSpawnerRef.SpawnNPC(SpawnerArrayDataRef)

Hope it helps.

That works! I knew I was missing something.

The code didn’t work right away, but I realized I had some issues with how GameManager references each instance of npc_spawner. Changing the @editable to this:

    @editable
    NPCSpawnerRef : []npc_spawner = array{}

Assigning each instance to the array, and running the following (so it runs for each instance):

# iterates over each instance of NPC Spawner
    SpawnRandomNPCs(): void =    
        for (i : int = 0 .. NPCSpawnerRef.Length - 1):
            if (Spawner := NPCSpawnerRef[i]):
                Spawner.SpawnNPC(SpawnerArrayDataRef)

seemed to do the trick. Thanks so much for your help!

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.