
Zombies+
Minecraft Mod
Project Overview
Zombies+ is a comprehensive Minecraft mod that enhances the zombie experience in the game. This project represents a significant milestone in my Java development journey, achieving over 140,000 downloads across multiple platforms. The mod introduces new zombie variants, behaviors, and gameplay mechanics that seamlessly integrate with Minecraft's existing systems.
Through this project, I refined my understanding of Java programming, object-oriented design patterns, and the Minecraft modding ecosystem. The mod's success demonstrates my ability to create engaging content that resonates with a large community of players.
Skills & Learning Outcomes
- •Advanced Java programming and object-oriented design principles
- •Proficiency with IntelliJ IDEA Community Edition development environment
- •Minecraft Forge API and modding framework expertise
- •Game balance and player experience design
- •Large-scale community management and user feedback integration (140k+ downloads)
Project Gallery

















The abstract base class that all zombie variants extend from. This class handles core zombie behavior, animations, and spawn conditions:
package net.trial.zombies_plus.entity.custom;
import net.minecraft.client.model.geom.ModelPart;
import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.RandomSource;
import net.minecraft.world.Difficulty;
import net.minecraft.world.entity.*;
public abstract class abstractZombieEntity extends Zombie {
public final AnimationState idleAnimationState = new AnimationState();
private int idleAnimationTimeout = 0;
private boolean hasSetupAnim = false;
private boolean leftArmVisible = true;
private boolean rightArmVisible = true;
private static boolean isAggro = false;
public abstractZombieEntity(EntityType<? extends Zombie> pEntityType, Level pLevel) {
super(pEntityType, pLevel);
this.refreshDimensions();
}
public ResourceLocation getTexture(){
return new ResourceLocation("minecraft", "textures/entity/zombie/zombie.png");
}
public static boolean getAggressiveState(){
return isAggro;
}
@Override
public boolean isAggressive() {
isAggro = super.isAggressive();
return isAggro;
}
@Override
protected boolean convertsInWater() {
return false;
}
public float rotlerpRad(float pAngle, float pMaxAngle, float pMul) {
float f = (pMul - pMaxAngle) % ((float)Math.PI * 2F);
if (f < -(float)Math.PI) {
f += ((float)Math.PI * 2F);
}
if (f >= (float)Math.PI) {
f -= ((float)Math.PI * 2F);
}
return pMaxAngle + pAngle * f;
}
@Override
public void tick() {
super.tick();
if(this.level().isClientSide()) {
setupAnimationStates();
}
}
protected void setupAnimationStates() {
if(this.idleAnimationTimeout <= 0) {
this.idleAnimationTimeout = this.random.nextInt(40) + 80;
this.idleAnimationState.start(this.tickCount);
} else {
--this.idleAnimationTimeout--;
}
}
@Override
public void setBaby(boolean pChildZombie) {
// Prevents baby zombies
}
@Override
protected void updateWalkAnimation(float pPartialTick) {
float f;
if(this.getPose() == Pose.STANDING) {
f = Math.min(pPartialTick * 6F, 1f);
} else {
f = 0f;
}
this.walkAnimation.update(f, 0.2f);
}
public static boolean canSpawnDuringDay(ServerLevelAccessor pLevel, BlockPos pPos, RandomSource pRandom) {
DimensionType dimensiontype = pLevel.dimensionType();
int i = dimensiontype.monsterSpawnBlockLightLimit();
if (i < 15 && pLevel.getBrightness(LightLayer.BLOCK, pPos) > i) {
return false;
}
int j = pLevel.getLevel().isThundering() ? pLevel.getMaxLocalRawBrightness(pPos, 10) : pLevel.getMaxLocalRawBrightness(pPos);
return j <= dimensiontype.monsterSpawnLightTest().sample(pRandom);
}
@Override
public EntityDimensions getDimensions(Pose pPose) {
return EntityDimensions.scalable(DEFAULT_BB_WIDTH, 2f);
}
}Click to expand and view the full code implementation.

