Sentinel

V1.01

Description:

The Sentinel is a package consisting of an NPC that walks or runs around, randomly going from point to point and spotting any player that enters its field of view and is not hiding behind an obstacle. A trigger is used to define the zone inside which the NPC will look for players. Once spotted, a player is teleported to a location with a fade to black effect, with a sound and a message on screen. Advanced users can also broadcast a server wide event to apply custom logic to a player when spotted.

Here is a remixable example game with a few sentinels so you can see how they are used (updated for v1.01):

If you find any bug, or have a comment or a suggestion to make, reply here or find me on discord: Czinczar#3046

Update 1 (v1.01):

  • Removed _G. global table use and replaced with script property for keeping track of players crouching.
  • Added optional ordered destinations: now you can set a path made of nodes that the NPC will follow instead of destinations being random. Read instructions below at point 5 on how to setup.
  • Added optional timer override for each individual node. You can even set a wait time of 0 which will in effect transform the node into a 'passing by node" only. See below at point 7.
  • Players that spawn inside a sentinel trigger are now taken into account.
  • Updated remixable example game.

How to use:

  1. Search for “The Sentinel” in the community tab and install the package.

  2. From the Library tab, bring one “Sentinel” into your game world:


    Drop the NPC Sentinel entity on the NPC property like so:

  3. From the Library tab, bring one “SentinelUser” and attach it to the User template:

  4. From the Library tab, bring one “SentinelPlayer” and attach it to the Player template:

  5. To customize the possible positions the NPC can walk to, look under the “Destinations” folder: for each position you want to add, add a locator under that folder, then another locator under the locator you just added which the NPC will look at once the position is reached. You don’t need to give these locators any particular names but it’s clearer if you do:
    CraytaClient-Win64-Shipping_P6QvlZ98xx
    Since v1.01, you can setup a list of ordered positions: the NPC will move from node to node in numerical order, then it will reverse and go back to the first node, and so on. To set this up, first you have to check the “Ordered Destinations” checkbox as follows:
    image
    Then the names of your destinations MUST BE numbers, like so:
    image
    And that’s all. Now, the NPC will start by going to destination 1, then to 2, then 3 and so on until 6, then it will go back to 5, then 4 and so on until 1, and it will start over from 1. Simply uncheck the “Ordered Destinations” checkbox if you want to go back to random destinations.

  6. Select the sentinel in the game world and look at its properties:

  • Timer is the minimum and maximum time the NPC will stay at each position before walking to another position. A random number of seconds will be picked between these numbers.
  • RunOrWalk let’s you decide if the NPC should walk or run: 1 = Walk, 2 = Run, 3 = Sprint.
  • NPCFoV is the field of view of the NPC and must be a number between 1 and -1. The lower the number, the wider the field of view of the NPC will be: 0.9 is very narrow, 0 is 180° in front, -1 is 360° all around and it’s as if the NPC has eyes on the back of the head. A value between 0.1 and 0.4 is recommended to simulate human peripheral vision.
  • Ordered Destinations will make the NPC move from node to node in the order you want. If you check this, the names of your destinations MUST BE numbers.
  • Default Spot Logic will lock input and teleport the spotted player to the SpottedRebirthPosition with a sound, a fade to black effect and a big “SPOTTED!” message on screen, if checked. Use CustomEventName to apply custom logic if you decide to uncheck this, otherwise nothing will happen at all. Warning: if you disable the default spot logic and apply your own logic, make sure to teleport the player outside of the zone trigger, otherwise some things might break.
  • Custom Event Name is the name of the event that will be broadcast server wide using ‘BroadcastToScripts’ when a player has been spotted. The broadcast will contain the player entity as first parameter. Leave blank if not in use.
  • SpottedRebirthPosition is the position the player will be teleported to when spotted by the NPC. Can be any entity.
  • DestinationsFolder is simply the Destinations locator that contains all the possible NPC destinations. You should not need to touch this.
  • NPC is the NPC entity itself under the sentinel template. Sometimes you need to drag and drop the npc on this property again, even if the property shows that it’s already done.
  • ZoneTrigger is the trigger which will be used by the NPC to spot players. Any player outside this trigger will be ignored.
  1. Since v1.01, you can override the time the NPC will wait at each individual node. To achieve this, simply place a locator as a child of the LookAt locator and rename it to the number of seconds you want the NPC to wait at this node, like so:
    image
    This will effectively override the global timer that has been set in the template properties.
    By setting it to 0, you can use this feature to turn a node into a simple transit point that the NPC will cross without waiting and then move to the next node:
    image

  2. You can change the sound that plays when the player is spotted and the color of the fade to black effect by looking at the SentinelUser template that is attached to the User template:

