Help with spawning / despawning

User avatar
DoctorX
Trespasser
Posts: 57
Joined: 10 Mar 2016, 00:36

Help with spawning / despawning

Postby DoctorX » 19 Mar 2017, 16:03

This one is giving me fits, probably because it's my first time delving into any major work with spawing objects, so hopefully I'm just missing something stupid...

Myself and some users have been experiencing a random crash with my Dynamic Anomalies addon. From testing by starting a new game and simply travelling back and forth from Yantar to Wild Territory, after a random amount of times doing that it will CTD when loading Yantar.

Here is the end of the crashlog when the crash occurs while loading Yantar:

Code: Select all

* [DETAILS] VertexConsts(256), Batch(61)
* [DETAILS] 11590 v(20), 6100 p
* [DETAILS] Batch(61), VB(226K), IB(35K)
* phase time: 18 ms
* phase cmem: 306076 K
* Loading HOM: e:\programs\s.t.a.l.k.e.r. - cotz\gamedata\levels\l08_yantar\level.hom
* phase time: 16 ms
* phase cmem: 306208 K
* phase time: 15 ms
* phase cmem: 306208 K
* phase time: 14 ms
* phase cmem: 306208 K
* t-report - base: 1548, 726041 K
* t-report - lmap: 8, 8193 K
* WARNING: player not logged in
! Can't find texture 'map\map_l12u_control_monolith'
* phase time: 2555 ms
* phase cmem: 314979 K
* phase time: 15 ms
* phase cmem: 314979 K
* [win32]: free[2435036 K], reserved[124508 K], committed[1634696 K]
* [ D3D ]: textures[783480 K]
* [x-ray]: process heap[314979 K], game lua[27022 K], render[4319 K]
* [x-ray]: economy: strings[18790 K], smem[10890 K]
DRX DA: Dynamic anomaly field zone_mine_gravitational_weak spawned at yan_smart_terrain_snork_u
compiling shader particle_alphaonly
compiling shader model_distort_0
stack trace:


(Nothing further after stack trace)

Here is the same log when it works while loading Yantar:

Code: Select all