Junk Food Additions
Minecraft Mod
Project Overview
Junk Food Additions is a fun and creative Minecraft mod that adds a variety of junk food items to the game. This project served as an excellent learning experience in texture creation and item implementation within Minecraft's framework. Each food item was carefully designed with custom textures that match the game's pixelated aesthetic.
The mod demonstrates my ability to create cohesive content that enhances gameplay while maintaining the vanilla Minecraft experience. Through this project, I developed skills in digital art, texture painting, and game asset integration.
Skills & Learning Outcomes
- •Java programming and Minecraft Forge API implementation
- •Digital texture creation and pixel art design
- •Game item balancing and crafting recipe design
- •Asset integration and resource pack management
- •Community engagement and mod distribution (3k+ downloads)

Cardboard Momoa
Lethal Company Mod
Project Overview
Cardboard Momoa is a Lethal Company mod that introduces a custom AI entity with advanced pathfinding capabilities. This project represents a significant achievement in AI programming, reaching over 40,000 downloads on Thunderstore. The mod features sophisticated enemy behavior that challenges players while maintaining game balance.
Through developing this mod, I refined my skills in AI pathfinding algorithms, C# programming, and Unity engine integration. The project demonstrates my ability to create complex game mechanics that enhance player experience and engagement.
Skills & Learning Outcomes
- •Advanced AI pathfinding algorithms and navigation systems
- •C# programming and Unity engine integration
- •Visual Studio 2022 development workflow and debugging
- •Game AI behavior design and state machine implementation
- •Performance optimization for real-time AI systems (40k+ downloads)
Here's the core setup method for configuring the Jason Momoa AI entity:
jasonBehaviour.yellSound= scream;
jasonBehaviour.scrapeSound= scrape;
jasonBehaviour.eye= momoaBody.transform.Find("Eye");
jasonBehaviour.animStopPoints= momoaBody.transform.Find("AnimContainer").GetComponent<AnimationStopPoints>();
momoaBody.GetComponent<EnemyAICollisionDetect>().mainScript= jasonBehaviour;
jasonBehaviour.mainCollider= momoaBody.GetComponent<BoxCollider>();
LethalLib.Modules.NetworkPrefabs.RegisterNetworkPrefab(jasonMomoa.enemyPrefab);
Utilities.FixMixerGroups(jasonMomoa.enemyPrefab);
Enemies.RegisterEnemy(jasonMomoa, Configuration.configSpawnWeight.Value, Levels.LevelTypes.All, null, null);Click to expand and view the full code implementation.
Gallery


Scraptopia
Lethal Company Mod
Project Overview
Scraptopia is a custom scrap mod for Lethal Company that introduces unique and creative collectible items to the game. This project served as my introduction to C# programming and the Visual Studio development environment. Through this mod, I learned the fundamentals of 3D modeling, texture painting, and game asset integration.
The mod features custom-designed items including various themed donuts and decorative objects that players can discover and collect throughout their missions. Each item was carefully modeled and textured to fit seamlessly into the game's aesthetic while adding personality to the gameplay experience.
Skills & Learning Outcomes
- •Introduction to C# programming language and object-oriented concepts
- •Proficiency with Visual Studio 2022 development environment
- •3D modeling and texture painting for game assets
- •Game modding and asset integration workflows
- •Community engagement and user feedback management (8,000+ downloads)
Here's the core method used to register custom scrap items in the mod:
void setupScrapItem(Item item, int rarity)
{
if (item != null && rarity > 0)
{
NetworkPrefabs.RegisterNetworkPrefab(item.spawnPrefab);
Utilities.FixMixerGroups(item.spawnPrefab);
Items.RegisterScrap(item, rarity, Levels.LevelTypes.All);
Logger.LogInfo($"{item} has been loaded!");
}
}Click to expand and view the full code implementation.

