RoboCatz.com

Art Museum AI Prompt 1

What is Vibe Coding?

Vibe Coding is a cool way to write programs with the help of AI (artificial intelligence). Imagine having a super-smart assistant by your side while coding! The AI can help you in different ways -- it might create an entire program for you, or just give you ideas and help with specific parts, depending on what you need.

To get started, you simply talk to the AI and explain what you want your program to do. The AI will then create a rough version of the program for you. After that, you can ask the AI questions, make suggestions, or request changes to add new features or fix things until the program is just the way you want it.

For this project, you will provide the AI with an existing Art Museum program and ask it to make a similar art project:

AI Prompt:
I am writing code for a Roblox world using a graphics API. This graphics API is stored in a module script in ReplicatedStorage called genericShapes. 
I am using this module to assist in creating an art museum. The art museum also uses several modules stored in ReplicatedStorage. 
In my "studentExhibition" module script, I include two supporting modules using:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local s = require(ReplicatedStorage.genericShapes)
local b = require(ReplicatedStorage.artInstallationRoom)

Each "student exhibition" is stored as a function that initializes a table with several "callback" functions. These callback functions are installed 
for the player when the player enters a particular art exhibit room.  The following shows how the startingScript sets up the exhibit room for the player.

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local b = require(ReplicatedStorage.artInstallationRoom)
local e = require(ReplicatedStorage.studentExhibition)
local Players = game:GetService("Players")
b.setWidth(75)
b.setLength(75)
Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(character)
		local humanoidRootPart = character:WaitForChild("HumanoidRootPart")
		local iteration = 1
		local currentRoomCenter = Vector3.new(0, 25, -45)
		local currentRoomSize = Vector3.new(75, 50, 75)
		while humanoidRootPart do
			local k=e.CalebRings(75, 75)
			k.draw()
			local iteration = 1
			k.defineInteractions()
			while true do
				k.animate({ 
					iteration=iteration, 
					locationInRoom = 100 * ((currentRoomCenter + currentRoomSize/2) - humanoidRootPart.Position)/currentRoomSize
				})
				wait(0.1)
				iteration = iteration + 1
			end
		end
	end)
end)

There are about 20 different student exhibition functions stored in the studentExhibition module. Each shows the artwork for one student's exhibition.

The artworks are typically made from various shape functions. The shape functions used in the art are: square, rectangle, circle, panel, disc, cube, 
tube, sphere, steps, and wall. Since the shapes are in a module, you need to include the reference to the replicated storage module. For example, to 
create a square you would use the square's constructor: s.square(). Optional parameters can be passed into the function such as x, y, z, size, color, material). 
A useful way of passing these parameters is through the use of a table. For example:
s.square({ x=0, y=5, z=-15, size=10, thickness=0.5, color=Color3.new(1, 0, 0) })
The table here is encapsulated using curly braces and the named values in the table are separated by commas.
Some of the basic numeric parameters that can be passed to this table include: x, y, z, size, radius, length, width, height, thickness.
You can also pass parameters such as position, rotateBy, and orientation which all require Vector3 values. RotateBy and Orientation are synonymous.
You can pass color as a string (color name) or as a Color3 value.
Transparency, opacity and reflectance are values that range from 0 to 1.
The parameter "anchored" uses a Boolean value.
Material is a parameter that can be passed as an enumerated value such as: Enum.Material.Foil
Some common materials include:
.Plastic, .Wood, .Slate, .Concrete, .CorrodedMetal, .DiamondPlate, .Foil, .Grass, .Ice, .Marble, .Granite, .Brick, .Pebble, .Sand, .Fabric, .SmoothPlastic, .Metal
Shape objects are created with a default orientation (unless you pass a specific orientation to be used). Circles, squares, discs, rectangles are 
initially rendered as having a vertical appearance (not laying flat on the ground).

The wall, steps and tube shapes require two sets of coordinates. For example:

s.tube({ x1=-10, y1=4, z1=25, x2=10, y2=4, z2=5, size=10, thickness=2, color=Color3.new(1, 0.243137, 0.054902), material=Enum.Material.Wood })
s.wall({x1=0, y1=0, z1=23, x2=20, y2=2, z2=23, thickness=1, material=Enum.Material.Brick, color=Color3.fromRGB(179, 73, 255)})
s.steps({x1=0, y1=0, z1=23, x2=20, y2=2, z2=23, thickness=1, material=Enum.Material.Brick, color=Color3.fromRGB(179, 73, 255)})