* [DETAILS] VertexConsts(256), Batch(61)
* [DETAILS] 11590 v(20), 6100 p
* [DETAILS] Batch(61), VB(226K), IB(35K)
* phase time: 14 ms
* phase cmem: 286781 K
* Loading HOM: e:\programs\s.t.a.l.k.e.r. - cotz\gamedata\levels\l08_yantar\level.hom
* phase time: 13 ms
* phase cmem: 286979 K
* phase time: 12 ms
* phase cmem: 286978 K
* phase time: 10 ms
* phase cmem: 286979 K
* t-report - base: 1483, 683791 K
* t-report - lmap: 8, 8193 K
* WARNING: player not logged in
! Can't find texture 'map\map_l12u_control_monolith'
* phase time: 2579 ms
* phase cmem: 297817 K
* phase time: 16 ms
* phase cmem: 297817 K
* [win32]: free[2657732 K], reserved[94256 K], committed[1442252 K]
* [ D3D ]: textures[733037 K]
* [x-ray]: process heap[297817 K], game lua[25300 K], render[194 K]
* [x-ray]: economy: strings[17922 K], smem[7797 K]
DRX DA: Dynamic anomaly field zone_mine_gravitational_strong spawned at yan_smart_terrain_2_5
DRX DAZ: Dynamic anomaly field zone_mine_gravitational_strong spawned at yan_smart_terrain_4_4
compiling shader particle_alphaonly
compiling shader model_distort_0
compiling shader deffer_model_bump_d-hq_1
compiling shader accum_emissivel
compiling shader model_distort4glass_0
compiling shader model_env_lq_2
compiling shader model_distort4glass_2
compiling shader model_def_lq
compiling shader model_def_lq_0
compiling shader deffer_model_bump_d-hq_3
compiling shader deffer_model_bump_d-hq_2
compiling shader deffer_model_flat_2
collectgarbage before=24217096Kb
collectgarbage after=18747484Kb
[LSS] Spawning object [zone_mine_gravitational_strong25601][zone_mine_gravitational_strong][25601]
[LSS] Spawning object [zone_mine_gravitational_strong25602][zone_mine_gravitational_strong][25602]
[LSS] Spawning object [zone_mine_gravitational_strong25603][zone_mine_gravitational_strong][25603]
[LSS] Spawning object [zone_mine_gravitational_strong25604][zone_mine_gravitational_strong][25604]
[LSS] Spawning object [zone_mine_gravitational_strong25605][zone_mine_gravitational_strong][25605]
[LSS] Spawning object [zone_mine_gravitational_strong25606][zone_mine_gravitational_strong][25606]
[LSS] Spawning object [zone_mine_gravitational_strong25607][zone_mine_gravitational_strong][25607]
[LSS] Spawning object [zone_mine_gravitational_strong25608][zone_mine_gravitational_strong][25608]
[LSS] Spawning object [zone_mine_gravitational_strong25609][zone_mine_gravitational_strong][25609]
[LSS] Spawning object [zone_mine_gravitational_strong25610][zone_mine_gravitational_strong][25610]
[LSS] Spawning object [zone_mine_gravitational_strong25611][zone_mine_gravitational_strong][25611]
[LSS] Spawning object [zone_mine_gravitational_strong25612][zone_mine_gravitational_strong][25612]
[LSS] Spawning object [zone_mine_gravitational_strong25613][zone_mine_gravitational_strong][25613]
[LSS] Spawning object [zone_mine_gravitational_strong25614][zone_mine_gravitational_strong][25614]
[LSS] Spawning object [zone_mine_gravitational_strong25615][zone_mine_gravitational_strong][25615]
[LSS] Spawning object [zone_mine_gravitational_strong25616][zone_mine_gravitational_strong][25616]
[LSS] Spawning object [zone_mine_gravitational_strong25617][zone_mine_gravitational_strong][25617]


Looks like the crash occurs right around or during garbage collection.

Here is the script, anyone see anything glaring with it?

Code: Select all

--=============================================================
--
-- Dynamic Anomaly Generator (drx_dynamic_anomaly.script)
--   CoC 1.4.22 - DoctorX Dynamic Anomalies 1.1
--
--   - Setting file: configs\plugins\drx\drx_dynamic_anomaly.ltx
--
--   Created by: DoctorX
--   Last revised: March 15, 2017
--
--=============================================================


-- ////////////////////////////////////////////////////////////////////////////////////////////////
--
-- Settings File
--
--   Created by DoctorX
--   for DoctorX Dynamic Anomalies 1.0
--   March 14, 2017
--
-- ------------------------------------------------------------------------------------------------

-- Location of the settings file:
local ini = ini_file( "plugins\\drx\\drx_dynamic_anomaly.ltx" )

-- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\


-- ////////////////////////////////////////////////////////////////////////////////////////////////
--
-- drx_da_dynamic_anom_list array
--
--   Created by DoctorX
--   for DoctorX Dynamic Anomalies 1.0
--   March 13, 2017
--
-- ------------------------------------------------------------------------------------------------

-- Array containing the id of each dynamically spawned anomaly:
local drx_da_dynamic_anom_list = {}

-- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\


-- ////////////////////////////////////////////////////////////////////////////////////////////////
--
-- drx_da_spawn_anomaly_field function
--
-- ------------------------------------------------------------------------------------------------
--
--   Description:
--      - Creates an anomaly field at a specified smart terrain
--
--   Usage:
--      drx_da_spawn_anomaly_field( smart_name, anomaly_type, anomaly_number )
--
--   Parameters:
--      smart_name (type: string, smart terrain name)
--         - Name of the smart terrain to spawn the anomaly field at
--      anomaly_type (type: string, anomaly type name)
--         - Type of anomaly to spawn
--      anomaly_number (type: int)
--         - Number of anomalies to include in the anomaly field
--
--   Ini requirements:
--      plugins\drx\drx_dynamic_anomaly.ltx
--         [anomaly_properties]
--            object_flags (type: int)
--               - Object flags to apply to the created anomalies (default = 31)
--            restrictor_type (type: int)
--               - Restrictor type of the created anomaly (default = 0)
--            radius (type: float, meters)
--               - Radius of each created anomaly (default = 3)
--         [location_offset]
--            max_offset_x (type: float, meters)
--               - Magnitude of maximum offset from smart terrain center in x (north-south) direction (default = 0)
--            max_offset_y (type: float, meters)
--               - Magnitude of maximum offset from smart terrain center in y (up-down) direction (default = 0)
--            max_offset_z (type: float, meters)
--               - Magnitude of maximum offset from smart terrain center in z (east-west) direction (default = 0)
--
--   Return value (type: nil):
--      none, creates the anomaly field
--
--   Notes:
--      - Each anomaly will be given a random offset from the center of the specified terrain, the maximum extent defined in the ini file
--      - The radius setting in the ini file refers to the radius of each anomaly, not the entire anomaly field
--      - Spawning anomalies only seems to take effect on the current level the actor is on
--      - The id of each spawned anomaly is stored in the drx_da_dynamic_anom_list array
--
-- ------------------------------------------------------------------------------------------------
--   Created by DoctorX
--   for DoctorX Dynamic Anomalies 1.1
--   Last modified March 15, 2017
-- ------------------------------------------------------------------------------------------------

-- Spawn an anomaly field at a specified location:
function drx_da_spawn_anomaly_field( smart_name, anomaly_type, anomaly_number )

   -- Get the specified smart:
   local smart = SIMBOARD.smarts_by_names[smart_name]
   if not ( smart ) then
      printf( "DRX DA Error: drx_da_spawn_anomaly_field - Unable to dynamic anomaly field, specified smart location does not exist!" )
      return
   end

   -- Get maximum offset values:
   local max_offset_x = (ini:r_float_ex( "location_offset", "max_offset_x" ) or 0)
   local max_offset_y = (ini:r_float_ex( "location_offset", "max_offset_y" ) or 0)
   local max_offset_z = (ini:r_float_ex( "location_offset", "max_offset_z" ) or 0)

   -- Create each anomaly in the anomaly field:
   for i = 1, ( anomaly_number ) do

      -- Randomly offset anomaly x position from center of smart terrain:
      local offset_x = (max_offset_x * math.random( ))
      if (math.random( ) <= 0.5) then
         offset_x = -(offset_x)
      end
      local pos_x = (smart.position.x + offset_x)

      -- Randomly offset anomaly y position from center of smart terrain:
      local offset_y = (max_offset_y * math.random( ))
      if (math.random( ) <= 0.5) then
         offset_y = -(offset_y)
      end
      local pos_y = (smart.position.y + offset_y)

      -- Randomly offset anomaly z position from center of smart terrain:
      local offset_z = (max_offset_z * math.random( ))
      if (math.random( ) <= 0.5) then
         offset_z = -(offset_z)
      end
      local pos_z = (smart.position.z + offset_z)

      -- Set anomaly position:
      local pos = vector( ):set( pos_x, pos_y, pos_z )

      -- Spawn anomaly at specified location:
      local sim = alife( )
      local se_obj = sim:create( anomaly_type, pos, smart.m_level_vertex_id, smart.m_game_vertex_id )
      if not ( se_obj ) then
         printf( "DRX DA Error: drx_da_spawn_anomaly_field - Unable to spawn dynamic anomaly!" )
      else

         -- Add the spawned anomaly id to the dynamic anomaly list:
         table.insert( drx_da_dynamic_anom_list, se_obj.id )

         -- Set anomaly properties:
         local data = stpk_utils.get_object_data( se_obj )
         if ( data ) then
            data.object_flags = (ini:r_float_ex( "anomaly_properties", "object_flags" ) or 31)
            data.restrictor_type = (ini:r_float_ex( "anomaly_properties", "restrictor_type" ) or 0)
            data.shapes = {}
            data.shapes[1] = {}
            data.shapes[1].shtype = 0
            data.shapes[1].offset = vector( ):set( 0, 0, 0 )
            data.shapes[1].radius = (ini:r_float_ex( "anomaly_properties", "radius" ) or 3)
            stpk_utils.set_object_data( data, se_obj )
         else
            printf( "DRX DA Error: drx_da_spawn_anomaly_field - Unable to set dynamic anomaly properties!" )
         end

      end
   end

   -- Send update to the console:
   printf( "DRX DA: Dynamic anomaly field spawned at %s", smart_name )

end

-- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\


-- ////////////////////////////////////////////////////////////////////////////////////////////////
--
-- drx_da_spawn_anomalies_current_level function
--
-- ------------------------------------------------------------------------------------------------
--
--   Description:
--      - Creates random anomaly fields at random locations on the current map
--
--   Usage:
--      drx_da_spawn_anomalies_current_level( )
--
--   Parameters:
--      none
--
--   Ini requirements:
--      plugins\drx\drx_dynamic_anomaly.ltx
--         [anomaly_types]
--            {anomaly type name} (type: string, anomaly name)
--               - List of potential anomalies to spawn
--         [field_properties]
--            anomaly_max_number (type: int)
--               - Maximum number of anomalies in each anomaly field (default = 0)
--            spawn_percent (type: float, decimal percent)
--               - Percent chance an anomaly field will be spawned at a specific smart (default = 0)
--         [{level name}]
--            {smart terrain name} (type: string, smart terrain name)
--               - List of allowable smart terrain names for each level for anomaly fields to spawn
--
--   Return value (type: nil):
--      none, creates random anomaly fields on the current map
--
--   Notes:
--      - The actor must be on a map when this function is called
--      - The maximum number of anomaly fields spawned on the map and the maximum number of anomalies in each field is specified in the ini file
--      - Allowable smart terrains for the current map must be specified in the ini file for dynamic anomaly fields to spawn on the current level
--
-- ------------------------------------------------------------------------------------------------
--   Created by DoctorX
--   for DoctorX Dynamic Anomalies 1.0
--   Last modified March 14, 2017
-- ------------------------------------------------------------------------------------------------

-- Spawn random anomaly fields at a random locations on the current map:
function drx_da_spawn_anomalies_current_level( )

   -- Get the current level name:
   local level_name = level.name( )
   if ( (not level_name) or (level_name == "") ) then
      printf( "DRX DA Error: drx_da_spawn_anomalies_current_level - Cannot spawn dynamic anomaly, actor not on a level" )
      return
   end

   -- Build a list of available smart terrains:
   local smart_list = alun_utils.collect_section( ini, level_name )
   if ( (not smart_list) or (#smart_list < 1) ) then
      return
   end

   -- Get the percent chance for anomalies to spawn:
   local spawn_percent = (ini:r_float_ex( "field_properties", "spawn_percent" ) or 0)
   if ( (not spawn_percent) or (spawn_percent == 0) ) then
      return
   end

   -- Determine the maximum amount of anomalies to spawn in each anomaly field:
   local anomaly_max_number = (ini:r_float_ex( "field_properties", "anomaly_max_number" ) or 0)
   if ( (not anomaly_max_number) or (anomaly_max_number < 1) ) then
      return
   end

   -- Build a list of available anomaly types:
   local anomaly_list = alun_utils.collect_section( ini, "anomaly_types" )
   if ( (not anomaly_list) or (#anomaly_list < 1) ) then
      printf( "DRX DA Error: drx_da_spawn_anomalies_current_level - No dynamic anomaly types found!" )
      return
   end

   -- Delete any existing dynamic anomalies:
   drx_da_release_dynamic_anomalies( )

   -- Spawn each dynamic anomaly field at random locations on the current map:
   for i = 1, ( #smart_list ) do

      -- Determine if an anomaly field should be spawned at the current smart location:
      if ( math.random( ) <= spawn_percent ) then

         -- Choose an anomaly field type to spawn:
         local anomaly_type = anomaly_list[math.random( #anomaly_list )]

         -- Determine the number of anomalies to spawn in the field:
         local anomaly_number = math.random( anomaly_max_number )

         -- Spawn the anomaly field at the current smart location:
         drx_da_spawn_anomaly_field( smart_list[i], anomaly_type, anomaly_number )

      end

   end

end

-- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\


-- ////////////////////////////////////////////////////////////////////////////////////////////////
--
-- drx_da_release_dynamic_anomalies function
--
-- ------------------------------------------------------------------------------------------------
--
--   Description:
--      - Releases (deletes) all dynamic anomalies that were spawned
--
--   Usage:
--      drx_da_release_dynamic_anomalies( )
--
--   Parameters:
--      none
--
--   Return value (type: nil):
--      none, deletes the anomalies
--
-- ------------------------------------------------------------------------------------------------
--   Created by DoctorX
--   for DoctorX Dynamic Anomalies 1.0
--   Last modified March 14, 2017
-- ------------------------------------------------------------------------------------------------

-- Delete all dynamic anomalies:
function drx_da_release_dynamic_anomalies( )

   -- Validate dynamic anomaly list:
   if ( (not drx_da_dynamic_anom_list) or (#drx_da_dynamic_anom_list < 1) ) then
      return
   end

   -- Release each anomaly in the list:
   local sim = alife( )
   for i = 1, ( #drx_da_dynamic_anom_list ) do
      local se_obj = sim:object( drx_da_dynamic_anom_list[i] )
      if ( se_obj ) then
         safe_release_manager.release( se_obj )
      end
   end

   -- Empty the anomaly list:
   drx_da_dynamic_anom_list = {}

   -- Send update to the console:
   printf( "DRX DA: Dynamic anomalies cleared" )

end

-- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\


-- ////////////////////////////////////////////////////////////////////////////////////////////////
--
-- drx_da_on_game_load_callback function
--
-- ------------------------------------------------------------------------------------------------
--
--   Description:
--      - Scripts to run when a game loads or level change occurs
--
--   Usage:
--      (called when a game loads or level change occurs)
--
--   Parameters:
--      none
--
--   Return value (type: nil):
--      none
--
-- ------------------------------------------------------------------------------------------------
--   Created by DoctorX
--   for DoctorX Dynamic Anomalies 1.0
--   Last modified March 13, 2017
-- ------------------------------------------------------------------------------------------------

-- Scripts to run when the game loads:
local function drx_da_on_game_load_callback( )

   -- Generate new dynamic anomalies:
   drx_da_spawn_anomalies_current_level( )

end

-- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\


-- ////////////////////////////////////////////////////////////////////////////////////////////////
--
-- drx_da_on_level_changing_callback function
--
-- ------------------------------------------------------------------------------------------------
--
--   Description:
--      - Scripts to run when a level change is about to occur
--
--   Usage:
--      (called when a level change is about to occur)
--
--   Parameters:
--      none
--
--   Return value (type: nil):
--      none
--
-- ------------------------------------------------------------------------------------------------
--   Created by DoctorX
--   for DoctorX Dynamic Anomalies 1.0
--   Last modified March 13, 2017
-- ------------------------------------------------------------------------------------------------

-- Scripts to run when a level change is about to occur:
local function drx_da_on_level_changing_callback( )

   -- Delete dynamic anomalies:
   drx_da_release_dynamic_anomalies( )

end

-- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\


-- ////////////////////////////////////////////////////////////////////////////////////////////////
--
-- on_game_start function
--
-- ------------------------------------------------------------------------------------------------
--
--   Description:
--      - Registers callback scripts
--
--   Usage:
--      (called when a game session begins)
--
--   Parameters:
--      none
--
--   Return value (type: nil):
--      none
--
-- ------------------------------------------------------------------------------------------------
--   Added by DoctorX
--   for DoctorX Dynamic Anomalies 1.0
--   Last modified March 12, 2017
-- ------------------------------------------------------------------------------------------------

-- Register callback scripts:
function on_game_start( )
   RegisterScriptCallback( "on_game_load", drx_da_on_game_load_callback )
   RegisterScriptCallback( "on_level_changing", drx_da_on_level_changing_callback )
end

-- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

User avatar
Alundaio
S.T.A.L.K.E.R.
Posts: 1372
Joined: 26 May 2012, 22:26

Re: Help with spawning / despawning

Postby Alundaio » 19 Mar 2017, 18:29

It may be the packet reading, try with the latest stpk_utils.script from the repo: https://bitbucket.org/revo_lucas/call-o ... ils.script


https://bitbucket.org/revo_lucas/call-o ... e3?at=main
= Fix r_vec3 reading in stpk_utils.script


Also anom zone should be using *_se_zone_properties_packet not *_se_zone_anom_properties_packet apparently
"I have a dream that one day this community will rise up and live out the true meaning of its creed: "We hold these truths to be self-evident; that all mods are created equal."

User avatar
DoctorX
Trespasser
Posts: 57
Joined: 10 Mar 2016, 00:36

Re: Help with spawning / despawning

Postby DoctorX » 01 Apr 2017, 14:15

Looks like the problem had to do with explicitly deleting the anomalies on level change. Once I took that out the problem went away and, much to my astonishment, the anomalies cleared themselves on level change anyway.

Trying to be responsible and clean up my own objects caused problems. Being lazy and letting it do it itself doesn't.

Slav logic. Gotta love it.

Thanks again for the help!

User avatar
DoctorX
Trespasser
Posts: 57
Joined: 10 Mar 2016, 00:36

Re: Help with spawning / despawning

Postby DoctorX » 09 Apr 2017, 10:48

Ok, disregard my last post. One of the 16,000 times and counting I thought I got it right only to be sadly mistaken. :suicide:

So I tried attacking the problem from a different angle. Instead of releasing the anomalies and creating new anomalies every time, I tried spawning them once, then teleporting them to a different position every time the game loads using the TeleportObject function. Here is a snippet of the test code that is called on_game_load:

Code: Select all

   if ( utils.load_var( db.actor, ("drx_da_anomalies_spawned_" .. level_name), false ) == true ) then
      local anom_id = utils.load_var( db.actor, "drx_da_anom_id_level_name_1a" )
      if ( anom_id ) then
         local smart = SIMBOARD.smarts_by_names["bar_zastava_dogs_lair_2"]
         local pos = drx_da_generate_position( "bar_zastava_dogs_lair_2", 10, 0, 50 )
         TeleportObject( anom_id, pos, smart.m_level_vertex_id, smart.m_game_vertex_id )
         printf( "DRX DA: Anomaly teleported" )
      end
      return
   end


Works great, I can start a new game in Rostok, quicksave and quickload indefinately and the anomaly happily moves to different locations around the smart as intended. UNTIL I EXIT THE GAME COMPLETELY AND THEN TRY TO LOAD THE PREVIOUS QUICKSAVE. Then it fails to spawn the anomaly and displays this error on the console:

Code: Select all

[LSS] Spawning object [zone_mine_gravitational_weak23297][zone_mine_gravitational_weak][23297]
ERROR: CGameObject:net_spawn() Object with ID already exists! ID=23297 self=zone_mine_gravitational_weak23297 other=zone_mine_gravitational_weak23297
assertion !m_crows[1].empty() failed: 1
0 bar_vodka_0009
! Failed to spawn entity 'zone_mine_gravitational_weak'


If I exit the game at this point, it will crash while closing.

I suspect I am storing or calling the anomaly id improperly? When the anomaly is first created I store the id with utils.save_var( db.actor, "drx_da_anom_id_level_name_1a", se_obj.id )

I have tested if the object is valid by calling alife( ):object( anom_id ), which does return a valid object. Interestingly, and perhaps related to the problem, I have never been able to successfully retrieve the object using level.object_by_id( anom_id ).

Any thoughts?


Return to “General Discussion”

Who is online

Users browsing this forum: No registered users and 2 guests