Open for commissions

Miky

Roblox Scripter

About

I'm Miky, a Roblox scripter building clean, reliable systems.

3+ years of experience, 3 paid commissions delivered.

I focus on individual systems, not full games. Shops, NPCs, save systems, UIs, anything that size and self-contained.

I write organized, modular code. Everything is split into proper modules, structured with configs, and named clearly so anything is easy to find and change later.

Luau / Lua
Server Architecture
Gameplay Systems
DataStore
UI / Interface
Networking

Scope

I work feature by feature, sometimes a small bundle of features that need each other (shop + inventory + save, combat + UI). Whole games and oversized asks are out of scope.

What I take on
Single systems, simple or fairly complex
  • Combat, hitboxes, abilities, dashes, parries
  • Shops, inventories, currency, crafting, trading
  • DataStore, player data, profiles, save systems
  • NPCs, dialogue, quests, daily rewards
  • UI, menus, HUD, settings screens
  • Tools, pickups, interactables, tycoons
  • Mini-games, boss fights, wave survival, round-based modes
  • Pets, mounts, leaderboards, kill feeds
What I don't
Bigger than a single system
  • Whole games, start to finish
  • Huge features that lean on tons of custom animation or art (full cinematic combat with unique anims for every move, big boss fights with cutscenes and phases, that kind of thing)
  • Open-ended builds with no clear finish line
  • Asks that look like one system but unpack into five
  • Polished vehicles or driving systems

What I've Built

Video demos on my YouTube channel

Code Samples

--!strict

local Debris = game:GetService("Debris")

local Hitbox = {}
Hitbox.__index = Hitbox

export type Hitbox = typeof(setmetatable({} :: {
	Size: Vector3,
	Params: OverlapParams,
	Debug: boolean,
}, Hitbox))

function Hitbox.new(size: Vector3): Hitbox
	local self = setmetatable({}, Hitbox)
	self.Size = size
	self.Params = OverlapParams.new()
	self.Params.FilterType = Enum.RaycastFilterType.Exclude
	self.Params.FilterDescendantsInstances = {}
	self.Debug = false
	return self
end

function Hitbox:SetIgnoreList(list: {Instance})
	-- have to set it, modifying the existing list does nothing
	self.Params.FilterDescendantsInstances = list
end

function Hitbox:Scan(cf: CFrame): {Model}
	if self.Debug then
		self:_DrawDebug(cf)
	end

	local parts = workspace:GetPartBoundsInBox(cf, self.Size, self.Params)
	local hits, seen = {}, {}

	for _, part in parts do
		local rig = part:FindFirstAncestorOfClass("Model")
		if rig and not seen[rig] and rig:FindFirstChildOfClass("Humanoid") then
			seen[rig] = true
			table.insert(hits, rig)
		end
	end

	return hits
end

function Hitbox:_DrawDebug(cf: CFrame)
	local p = Instance.new("Part")
	p.Size = self.Size
	p.CFrame = cf
	p.Anchored = true
	p.CanCollide = false
	p.CanQuery = false
	p.Transparency = 0.7
	p.Color = Color3.fromRGB(255, 80, 80)
	p.Parent = workspace
	Debris:AddItem(p, 0.15)
end

return Hitbox
--!strict

local DataStoreService = game:GetService("DataStoreService")
local store = DataStoreService:GetDataStore("PlayerData_v2")

local DEFAULT_PROFILE = {
	Coins = 0,
	Level = 1,
	Wins = 0,
}

export type Profile = typeof(DEFAULT_PROFILE)

local PlayerData = {}

local function deepCopy(t: T): T
	local out = {}
	for k, v in t :: any do
		out[k] = if type(v) == "table" then deepCopy(v) else v
	end
	return out :: any
end

function PlayerData.Load(userId: number): Profile
	local key = "u_" .. userId
	local ok, data = pcall(store.GetAsync, store, key)

	-- if load fails return defaults but dont save them
	-- saving defaults would overwrite real data later
	if not ok then
		warn(string.format("[PlayerData] load failed for %d: %s", userId, tostring(data)))
		return deepCopy(DEFAULT_PROFILE)
	end

	return data or deepCopy(DEFAULT_PROFILE)
end

function PlayerData.Save(userId: number, profile: Profile): boolean
	local key = "u_" .. userId

	for attempt = 1, 3 do
		local ok, err = pcall(store.SetAsync, store, key, profile)
		if ok then
			return true
		end
		warn(string.format("[PlayerData] save attempt %d failed: %s", attempt, tostring(err)))
		task.wait(2 ^ attempt)
	end

	warn(string.format("[PlayerData] gave up saving for %d", userId))
	return false
end

return PlayerData
--!strict

local Cooldown = {}
Cooldown.__index = Cooldown

export type Cooldown = typeof(setmetatable({} :: {
	Duration: number,
	_stamps: {[any]: number},
}, Cooldown))

function Cooldown.new(duration: number): Cooldown
	return setmetatable({
		Duration = duration,
		_stamps = {},
	}, Cooldown)
end

function Cooldown:TryUse(key: any): boolean
	local last = self._stamps[key]
	if last and (os.clock() - last) < self.Duration then
		return false
	end

	self._stamps[key] = os.clock()
	return true
end

function Cooldown:Remaining(key: any): number
	local last = self._stamps[key]
	if not last then
		return 0
	end

	return math.max(0, self.Duration - (os.clock() - last))
end

function Cooldown:Reset(key: any?)
	if key == nil then
		table.clear(self._stamps)
	else
		self._stamps[key] = nil
	end
end

return Cooldown

Hire Me

Single System
Small scope
From $20 USD
or ~R$7,520 in Robux

One standalone system or script. Combat, shop, NPC, data handler, or custom tool.

  • One focused system
  • Revisions included
  • Delivers in 3-7 days
Multi-System
Medium scope
From $100 USD total
or ~R$37,600 in Robux · split across tasks

Multiple systems that work together. Shop + inventory + data saving, combat + UI, etc.

  • 2-4 connected systems
  • Server and client side
  • Fully tested
  • Delivers in 1-3 weeks
Payment

Pay per task by default. Each commission gets broken into small pieces and you pay for each one as it's delivered. If you'd rather do a simple 50/50 (upfront and on delivery), that works too. No rev-share, no "pay when the game ships." Gift cards and crypto aren't accepted; ask if you have something else in mind.

Cash App
$ml3dev

Quick and simple. No extra fees on your end.

Z
Zelle
ask for details

Bank-to-bank transfer. Free with most US banks. Send a message for the handle or QR.

Robux
miky

You cover the 30% Roblox tax, and the total must match the listed USD value at the current DevEx rate. Pay via gamepass or group funds.

Ownership

As soon as a task is paid for, that code is fully yours. You can modify it, ship it anywhere, and I don't keep a copy.

Refunds

You can walk away anytime. Per-task means you only pay for what's been delivered; with 50/50, the upfront half is refundable until I've started.

Availability

EST based. I reply within hours on Discord, slower on email.

Start a project

Send me a message and tell me what you're building. Include the systems you need, your timeline, and a budget if you have one.