For the wall and steps, the height of the wall and steps are determined by the difference between the y1 and y2 values. If y1 is 0 and y2 is 2, 
then the height of the wall will be 2 units. The thickness of the wall indicates how wide it should be as it traverses from x1,z1 to x2,z2.
The tube function also takes two coordinates. The size parameter indicates the diameter of the tube and the thickness indicates the thickness 
of the walls of the tube.

There are a variety of methods, common to all basic shape functions, that can be chained. For example:

s.sphere()
:fill(randomColor())
:setMaterial(Enum.Material.CorrodedMetal)

or

s.cube()
:rotate(45, 45, 0)
:setColor(randomColor())
:setMaterial(Enum.Material.Marble)
:opacity(0.90)

The list of basic methods includes:
anchored(boolean)
setAnchored(boolean)
setAttribute(string, string)

color(Color3)
setColor(Color3)
fill(Color3)
fillColor(Color3)

material(Enum.Material)
setMaterial(Enum.Material)

rotate(Vector3 | number, y: number?, z: number?)
rotateBy(Vector3 | number, y: number?, z: number?)

size(number)
setSize(number)
reSize(number)

opacity(number)
setOpacity(number)

transparency(number)
setTransparency(number)

moveBy(Vector3 | number, y: number?, z: number?)
moveTo(Vector3 | number, y: number?, z: number?)
subtract(ShapeObject | Part, destroySubPart: boolean?)
cut(ShapeObject | Part, destroySubPart: boolean?)
join(ShapeObject | Part | {ShapeObject | Part})
merge(ShapeObject | Part | {ShapeObject | Part})
union(ShapeObject | Part | {ShapeObject | Part})
intersect(ShapeObject | Part | {ShapeObject | Part})

I would like you to create artworks to be shown in the museum.
Please note that when creating an artwork from shapes, you need to store the shapes in an array using:
local someShape = s.someShapeFunction()
table.insert(exhibitRoom.parts, someShape )
The reason for this is because the art is destroyed once the player exits the room.  There may be hundreds of rooms in the museum and each exhibit 
could have hundreds of shapes as the art.  So, there is a potential for thousands of shapes and with their animation and interactions, this could 
slow the processing down significantly.  So, the art will only be created when the player is in the room and will be destroyed when the player leaves the room.

