Skip to content

Instantly share code, notes, and snippets.

@NAEL2XD
Last active April 22, 2025 20:05
Show Gist options
  • Select an option

  • Save NAEL2XD/a6938dfb60ebf3b858547df0ecafdf0a to your computer and use it in GitHub Desktop.

Select an option

Save NAEL2XD/a6938dfb60ebf3b858547df0ecafdf0a to your computer and use it in GitHub Desktop.
Psych Engine: Virtual Streaming w/ Chat Reaction.
--[[
A Psych Engine Script that acts like you are streaming but in real time it's actually virtual.
The users and messages you are seeing are from text files, specifically messages.txt and users.txt
users.txt is where the users will act like, a lone viewer.
messages.txt is where you can type your whole message and then place in there like it's a Twitch live stream.
MAKE SURE BOTH FILES THAT ENDS WITH .TXT MUST BE IN scripts/ OR ELSE YOU'LL GET A SCRIPT ERROR.
]]
local chat = {
-- Don't touch this.
users = {},
messages = {},
messageNames = {},
userColors = {},
inChat = {},
targetNum = 0,
intendedViewers = 1;
canRollViewers = false;
messageSent = 0;
}
function onCreatePost()
luaDebugMode = true
chat.users = getTextAndSplitLines("users")
chat.messages = getTextAndSplitLines("messages")
makeLuaSprite("chatBox", "", 0, 420)
makeGraphic("chatBox", 480, 300, "000000")
setObjectCamera("chatBox", "other")
setProperty("chatBox.alpha", 0.3)
addLuaSprite("chatBox")
makeLuaText("viewerCount", getRandomViewers(), 1280, -10, 690)
setTextSize("viewerCount", 20)
setTextAlignment("viewerCount", "right")
setObjectCamera("viewerCount", "other")
addLuaText("viewerCount")
makeLuaSprite("vc", "", 1)
for i = 1, #chat.users do
table.insert(chat.userColors, {chat.users[i] .. ":", getRandomColor()})
runTimer("newMessage" .. i, getRandomFloat(0, 50))
end
runTimer("updateViewers", 20, 0)
end
function onUpdate(elapsed)
if chat.canRollViewers then
chat.intendedViewers = getProperty("vc.x")
setTextString("viewerCount", getRandomViewers())
end
end
function onTimerCompleted(tag, loops, loopsLeft)
if stringStartsWith(tag, "newMessage") then
local randomInt = tonumber(tag:sub(11, #tag))
local randomMessage = chat.messages[getRandomInt(1, #chat.messages)]
local length = #(chat.users[randomInt] .. ":") + 1
local increment = math.floor(#((" "):rep(length) .. randomMessage) / 40)
for i=1, #chat.messageNames do
setProperty(chat.messageNames[i] .. ".y", getProperty(chat.messageNames[i] .. ".y") - 20 - (18 * increment))
end
for j = 1, 2 do
local name = "chatMessage" .. chat.messageSent .. j
table.insert(chat.messageNames, name)
local n = chat.users[randomInt] .. ":"
if j == 2 then n = randomMessage end
makeLuaText(name, (j == 2 and (" "):rep(length) .. n or n), 460, 7, 694 - (18 * increment))
setTextAlignment(name, "left")
setTextSize(name, 18)
if j == 1 then
setTextColor(name, getIndexColor(n))
checkContains(n)
end
setObjectCamera(name, "other")
addLuaText(name)
end
chat.messageSent = chat.messageSent + 1
local i = 1
while i < #chat.messageNames do
if getProperty(chat.messageNames[i] .. ".y") < 420 then
removeLuaText(chat.messageNames[i])
table.remove(chat.messageNames, i)
i = i - 1
end
i = i + 1
end
runTimer("newMessage" .. randomInt, getRandomFloat(0, 50))
elseif tag == "updateViewers" then
for i = 1, #chat.inChat do
if chat.inChat[i][2] <= getSongPosition() then
table.remove(chat.inChat, i)
return
end
end
doTweenX("r", "vc", #chat.inChat + 1, 5, "sineOut")
chat.targetNum = #chat.inChat + 1
chat.canRollViewers = true
end
end
function getIndexColor(user)
for i = 1, #chat.userColors do
if chat.userColors[i][1] == user then
return chat.userColors[i][2]
end
end
return "000000"
end
function getRandomViewers()
return math.floor(chat.intendedViewers) .. " viewer" .. (math.floor(chat.intendedViewers) == 1 and "." or "s.")
end
function checkContains(user)
for i = 1, #chat.inChat do
if chat.inChat[i][1] == user then
chat.inChat[i][2] = getSongPosition()+30000
return
end
end
table.insert(chat.inChat, {user, getSongPosition()+30000})
end
function onTweenCompleted(tag)
if tag == "r" then
chat.canRollViewers = false
end
end
function getRandomColor()
local hexadecimal = ''
local rgb = {getRandomInt(0, 255), getRandomInt(0, 255), getRandomInt(0, 255)}
for key, value in pairs(rgb) do
local hex = ''
while (value > 0) do
local index = math.fmod(value, 16)+1
value = math.floor(value / 16)
hex = string.sub('0123456789ABCDEF', index, index) .. hex
end
if (string.len(hex) == 0) then
hex = '00'
elseif (string.len(hex) == 1) then
hex = '0' .. hex
end
hexadecimal = hexadecimal .. hex
end
return hexadecimal
end
function getTextAndSplitLines(fileName)
local text = getTextFromFile("scripts/" .. fileName .. ".txt")
local t = {}
for line in text:gmatch("[^\r\n]+") do table.insert(t, line) end
return t
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment