Hi all, back with another late night coding question~
I’m trying to figure out a way to track eliminations of NPC characters, and I thought to use a subscribe event on the npc_spawner_device. Like this:
if (npc_currentSpawnDevice := npc_spawn_listShuffled[index_npcDevice]):
npc_currentSpawnDevice.Spawn()
npc_currentSpawnDevice.EliminatedEvent.Subscribe(OnNPCEliminated)
(pretend the two lines after IF are indented, the block quote formatting removed spaces)
then later after OnBegin function ends
OnNPCEliminated(idkWhatThisThingIs : device_ai_interaction_result) : void =
# increment number of NPCs that are eliminated this wave
Print(“NPC has been eliminated”)
npc_eliminated_this_wave += 1 # would want to increment a variable from outside the function here
(lines after function OnNPCEliminated are indented)
I’m unsure how to increment or collect a value from the function that gets called in the Subscribe event. Is there a way to return a result? Would Handlers help at all here or do they only pass information into the function and not out from the results of the function?
Maybe something with cancelable results would help?
Or maybe some other approach?
Any help would be appreciated!
## Hey, well you can try something like this:
npc_spawn_listShuffled : [ ]npc_spawner_device = array{}
var npc_eliminated_this_wave : int = 0
OnBegin():void=
– set npc_eliminated_this_wave : int = 0
– for (npcDevice : index_npcDevice):
– - - if (npc_currentSpawnDevice := npc_spawn_listShuffled[npcDevice]):
- - — - npc_currentSpawnDevice.Spawn()
- - — - npc_currentSpawnDevice.SpawnedEvent.Subscribe(OnNPCSpawned)
- - — - npc_currentSpawnDevice.EliminatedEvent.Subscribe(EliminateNPC)
EliminateNPC(result : device_ai_interaction_result): void=
– Print(“NPC has been eliminated”)
– set npc_eliminated_this_wave += 1
OnNPCSpawned(NPCAgent : agent): void=
– Print(“NPC Spawned”)
## Here you have device_event_ai_interaction info from documentation, you can get for
instance killer info from this or specific npc
#Payload of device_event_ai_interaction
.
device_ai_interaction_result := struct<epic_internal>:
# Optional agent that triggered the interaction
Source:?agent
#Optional agent targeted by Source
.
Target:?agent
## Cancelables are used to cancel your Subscriptions
Hi thanks for the response!
I think I found how to reference a variable, just as you have set npc_eliminated_this_wave += 1
and with the variable created outside of OnBegin.
I think I was wondering also, this seems like we make the variable global in some scope so the function can access it without having it passed as a parameter, if that makes sense? I didn’t know if this was bad practice, usually I was taught to avoid setting up global variables. At least we can consider it global in the scope of our creative device verse script, right?
I’m still trying to wrap my head around the canceling subscription thing. Is it like we should aim to do that after every subscribe, for example if we have a game that continues round after round and we want to reset those subscribed events?
My code is working for now, in incrementing and decrementing the NPC number. 
1 Like
Hey,
I’m not professional myself, but I think that’s okey to set variables in that way.
Since I’ve started my journey with uefn and verse I had to use cancelables only once. In your case I don’t think that you need it. You will have to use them to avoid double subscriptions, I’m not sure how ot works in “Rounds” but I think that they are restarted. You can always check with prints.
1 Like
Exactly, the variable is defined at class scope (so creative_device scope) which is a good practice, in fact if you were to define the variable at function scope, it would get erased upon leaving that function, which is not what you want
Defining a variable at module scope (e.g. above the creative_device) is tricky to do, because it will require you to use weak_maps, but you won’t need it until you need it, you’ll know eventually
If you ever were to pass the variable as a parameter, only the value of the variable would be copied over to that parameter, so you wouldn’t be able to change the value of that variable if that makes sense
If you’re using fortnite native rounds system, everything in your map will reset correctly, no need to clean anything. Also in your case you don’t want it to cancel during the round since you’d need to keep that elimination handling script going, so I guess it’s fine to keep it
2 Likes
Thanks so much! And yeah, I’m doing rounds but the structure of my lists are arrays for the most part (like arrays of teleporters, arrays of trigger devices, arrays of guard / npc spawners). So when I loop over them, they should only be subscribed to once to cover all of them. That’s good to know about the double subscription thought, I’ll keep that in mind!
Ah many thanks for the clarifying! That helps a lot 
Oh yeah I came from a C++ background back in the day, so I remember passing function parameters by reference (where changing that parameter actually changes the original value where it’s stored). It’s honestly been a while since I picked up coding and messed around with it. Right, normally passing a parameter makes a copy of the value of the variable being passed into the parameter variable, which is separate.
If you’re using fortnite native rounds system, everything in your map will reset correctly, no need to clean anything. Also in your case you don’t want it to cancel during the round since you’d need to keep that elimination handling script going, so I guess it’s fine to keep it
And ok gotcha! This is all really helpful to know, thank you so much!
1 Like