Below is an example of a single student exhibition function:
function StudentExhibition.AmirsFirstArt(x, z)
	local exhibitRoom = { room=b.new({x=x, z=z}), name="AmirsFirstArt", parts={}, onInteraction=nil }
	exhibitRoom.draw = function() 
		-- Exhibit Settings
		local exhibitSpacing = 20
		local pedestalSize = 10
		local floorLevel = 0
		-- Define a few "Exhibits" with different shapes and positions
		local exhibits = {
			{x = exhibitRoom.room.center.X-exhibitSpacing, z = exhibitRoom.room.center.Z, color = Color3.fromRGB(255, 85, 0),   shape = "Geometric Tension"},
			{x = exhibitRoom.room.center.X,   z = exhibitRoom.room.center.Z, color = Color3.fromRGB(0, 170, 255),  shape = "The Floating Core"},
			{x = exhibitRoom.room.center.X+exhibitSpacing,  z = exhibitRoom.room.center.Z, color = Color3.fromRGB(170, 0, 255),  shape = "Structural Void"}
		}
		for _, data in ipairs(exhibits) do
			-- 1. BUILD THE PEDESTAL
			-- A sleek, dark base for the art to sit on
			local pedestal = s.cube({x = data.x, y = floorLevel + 2, z = data.z, size = pedestalSize})
				:setMaterial(Enum.Material.Marble)
				:setColor(Color3.fromRGB(30, 30, 30))
				:setTransparency(0)
				:setAttribute("ArtObject", "Pedestal")
			table.insert(exhibitRoom.parts, pedestal)

			-- 2. CREATE THE ART PIECE (Different for each position)
			local artY = floorLevel + pedestalSize * 1.2 -- Floating slightly above the pedestal

			if data.shape == "Geometric Tension" then
				-- Abstract spikes using tubes
				for i = 1, 8 do
					local tensionPart = s.tube({
						x1 = data.x, y1 = artY - 2, z1 = data.z,
						x2 = data.x + math.random(-10, 10), 
						y2 = artY + math.random(5, pedestalSize), 
						z2 = data.z + math.random(-10, 10),
						size = 2, thickness = 0.5
					})
						:setMaterial(Enum.Material.Neon)
						:setColor(data.color)
					table.insert(exhibitRoom.parts, tensionPart)
				end

			elseif data.shape == "The Floating Core" then
				-- A sphere inside a hollow cube frame
				local floatingCore = s.cube({x = data.x, y = artY, z = data.z, size = 10})
					:setMaterial(Enum.Material.Glass)
					:setColor(Color3.new(1, 1, 1))
					:setTransparency(0.8)
					:cut(s.cube({x = data.x, y = artY, z = data.z, size = 9})) -- Make it a thin frame
				table.insert(exhibitRoom.parts, floatingCore)
				local coreSphere = s.sphere({x = data.x, y = artY, z = data.z, size = 6})
					:setMaterial(Enum.Material.Neon)
					:setColor(data.color)
				table.insert(exhibitRoom.parts, coreSphere)
			elseif data.shape == "Structural Void" then
				-- A disc-based sculpture
				for i = 1, 5 do
					local discPart = s.disc({x = data.x, y = artY + (i * 2), z = data.z, size = pedestalSize - i})
						:rotateBy(math.random(0, 180), math.random(0, 180), 0)
						:setMaterial(Enum.Material.SmoothPlastic)
						:setColor(data.color)
						:setTransparency(0.3)
					table.insert(exhibitRoom.parts, discPart)
				end
			end

			-- 3. ADD AN EXHIBIT LIGHT (Optional Aesthetic)
			local lightPart = s.sphere({x = data.x, y = artY + 20, z = data.z, size = 1})
				:setMaterial(Enum.Material.Neon)
				:setColor(Color3.new(1, 1, 1))
			table.insert(exhibitRoom.parts, lightPart)
		end

	end
	exhibitRoom.onInteraction = function(thePart)
		local touchingPartsTable = thePart:GetTouchingParts()
		local artObject = thePart:GetAttribute("ArtObject")
		if artObject ~= "Pedestal" then 
			for i=1,#touchingPartsTable do
				touchingPartsTable[i].Color =Color3.new(0, 0.34902, 1)
				touchingPartsTable[i].Material = Enum.Material.Wood
			end
		end
	end
	exhibitRoom.defineInteractions = function()
		for i=1,#exhibitRoom.parts do exhibitRoom.parts[i].part.Touched:Connect(exhibitRoom.onInteraction) end
	end
	exhibitRoom.animate = function(...) 
		for i=1,#exhibitRoom.parts do
			local artObject = exhibitRoom.parts[i].part:GetAttribute("ArtObject")
			if artObject ~= "Pedestal" then 
				exhibitRoom.parts[i].Color = Color3.new(math.random(),math.random(),math.random())
			end
		end
	end
	return exhibitRoom
end

Create a new art exhibit function using the same format for the functions and callbacks.



AI Prompt:
Here are three more examples of student art exhibits.

function StudentExhibition.OrbitalBloom(x, z)
	local TweenService = game:GetService("TweenService")

	local exhibitRoom = {
		room = b.new({x = x, z = z}),
		name = "OrbitalBloom",
		parts = {},
		onInteraction = nil
	}

	exhibitRoom.draw = function()
		local cx = exhibitRoom.room.center.X
		local cz = exhibitRoom.room.center.Z
		local floorY = 0

		---------------------------------------------------------
		-- 1. CENTRAL CORE
		---------------------------------------------------------
		local core =
			s.sphere({x = cx, y = floorY + 10, z = cz, size = 6})
			:setMaterial(Enum.Material.Neon)
			:setColor(Color3.fromRGB(255, 200, 255))
			:setTransparency(0.1)
			:setAttribute("ArtObject", "Core")
		table.insert(exhibitRoom.parts, core)

		---------------------------------------------------------
		-- 2. PETAL RING (12 panels)
		---------------------------------------------------------
		local petalCount = 12
		local radius = 14

		for i = 1, petalCount do
			local angle = math.rad((360 / petalCount) * i)
			local px = cx + math.cos(angle) * radius
			local pz = cz + math.sin(angle) * radius

			local petal =
				s.panel({x = px, y = floorY + 10, z = pz, width = 4, height = 10})
				:rotateBy(0, math.deg(angle) + 90, 0)
				:setMaterial(Enum.Material.Marble)
				:setColor(Color3.fromRGB(255, 150, 200))
				:setTransparency(0.2)
				:setAttribute("ArtObject", "Petal")
			table.insert(exhibitRoom.parts, petal)
		end
	end

	---------------------------------------------------------
	-- INTERACTION CALLBACK
	---------------------------------------------------------
	exhibitRoom.onInteraction = function(thePart)
		local touching = thePart:GetTouchingParts()
		local artType = thePart:GetAttribute("ArtObject")

		if artType ~= "Core" then
			for _, p in ipairs(touching) do
				if p:GetAttribute("ArtObject") == "Petal" then
					p.Color = s.randomColor()
					p.Material = Enum.Material.Glass
				end
			end

		end
	end

	exhibitRoom.defineInteractions = function()
		for i = 1, #exhibitRoom.parts do
			exhibitRoom.parts[i].part.Touched:Connect(exhibitRoom.onInteraction)
		end
	end
		
	
	---------------------------------------------------------
	-- ANIMATION (TweenService)
	---------------------------------------------------------
	exhibitRoom.animate = function(args)
		local iteration = args.iteration or 1

		for i = 1, #exhibitRoom.parts do
			local obj = exhibitRoom.parts[i]
			local artType = obj.part:GetAttribute("ArtObject")

			-----------------------------------------------------
			-- Tween petals to open and close
			-----------------------------------------------------
			if artType == "Petal" then
				local petal = obj.part

				-- Compute target rotation
				local openAngle = 20 * math.sin(iteration / 20)

				local tweenInfo = TweenInfo.new(
					0.4,                      -- time
					Enum.EasingStyle.Sine,    -- easing
					Enum.EasingDirection.InOut
				)

				local goal = {
					Orientation = petal.Orientation + Vector3.new(openAngle, 0, 0)
				}

				local tween = TweenService:Create(petal, tweenInfo, goal)
				tween:Play()

				-----------------------------------------------------
				-- Tween core to pulse
				-----------------------------------------------------
			elseif artType == "Core" then
				local core = obj.part

				local pulse = 6 + math.sin(iteration / 15)

				local tweenInfo = TweenInfo.new(
					0.3,
					Enum.EasingStyle.Sine,
					Enum.EasingDirection.InOut
				)

				local goal = {
					Size = Vector3.new(pulse, pulse, pulse)
				}

				local tween = TweenService:Create(core, tweenInfo, goal)
				tween:Play()
			end
		end
	end

	return exhibitRoom
end


-- Copilot Prompt:
function StudentExhibition.LuminousHelixGarden(x, z)
	local exhibitRoom = { 
		room = b.new({x = x, z = z}), 
		name = "LuminousHelixGarden", 
		parts = {}, 
		onInteraction = nil 
	}

	exhibitRoom.draw = function()
		local centerX = exhibitRoom.room.center.X
		local centerZ = exhibitRoom.room.center.Z
		local floorY = 0

		-- PARAMETERS
		local helixCount = 6
		local helixRadius = 18
		local helixHeight = 30
		local helixTurns = 3
		local sphereSpacing = 4

		-- COLOR PALETTE
		local palette = {
			Color3.fromRGB(255, 90, 90),
			Color3.fromRGB(90, 255, 140),
			Color3.fromRGB(90, 170, 255),
			Color3.fromRGB(255, 200, 90),
			Color3.fromRGB(200, 90, 255),
			Color3.fromRGB(255, 120, 200)
		}

		---------------------------------------------------------
		-- 1. CENTRAL FLOATING CORE
		---------------------------------------------------------
		local centralCore = s.sphere({x = centerX, y = floorY + 12, z = centerZ, size = 10})
			:setMaterial(Enum.Material.Neon)
			:setColor(Color3.fromRGB(255, 255, 255))
			:setTransparency(0.2)
			:setAttribute("ArtObject", "Core")
		table.insert(exhibitRoom.parts,	centralCore)

		---------------------------------------------------------
		-- 2. SPIRALING HELIX TOWERS
		---------------------------------------------------------
		for h = 1, helixCount do
			local angle = (2 * math.pi / helixCount) * h
			local baseX = centerX + math.cos(angle) * helixRadius
			local baseZ = centerZ + math.sin(angle) * helixRadius
			local color = palette[h]

			-- Build the helix using tubes
			for step = 1, helixTurns * 20 do
				local t = step / (helixTurns * 20)
				local y1 = floorY + t * helixHeight
				local y2 = floorY + (t + 0.05) * helixHeight

				local x1 = baseX + math.cos(angle + t * math.pi * 2) * 2
				local z1 = baseZ + math.sin(angle + t * math.pi * 2) * 2

				local x2 = baseX + math.cos(angle + (t + 0.05) * math.pi * 2) * 2
				local z2 = baseZ + math.sin(angle + (t + 0.05) * math.pi * 2) * 2
				
				local helixTube = s.tube({
						x1 = x1, y1 = y1, z1 = z1,
						x2 = x2, y2 = y2, z2 = z2,
						size = 1.5,
						thickness = 0.4
					})
						:setMaterial(Enum.Material.Neon)
						:setColor(color)
						:setAttribute("ArtObject", "Helix")
				table.insert(exhibitRoom.parts, helixTube)
			end

			---------------------------------------------------------
			-- 3. FLOATING SPHERES ALONG EACH HELIX
			---------------------------------------------------------
			for sIndex = 1, math.floor(helixHeight / sphereSpacing) do
				local t = sIndex / (helixHeight / sphereSpacing)
				local y = floorY + t * helixHeight

				local sx = baseX + math.cos(angle + t * math.pi * 2) * 3
				local sz = baseZ + math.sin(angle + t * math.pi * 2) * 3
				
				local floatingSphere = 
					s.sphere({x = sx, y = y, z = sz, size = 2})
						:setMaterial(Enum.Material.SmoothPlastic)
						:setColor(color)
						:setTransparency(0.1)
						:setAttribute("ArtObject", "Orb")
				table.insert(exhibitRoom.parts, floatingSphere)
			end
		end

		---------------------------------------------------------
		-- 4. ROTATING PANEL RING
		---------------------------------------------------------
		for i = 1, 12 do
			local angle = (2 * math.pi / 12) * i
			local px = centerX + math.cos(angle) * (helixRadius + 6)
			local pz = centerZ + math.sin(angle) * (helixRadius + 6)

			local rotatingPanel	=
				s.panel({x = px, y = floorY + 8, z = pz, width = 6, height = 8})
					:rotateBy(0, math.deg(angle) + 90, 0)
					:setMaterial(Enum.Material.Marble)
					:setColor(Color3.fromRGB(240, 240, 240))
					:setTransparency(0.3)
					:setAttribute("ArtObject", "Panel")
			table.insert(exhibitRoom.parts, rotatingPanel)
		end
	end

	---------------------------------------------------------
	-- INTERACTION CALLBACK
	---------------------------------------------------------
	exhibitRoom.onInteraction = function(thePart)
		local touching = thePart:GetTouchingParts()
		local artType = thePart:GetAttribute("ArtObject")

		if artType ~= "Core" then
			for _, p in ipairs(touching) do
				p.Color = Color3.fromRGB(0, 120, 255)
				p.Material = Enum.Material.Foil
			end
		end
	end

	exhibitRoom.defineInteractions = function()
		for i = 1, #exhibitRoom.parts do
			exhibitRoom.parts[i].part.Touched:Connect(exhibitRoom.onInteraction)
		end
	end

	---------------------------------------------------------
	-- ANIMATION LOOP
	---------------------------------------------------------
	exhibitRoom.animate = function(args)
		local iteration = args.iteration or 1
		for i = 1, #exhibitRoom.parts do
			local obj = exhibitRoom.parts[i]
			local artType = obj.part:GetAttribute("ArtObject")

			if artType == "Orb" then
				-- Orbs pulse in size
				local pulse = 1 + 0.2 * math.sin(iteration / 10)
				obj:setSize(pulse)
			elseif artType == "Panel" then
				-- Panels rotate slowly
				obj:rotateBy(0, 2, 0)
			elseif artType == "Helix" then
				-- Helix tubes shimmer
				local c = obj.Color
				local delta = 0.04

				local r = (c.R + delta) % 1
				local g = (c.G + delta) % 1
				local b = (c.B + delta) % 1

				obj:setColor(Color3.new(r, g, b))

				--obj:setColor(Color3.new(math.random(), math.random(), math.random()))
			end
		end
	end

	return exhibitRoom