Updates to expect:

  • Make the npc listen for sound: when the player is running, sprinting or jumping, the npc might have its fov to a full 360° for a short time to force players to adopt a stealthy approach.

  • Make it so that multiple triggers can be used in order to adapt the shape of the zone to different shaped rooms for example.

4 Likes

Hey @Czinczar

This is great, nice to see the NPC being made into something great for gameplay! One thing I noticed is that if the player spawns in the trigger zone then the sential ignores them. It might be worth checking if the player is overlapping any of these triggers when they spawn and making sure they’re accounted for. Does that makes sense?

1 Like

Oh yeah that’s a good point! I should have at least warned that this could be a problem.

For now I will add a warning to the OP and for the next update I will find a solution to this (and I think it will involve IsOverlapping like you suggested, even though I am reticent to check over all players every second or so…).

Thanks for the feedback!

Yeah checking all players wouldn’t be great! I wonder if what would be better is to just check, on player Init, if they’re overlapping any of the triggers. Therefore you’re only checking when a player spawns against all the triggers in the world (rather than getting the triggers to look for players).

Cool package! It’s a really good idea, and I like your execution with trigger, LOS and raycasting to ensure it’s performant and accurate.

Just a thought…it might be better to alter the way you check the players stand/crouch state. Rather than updating a global array of players crouch/stand state (_G.playersCrouching) in your SentinelPlayerScript, and then reading it in your SentinelNpcBehaviorScript I think it might be more optimal to use SentinelPlayerScript to update a property (e.g. isCrouching) and then use player:FindScriptProperty to read it as you are looping through the players in the trigger already.

Yes! Actually in my head I was looking for a ‘player spawned event’, but the player init is exactly that in a way. It would send an event to all triggers and they would check if the player is overlapping or not. Thanks for the suggestion :slight_smile:

1 Like

Is there a problem of performance or compatibility with using the global table? Or maybe looping through _G.playersCrouching is what isn’t optimal here. Either way it’s a good suggestion, and I actually use that in seek&tag (setting a property that represents their team). Thanks for the suggestion!

Even though this package didn’t even deserve a 1k Spark, I will keep updating it just because I like it!

1 Like

With regards to _G it’s also something that is actually not ideal for packages becuase we can’t guarentee it always being supported within the Crayta API. It’s something that isn’t officially supported and therefore could be removed at a later date resulting in packages ending up broken.

It’s an awesome package so I think working on these bits of feedback would be great and don’t forget that updates to the package will make it eligible for the Spark awards for May!

I have updated the sentinel with these changes:

  • Removed _G. global table use and replaced with script property for keeping track of players crouching.
  • Added optional ordered destinations: now you can set a path made of nodes that the NPC will follow instead of destinations being random.
  • Added optional timer override for each individual node. You can even set a wait time of 0 which will in effect transform the node into a ‘passing by node’ only.
  • Players that spawn inside a sentinel trigger are now taken into account.
  • Updated remixable example game.
    Crayta
1 Like

You were right, it’s much cleaner to use the script property, and it’s actually less code!
And I have also set the example game to 1st person camera and it’s soooooo much harder now! (I remembered our build session the other day)

2 Likes