UncannyJackBlack
Lethal Company Mod
Project Overview
UncannyJackBlack is a Lethal Company mod that introduces a custom AI entity with advanced animations and pathfinding systems. This project served as my introduction to AI animation programming and complex behavior systems. The mod features a unique enemy with fluid animations and intelligent navigation that creates engaging gameplay moments.
Through this project, I learned the fundamentals of animation state machines, AI behavior trees, and pathfinding algorithms. The mod's success with over 12,000 downloads demonstrates the quality of the implementation and player engagement.
Skills & Learning Outcomes
- •Introduction to AI animation systems and state machines
- •AI pathfinding algorithms and navigation mesh integration
- •C# programming and Unity animation controller setup
- •Behavior tree design and AI decision-making systems
- •Game balance and enemy design principles (12k+ downloads)
This code implements the chase behavior with a 20-second timeout system. Jack Black acts as a "streak killer" - if no kill occurs within 20 seconds, he returns to wandering mode, creating dynamic gameplay tension.
PlayerControllerB closestPlayer = GetClosestPlayer();
SetMovingTowardsTargetPlayer(closestPlayer);
ModMain.LOGGER.LogInfo(sinceLastKill);
if ((Time.time - sinceLastKill) >= 20f)
{
ModMain.LOGGER.LogInfo("Switching back to wandering!");
this.creatureAnimator.SetTrigger("stopChase");
SwitchToBehaviourState((int)behaviourStates.wanderingState);
StartSearch(base.transform.position, this.searchRoutine);
break;
}
audioSource.PlayOneShot(screamAudio);
StopSearch(this.searchRoutine);
this.agent.speed= chaseSpeed;
ModMain.LOGGER.LogInfo("Chasing closest player");
break;Click to expand and view the full code implementation.
Gallery


Escape Jason
Roblox Game
Key Highlights
Project Overview
Escape Jason is a horror-themed Roblox game that challenges players to escape from a relentless pursuer. This project represents my introduction to game development on the Roblox platform and LUA programming. The game features atmospheric environments, suspenseful gameplay mechanics, and engaging chase sequences that keep players on edge.
Through developing this game, I learned the fundamentals of Roblox Studio, LUA scripting, and game design principles. The project successfully attracted over 1,000 visits and built a small community of around 100 players who enjoyed the horror experience.
Skills & Learning Outcomes
- •Introduction to LUA programming and scripting fundamentals
- •Proficiency with Roblox Studio development environment
- •Game design principles and horror game mechanics
- •Level design and atmospheric environment creation
- •Community building and player engagement (1,000+ visits, ~100 community members)
Project Gallery