end

-- Helper: Generate evenly distributed points on a sphere using Fibonacci sampling
local function fibonacciSpherePoints(count, radius)
	local points = {}
	local offset = 2 / count
	local increment = math.pi * (3 - math.sqrt(5)) -- golden angle

	for i = 0, count - 1 do
		local y = ((i * offset) - 1) + (offset / 2)
		local r = math.sqrt(1 - y * y)
		local phi = i * increment

		local x = math.cos(phi) * r
		local z = math.sin(phi) * r

		table.insert(points, Vector3.new(x, y, z) * radius)
	end

	return points
end


function StudentExhibition.CircleTessellationSphere(x, z)
	local exhibitRoom = {
		room = b.new({x = x, z = z}),
		name = "CircleTessellationSphere",
		parts = {},
		tick = 0
	}

	exhibitRoom.draw = function()
		local center = exhibitRoom.room.center

		-- Sphere parameters
		local sphereRadius = 15      -- 30‑unit diameter
		local circleRadius = 5       -- circle diameter ≈ 5
		local numCircles = 120       -- good coverage without overloading

		-- Generate points on sphere surface
		local points = fibonacciSpherePoints(numCircles, sphereRadius)

		for _, offset in ipairs(points) do
			local pos = center + offset

			-- Normal vector from center to point
			local normal = offset.Unit

			-- Create the circle
			local circle = s.circle({
				x = pos.X,
				y = pos.Y,
				z = pos.Z,
				size = circleRadius,
				color = Color3.fromRGB(255, 255, 255),
				material = Enum.Material.Plastic,  --Neon,
				opacity = 0.2
			})

			-- Rotate circle so it lies flush against the sphere surface
			-- We align the circle's local Z axis with the normal vector
			local up = Vector3.new(0, 1, 0)
			local axis = up:Cross(normal)
			local angle = math.acos(up:Dot(normal))

			if axis.Magnitude > 0.001 then
				circle:rotateBy(CFrame.fromAxisAngle(axis.Unit, angle))
			end

			table.insert(exhibitRoom.parts, circle)
		end

		-- Optional: a faint core sphere for visual grounding
		local core = s.sphere({
			x = center.X,
			y = center.Y,
			z = center.Z,
			size = sphereRadius * 1.2,
			color = Color3.fromRGB(50, 50, 80),
			material = Enum.Material.SmoothPlastic,
			transparency = 0.8
		})
		table.insert(exhibitRoom.parts, core)
	end


	---------------------------------------------------------
	-- INTERACTIONS
	---------------------------------------------------------
	-- Interaction: touching a circle brightens it briefly
	exhibitRoom.onInteraction = function(thePart)
		thePart.Color = Color3.fromRGB(0, 200, 255)
		thePart.Material = Enum.Material.Neon
	end
	
	exhibitRoom.defineInteractions = function()
		for _, part in ipairs(exhibitRoom.parts) do
			part.part.Touched:Connect(function(hit)
				if hit:GetAttribute("ArtObject") == "Projectile" then
					part.Anchored = false
					--exhibitRoom.dropToGround(part)
				end				
				if hit.Parent:FindFirstChild("Humanoid") then
					exhibitRoom.onInteraction(part)
				end
			end)
		end
	end


	---------------------------------------------------------
	-- ANIMATIONS
	---------------------------------------------------------
	-- Animation: slow rotation of the entire tessellated sphere
	exhibitRoom.animate = function(dt)
		for _, part in ipairs(exhibitRoom.parts) do
			if part.Anchored == true then
				part:rotateBy(0, 0.3, 0)
			end
		end
	end

	return exhibitRoom
end

Can you create another student art exhibit that is similar to the examples shown here.  You need to use similar callback functions.