Creating, Deleting, and Validating Entity Effectiveness

# Course Introduction

Creation and deletion of entities are the most frequently used functions when creating a world. In this course, we'll look at how to create and delete entities, as well as discuss an effectiveness validation function to check the existence of entities.

# Creating Entity

SpawnService provides a function to create an entity. We'll look into `SpawnByEntity` and `SpawnByModelId`, the main functions used when creating entities.

## SpawnByEntity

Creates a new entity based on an entity.

#### Parameter

[{"Parameter":"entity","Type":"Entity","Description":"Specifies the entity to be duplicated."},{"Parameter":"name","Type":"string","Description":"Set the name of the entity that will be created."},{"Parameter":"spawnPosition","Type":"Vector3","Description":"Set the location coordinate where the entity will be created."},{"Parameter":"parent(Optional)","Type":"Entity","Description":"Enter the parent entity of the entity that will be created."},{"Parameter":"includeChild(Optional)","Type":"boolean","Description":"Decide whether you will also copy the child entity of the entity to be duplicated."}]

#### Return Value

  * In case of successful spawning, returns Entity.
  * In case of failed spawning, returns nil.


    
    
    

#### Usage Example

Let's learn how to create an entity identical to the entity placed in a map.

  1. In Preset List, place the entity to be duplicated on the map. [png](16602756252223e544189296248be9e622a6f6aede534)

  2. Generate the new script component SpawnManager. Double-click SpawnManager to open Script Editor, and create the `SpawnByEntity` function.
         
         @Component
         script CloneSpawner extends Component
         method void SpawnByEntity()
         local entity = _EntityService:GetEntityByPath("/maps/map01/monster-8") -- Right click on placed entity - Select Copy Entity Path to get the Path.
         local name = entity.Name .. "Copy" -- Set the entity name to be created
         local spawnPosition = Vector3(0,0,0) -- Set the location to be created
         
         local spawnEntity = _SpawnService:SpawnByEntity(entity,name,spawnPosition)
         if isvalid(spawnEntity) == false then 
             log("Spawn Failed")
         end
         end
         end
         



    
    
    3. Upon completion, add the `OnBeginPlay` function and write as follows.
        ```lua
    @Component
    script EntitySpawner extends Component
        @ExecSpace("ServerOnly")
        method void OnBeginPlay()
        self:SpawnByEntity()
        end
    end
    

  4. Add the SpawnManager script component to common. [png](1659601195286fbb9556ae01c4adb8b44b90ab8e68840)
  5.  Click [Start] to check if an entity identical to the entity placed on the map is created. [png](1655870326527ec7ce48fd9b74ea799d7072cf1ac7f5f)



## SpawnByModelId

#### Description

Assign one model from the models added to Workspace and create as an entity.

#### Parameter

[{"Parameter":"id","Type":"string","Description":"Among the models added to the workspace, enter the Entry ID that will serve as the template for the newly created entity.You can import an Entry ID by selecting Workspace - Model (to become the template for the entity to be created) - Copy Entry ID."},{"Parameter":"name","Type":"string","Description":"Set the name of the entity that will be created."},{"Parameter":"spawnPosition","Type":"Vector3","Description":"Set the location coordinate where the entity will be created."},{"Parameter":"parent","Type":"Entity","Description":"Enter the parent entity of the entity that will be created."}]

#### Return Value

  * In case of successful spawning, returns Entity.
  * In case of failed spawning, returns nil.



#### Usage Example

  1. In Preset List, open the context menu for the desired model, press Add to Workspace to add the model to Workspace. [png](165995860982314bcc1601e8c44d885b2067b34ea32f3)
  2. In the context menu of the added model, press Copy Entry ID to copy the Entry ID to the clipboard. [png](1687760366731d075f28ddc3b4f14ac0791f36257437a)
  3. Open SpawnManager component and create the `SpawnByModelId` function. 
         
         @Component
         script ModelEntitySpawner extends Component
         method void SpawnByModelId()
         local id = "maplestorymonster$0108737afb9548309c03795430b20c05" -- Click Copy Entry ID to paste the copied ID. Remove the preceding "model://".
         local name = "SpawnedEntity" -- Set the entity name to be created
         local spawnPosition = Vector3(0,0,0) -- Set the location to be created
         local parent = _EntityService:GetEntityByPath("/maps/map01") --The parent entity of the entity to be created
         
         local spawnedEntity = _SpawnService:SpawnByModelId(id, name, spawnPosition, parent)
         if isvalid(spawnedEntity) == false then
             log("Spawn Failed")
         end
         end
         end
         



    
    
    4. Modify the `OnBeginPlay` function as below.
        ```lua
    @Component
    script ModelSpawner extends Component
        @ExecSpace("ServerOnly")
        method void OnBeginPlay()
        -- self:SpawnByEntity()
        self:SpawnByModelId()
        end
    end
    

  4.  Click [Start] to check if the same entity as the model in Workspace is created. [png](1655816153693283ae21166b6476ea65044a4ffde1a21)



# Removing Entity

MapleStory Worlds provides two methods to remove entities, `_EntityService:Destroy` and `Entity:Destroy`. `_EntityService:Destroy` deletes an entity that was passed as a parameter, while `Entity:Destroy` deletes the entity itself that called Destroy. Hence, the two functions share the same deletion movement with only a difference in the target.

## Destroy

#### Parameter

[{"index":"Parameter","0":"entity"},{"index":"Description","0":"Enter the entity, which is the target of removal."}]

#### Usage Example

Create an entity via SpawnService's spawn function, then remove it 3 seconds after creation. For the example, use the SpawnManager script component, which was used in the creation of the entity above.

  1. Add a property, and set the type and name as follows. 
         
         @Component
         script SpawnedEntityHolder extends Component
         property any SpawnedEntity = nil
         end
         



    
    
        
    2. Modify the `SpawnByModelId` function as follows.
    
        ```lua
    @Component
    script MonsterModelSpawner extends Component
        method void SpawnByModelId()
        local id = "maplestorymonster$0108737afb9548309c03795430b20c05"
        local name = "SpawnedEntity"
        local spawnPosition = Vector3(0,0,0)
        local parent = _EntityService:GetEntityByPath("/maps/map01")
    
        -- Modify the part below.
        self.SpawnedEntity = _SpawnService:SpawnByModelId(id, name, spawnPosition, parent)
        if isvalid(self.SpawnedEntity) == false then
            log("Spawn Failed")
        end
        end
    end
    
    
    
    

  3. Add the `OnUpdate` function and compose its content as follows. Write a script that deletes the entity 3 seconds after its creation.
         
         @Component
         script TimedDestroyer extends Component
         @ExecSpace("ServerOnly")
         method void OnUpdate(number delta)
         if isvalid(self.SpawnedEntity) == false then
             return
         end
         
         if self._T.time == nil then
             self._T.time = 0
         end
         
         self._T.time = self._T.time + delta
         
         if self._T.time >= 3 then
             _EntityService:Destroy(self.SpawnedEntity)
         end
         end
         end
         



    
    
    5.  Click **[Start]** to check that the entity disappears 3 seconds after its creation.
    
        >**Tip**
        > You can delete entities using `Entity:Destroy`. The following is a script using `Entity:Destroy`.
    
        ```lua
    @Component
    script LifetimeTimer extends Component
        @ExecSpace("ServerOnly")
        method void OnUpdate(number delta)
        if isvalid(self.SpawnedEntity) == false then
            return
        end
    
        if self._T.time == nil then
            self._T.time = 0
        end
    
        self._T.time = self._T.time + delta
    
        if self._T.time >= 3 then
        self.SpawnedEntity:Destroy() -- Replace _EntityService:Destroy with Entity:Destroy.
        end
        end
    end
    

# Entity Effectiveness Validation

When creating or deleting an entity, check the state of the entity. Normally you would perform a nil check of the entity, but you often don't obtain the desired value, such as when the entity is waiting to be deleted, for instance. In this case, you can use the entity effectiveness check feature. Entity effectiveness can be checked via `isvalid`, a global function.

## isvalid

The `isvalid` function checks if an entity is waiting to be deleted or if it has been already deleted, then returns true or false.

#### Parameter

[{"index":"Parameter","0":"entity"},{"index":"Description","0":"Enter the entity, which is the target of effectiveness validation."}]

#### Return Value

  * If the entity passed as a parameter exists, returns true.
  * If the entity is nil, waiting to be deleted, or has already been deleted, returns false.



#### Usage Example

In continuation of the above `Destroy` function example, let's see which value the `isvalid` function returns before and after the deletion of the entity, and how to use the method.

  1. Edit the `OnUpdate` function of SpawnManager as follows.
         
         @Component
         script DelayedEntityDestroyer extends Component
         @ExecSpace("ServerOnly")
         method void OnUpdate(number delta)
         if isvalid(self.SpawnedEntity) == false then
             return
         end
         
         if self._T.time == nil then
             self._T.time = 0
         end
         
         self._T.time = self._T.time + delta
         
         if self._T.time >= 3 then
             local isvalidValue = isvalid(self.SpawnedEntity)
             log("Before deletion : "..tostring(isvalidValue))
             self.SpawnedEntity:Destroy()
             isvalidValue = isvalid(self.SpawnedEntity)
             log("After deletion : "..tostring(isvalidValue))
         end
         end
         end
         



    
    
            
    2.  Click **[Start]** to test. Check the log for before and after entity deletion in the console window.
        [png](1655869031532a1ede31bc9bd46d8b521d0e7b328442f)
    
        > **Tip**
        > Although we usually use the global function `isvalid` for effectiveness check, `EntityService:IsValid(entity)` offers a similar function.
        > So if you modify the above script as follows, the result will be the same.
    
        ```lua
    @Component
    script TimedEntityDestroyer extends Component
        @ExecSpace("ServerOnly")
        method void OnUpdate(number delta)
        if isvalid(self.SpawnedEntity) == false then
            return
        end
    
        if self._T.time == nil then
            self._T.time = 0
        end
    
        self._T.time = self._T.time + delta
    
        if self._T.time >= 3 then
            local isvalidValue = _EntityService:IsValid(self.SpawnedEntity)
            log("Before deletion : "..tostring(isvalidValue))
            self.SpawnedEntity:Destroy()
            isvalidValue = _EntityService:IsValid(self.SpawnedEntity)
            log("After deletion : "..tostring(isvalidValue))
        end
        end
    end