The complete AI pathfinding script that controls Jason's behavior, including player detection, raycasting for line of sight, chasing mechanics, waypoint patrolling, anti-stuck mechanisms, ground smash effects, and jumpscare functionality:
local jason = script.Parent
local Enemy = jason:WaitForChild("Enemy")
local jasonisStuck = false
-- set the bounds of the model
local AgentParameters = {
["AgentRadius"] = 7,
["AgentHeight"] = 5,
["AgentCanJump"] = true
}
-- grab the walkpoints of that the AI will move to
local Waypoints = jason:WaitForChild("Waypoints").Value:GetChildren()
-- grab the necessary services
local PathFindingService = game:GetService("PathfindingService")
local DebrisService = game:GetService("DebrisService")
-- SimplePath is a Roblox pathfinding module developed by other creators
-- The link to SimplePath is here: https://grayzcale.github.io/simplepath/
local SimplePath = require(game.ServerStorage:WaitForChild("SimplePath"))
local Players = game:GetService("Players")
local MaxDistance = jason:WaitForChild("MaxDistance")
local DefaultSpeed = jason:WaitForChild("DefaultSpeed")
local ChaseSpeed = jason:WaitForChild("ChaseSpeed")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RoundEventsFolder = ReplicatedStorage:WaitForChild("RoundEvents")
local JumpscareEvent = RoundEventsFolder:WaitForChild("Jumpscare")
local ChasedTarget, ChasingTime = nil, 0
local TimeOutCount = 0
local MaxChasingTime = jason:WaitForChild("MaxChasingTime").Value
-- function that checks to see if we can see a player to chase
local function CanSeeTarget(Target)
-- roblox raycasts can be used to check of line of sight between two positions
local Origin = jason.HumanoidRootPart.Position
local Direction = (Target.HumanoidRootPart.Position - Origin).unit * MaxDistance.Value
local RayParams = RaycastParams.new()
RayParams.FilterType = Enum.RaycastFilterType.Blacklist
RayParams.FilterDescendantsInstances = {Enemy}
local RaycastResult = game.Workspace:Raycast(Origin, Direction, RayParams)
if RaycastResult then
local RaycastInstance = RaycastResult.Instance
if RaycastInstance then
if RaycastInstance:IsDescendantOf(Target) and not Target:FindFirstChild("Bubble Shield") then
ChasingTime = 0
jason.ChasingTime.Value = ChasingTime
return true
else
if ChasedTarget then
if ChasedTarget == game.Players:GetPlayerFromCharacter(Target).Name then
ChasingTime += 1
jason.ChasingTime.Value = ChasingTime
if ChasingTime > MaxChasingTime then
return "LostInterest"
else
return true
end
end
end
end
end
end
end
-- gets all players in the game and measures their distance
-- returns the closest player
local function LocatePlayers()
local ClosestDistance, ClosestPlayer = math.huge, nil
for index, player in pairs(Players:GetPlayers()) do
local character = player.Character
if character then
local Distance = (jason.HumanoidRootPart.Position - character.HumanoidRootPart.Position).Magnitude
if Distance < MaxDistance.Value then
local CanSeeState = CanSeeTarget(character)
if CanSeeState == "LostInterest" then
return CanSeeState
end
if Distance < ClosestDistance and CanSeeState == true then
ClosestDistance, ClosestPlayer = Distance, player
end
end
end
end
return ClosestPlayer
end
-- we use SimplePath to create the paths
local MainPath = SimplePath.new(jason)
MainPath.Visualize = false
local AttackPath = SimplePath.new(jason)
AttackPath.Visualize = false
-- just in case the AI gets stuck on an object, we resolve by jumping
local function FixPath(errorType)
if errorType == "AgentStuck" then
Enemy:ChangeState(Enum.HumanoidStateType.Jumping)
wait(.5)
Enemy:ChangeState(Enum.HumanoidStateType.Jumping)
end
end
AttackPath.Error:Connect(FixPath)
MainPath.Error:Connect(FixPath)
local function GetWaypoint()
local chosenWaypoint = Waypoints[math.random(1, #Waypoints)]
return chosenWaypoint
end
-- we chase a player down
local function AttackPlayer(TargetedCharacter)
Enemy.WalkSpeed = ChaseSpeed.Value
local TargetedPlayer = Players:GetPlayerFromCharacter(TargetedCharacter)
if TargetedCharacter:FindFirstChild("Humanoid") then
TargetedCharacter.Humanoid:SetAttribute("Chased", true)
else
return false
end
if TargetedPlayer then
ChasedTarget = TargetedPlayer.Name
end
MainPath:Stop()
-- difference apperances based on game difficulty and map
jason.Head.Transparency = 1
jason.Head.face.Transparency = 1
if jason.Difficulty.Value == "Nightmare" then
jason.Nightmare.Transparency = 0
else
jason.Angry.Transparency = 0
end
if jason.Map.Value == "jason's Carnival" then
jason.Nightmare.Transparency = 1
jason.Angry.Transparency = 1
jason.Carnival.Transparency = 0
end
jason.Head.Scream:Play()
-- continous chasing
local Distance
repeat
local TargetedPlayer = LocatePlayers()
if ChasedTarget then
if TargetedPlayer then
if TargetedPlayer == "LostInterest" then
ChasingTime = 0
game.Workspace:FindFirstChild(ChasedTarget).Humanoid:SetAttribute("Chased", nil)
ChasedTarget = nil
jason.Head.Transparency = 0
jason.Head.face.Transparency = 0
jason.Angry.Transparency = 1
print("Broken")
break
end
if ChasedTarget == TargetedPlayer.Name then
else
game.Workspace:FindFirstChild(ChasedTarget).Humanoid:SetAttribute("Chased", nil)
AttackPlayer(TargetedPlayer)
end
end
end
Distance = (jason.HumanoidRootPart.Position - TargetedCharacter.HumanoidRootPart.Position).Magnitude
AttackPath:Run(TargetedCharacter.HumanoidRootPart, AgentParameters)
until Distance < 10 or ChasedTarget == nil
-- we eliminate the player and jumpscare them
if Distance < 10 then
TargetedCharacter:BreakJoints()
JumpscareEvent:FireClient(Players:GetPlayerFromCharacter(TargetedCharacter))
end
end
-- we walk to waypoint on the map
local function WalkToGoal(CurrentWaypoint)
-- cosmetic/appearance changes
local TargetedPlayer
jason.Head.Transparency = 0
jason.Head.face.Transparency = 0
jason.Angry.Transparency = 1
jason.Nightmare.Transparency = 1
jason.Carnival.Transparency = 1
jason.Head.Scream:Stop()
-- calm patrolling
repeat
Enemy.WalkSpeed = DefaultSpeed.Value
local Distance = (jason.HumanoidRootPart.Position - CurrentWaypoint.Position).Magnitude
MainPath:Run(CurrentWaypoint, AgentParameters)
TargetedPlayer = LocatePlayers()
if TargetedPlayer then
break
end
until Distance < 5
if TargetedPlayer then
local TargetedCharacter = TargetedPlayer.Character
if TargetedCharacter and TargetedCharacter.Humanoid.Health > 0 then
AttackPlayer(TargetedCharacter)
end
end
end
-- patrol (as in just walk to waypoints around the map scanning for players)
local function Patrol()
local CurrentWaypoint = GetWaypoint()
WalkToGoal(CurrentWaypoint)
end
local StuckTimer = 0
local NewPosition, OldPosition
task.spawn(function()
while task.wait(1) do
NewPosition = jason.HumanoidRootPart.Position
if OldPosition then
local positionDifference = (NewPosition - OldPosition).Magnitude
if positionDifference < 2 then
StuckTimer += 1
end
end
if StuckTimer == 2 then
jason.HumanoidRootPart.CFrame = jason.HumanoidRootPart:GetPivot() + Vector3.new(math.random( -5, 5), 0, math.random( -5, 5))
StuckTimer = 0
end
OldPosition = jason.HumanoidRootPart.Position
end
end
end
local DebrisService = game:GetService("DebrisService")
local PhysicsService = game:GetService("PhysicsService")
jason.HumanoidRootPart.CollisionGroup = "jason"
-- ground smash effects
Enemy.StateChanged:Connect(function(oldState, newState)
if oldState == Enum.HumanoidStateType.Freefall and newState == Enum.HumanoidStateType.Landed then
local function CrashDebris()
local randomDebrisCount = math.random(5, 13)
local RaycastParameters = Instance.new("RaycastParams")
RaycastParameters.FilterType = Enum.RaycastFilterType.Blacklist
RaycastParameters.FilterDescendantsInstances = {jason}
local RaycastResult = game.Workspace:Raycast(jason.HumanoidRootPart.Position, Vector3.new(0, -50, 0), RaycastParameters)
local RaycastInstance
if RaycastResult then
RaycastInstance = RaycastResult.Instance
end
local FloorColor
if RaycastInstance then
FloorColor = RaycastInstance.Color
end
for i = randomDebrisCount, 0, -1 do
local newDebris = Instance.new("Part", game.Workspace)
newDebris.Position = jason.HumanoidRootPart.Position - Vector3.new(0, 3, 0)
newDebris.Size = Vector3.new(math.random(1, 3), math.random(1, 3), math.random(1, 3))
if FloorColor then
newDebris.Color = FloorColor
end
newDebris.Material = Enemy.FloorMaterial
local PathfindingMod = Instance.new("PathfindingModifier", newDebris)
PathfindingMod.PassThrough = true
newDebris.CollisionGroup = "CrashDebris"
local Attachment = Instance.new("Attachment", newDebris)
local VectorForce = Instance.new("VectorForce", newDebris)
VectorForce.ApplyAtCenterOfMass = true
VectorForce.Attachment0 = Attachment
VectorForce.Force = Vector3.new(0, 2500, 0)
delay(.3, function()
VectorForce.Force = Vector3.new(0, 0, 0)
end)
VectorForce.RelativeTo = Enum.ActuatorRelativeTo.World
DebrisService:AddItem(VectorForce, 3)
DebrisService:AddItem(newDebris, 10)
end
end
end
jason.Head.LandCrash:Play()
CrashDebris()
end
end
-- main loop that does the patrolling
while wait() do
Patrol()
end