I just finished making a worm AI script that is compatible with both filtering modes that is capable of tunneling through bricks as well as tunneling through air when under a certain height. Right now it is using a model of the Destroyer, a mid to late game boss in the game Terraria. With the current setup it has a total of 82 segments, the same amount of segments it has in Terraria, and does the same amount of damage as well. The script is can support any number of worms with any number of segments[strike], but most of the settings are global in it right now so all worms would behave exactly the same[/strike] and now the script uses template tables full of variables. Each worm, even ones of the same type, can have its own unique values. The worms have Humanoids in them so any Humanoid damaging weapon will work against them. There are a lot of variables that can be changed to customize the behavior of the worms. It is currently on display at this place.
Once I am done fixing bugs with the script and polish it a bit, I will release a copy of it in a free model for everyone to use. Before I do that though, I am going to need to refactor code, add comments, and add support for multiple worm configurations. If you find any bugs, just let me know and I will do my best to fix them. Free model is here. Now that the model is released, show me what you can make with this!
defaultConfigurationTable = {
SegmentCount = 8, --Number of body segments in the worm
Health = 50, --Maximum health of the worm
HeadContactDamage = 3.5, --Damage dealt by the worm's head segment
BodyContactDamage = 2.5, --Damage dealt by the worm's body segments
TailContactDamage = 2, --Damage dealt by the worm's tail segment
GroundHeight = 0, --Height where everything is considered as "ground" by the AI
MinimumTravelDepth = -1e6, --Depth where the worm avoids reaching (will automatically change to Workspace.FallenPartsDestroyHeight + 10 if below it)
AttackDepth = 100, --How far below the target the worm travels before charging at the target
Speed = 50, --Maximum movement speed of worm (will slow down if too much speed is gained while in the air)
Acceleration = 25, --Acceleration rate towards target destination
Gravity = 10, --Downwards acceleration due to gravity
MinimumAttackSpeed = 40, --Movement speed towards the target required to surface
SegmentPartSize = Vector3.new(1,1,1), --Size of each segment part
MinimumDamageSpeed = 10, --Minimum speed required for segments to damage objects
HeadSegmentModel = destroyerSegmentModels.Head, --Model for the worm's head segment
BodySegmentModel = destroyerSegmentModels.Segment, --Model for the worm's body segment
TailSegmentModel = destroyerSegmentModels.Tail, --Model for the worm's tail segment
UpdateFrameSkip = 3, --How many frames the worm AI should skip target position updates
--[[Finds a new target when the current target is lost
Parameters:
table worm - Contains AI data for the worm. Table includes all configuration data for its AI type as well as:
Model Model - A model containing all of the server sided segments. All segments are invisible and not collidable
table Segments - A table containing all of the segment parts
BasePart Target - The part that the worm moves towards
]]
FindNewTarget = function(wormAI) end,
--[[
Re-evaluates the current target to check if the target is valid. Returns true if the target is valid, returns false if it isn't.
Parameters:
table worm - Contains AI data for the worm. Table includes all configuration data for its AI type as well as:
Model Model - A model containing all of the server sided segments. All segments are invisible and not collidable
table Segments - A table containing all of the segment parts
BasePart Target - The part that the worm moves towards
]]
ReevaluateTarget = function(wormAI) end,
--[[
Fired when the worm hits an object.
Parameters:
table wormAI - Contains AI data for the worm. Table includes all configuration data for its AI type as well as:
Model Model - A model containing all of the server sided segments. All segments are invisible and not collidable
table Segments - A table containing all of the segment parts
BasePart Target - The part that the worm moves towards
Part segment - The segment that hit the object.
BasePart object - The object the segment hit.
]]
HitObject = function(wormAI,segment,object)end
}
[size=2]save yourself the headache and just copy and paste this to a text editor if you want to see this[/size]
[ol]
[li]Use require() on the WormAI ModuleScript and save the table returned to a variable.[/li]
[li]To add a new worm AI template, call RegisterAIType(table variableOverwrites) in the table from step 1 and pass a table containing variable overwrite values to it. The template will be named after the “Name” field in the overwrite table that was passed and will be used when spawning new worms. Make sure you overwrite the SegmentPartSize, HeadSegmentModel, BodySegmentModel, and TailSegmentModel variables if you wish to use a new model for the worm.[/li]
[li]To spawn a new worm from a template, call NewWorm(value name,Vector3 position) and pass the name of the template as well as a desired spawn position. The function will return a table containing a copy of all the variables along with a few extras that are listed in the above spoiler.[/li]
[/ol]
That is all you have to do to create your own customized worm! There are a few callback functions that can be overwritten to customize the behavior further. I may be adding more callbacks that can be overwritten in the future. Since the model is open source you can just modify the AI script if you really need to change currently unchangeable behavior.
Example usage:
wormAI = require(game.ServerScriptService.WormAI)
dogeSegmentModel = game.ReplicatedStorage.DogeWormSegments
wormAI.RegisterAIType {
Name = "DogeWorm",
SegmentCount = 100,
HeadSegmentModel = dogeSegmentModel.Head,
BodySegmentModel = dogeSegmentModel.Segment,
TailSegmentModel = dogeSegmentModel.Tail,
Gravity = 50,
HitObject = function(wormAI,segment,object)
print("Wow!")
end
}
dogeWormAI = wormAI.NewWorm("DogeWorm",Vector3.new(0,10,0))
dogeWormAI.Speed = 100
Note about requiring by model ID: I cannot make this model able to be required using the ID alone because the worm AI uses a LocalScript to display worms and it must be added to a location where the script will not be lost or constantly replaced (such as the StarterGui in games with RestartPlayerGuiOnSpawn set to true) and there is no guarantee the script will make it to ReplicatedFirst before the first player joins.
Note about building a model for a worm: To make a working model, just build one copy of a head, body, and tail segment and group each segment into their own Model object. Each segment model must have a “Main” part that the segment is centered around. The front side of the “Main” part connects to the segment in front, and the back side connects to the segment in the back. It is recommended to make all parts note collide-able and anchored or else (more) lag and/or weird behavior may occur.