<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.runerealm.org/index.php?action=history&amp;feed=atom&amp;title=Module%3ASkilling_success_chart%2FSandbox</id>
	<title>Module:Skilling success chart/Sandbox - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.runerealm.org/index.php?action=history&amp;feed=atom&amp;title=Module%3ASkilling_success_chart%2FSandbox"/>
	<link rel="alternate" type="text/html" href="https://wiki.runerealm.org/index.php?title=Module:Skilling_success_chart/Sandbox&amp;action=history"/>
	<updated>2026-04-21T10:22:48Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.41.1</generator>
	<entry>
		<id>https://wiki.runerealm.org/index.php?title=Module:Skilling_success_chart/Sandbox&amp;diff=38433&amp;oldid=prev</id>
		<title>Alex: Created page with &quot;local chart = require( &#039;Module:Chart data&#039; )  local p = {}  function interp(low, high, level) 	local value = math.floor(low*(99-level)/98 + high*(level-1)/98 + 0.5) + 1 	return math.min(math.max(value / 256, 0), 1)	 end  function oldInterp(low, high, level) 	local value = math.modf(low*(99-level)/98) + math.modf(high*(level-1)/98) + 1 	return math.min(math.max(value / 256, 0), 1)	 end  function bonusInterp(low, high, bonuslow, bonushigh, level) 	local value = interp(low,...&quot;</title>
		<link rel="alternate" type="text/html" href="https://wiki.runerealm.org/index.php?title=Module:Skilling_success_chart/Sandbox&amp;diff=38433&amp;oldid=prev"/>
		<updated>2024-10-17T10:23:52Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;local chart = require( &amp;#039;Module:Chart data&amp;#039; )  local p = {}  function interp(low, high, level) 	local value = math.floor(low*(99-level)/98 + high*(level-1)/98 + 0.5) + 1 	return math.min(math.max(value / 256, 0), 1)	 end  function oldInterp(low, high, level) 	local value = math.modf(low*(99-level)/98) + math.modf(high*(level-1)/98) + 1 	return math.min(math.max(value / 256, 0), 1)	 end  function bonusInterp(low, high, bonuslow, bonushigh, level) 	local value = interp(low,...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;local chart = require( &amp;#039;Module:Chart data&amp;#039; )&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
function interp(low, high, level)&lt;br /&gt;
	local value = math.floor(low*(99-level)/98 + high*(level-1)/98 + 0.5) + 1&lt;br /&gt;
	return math.min(math.max(value / 256, 0), 1)	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function oldInterp(low, high, level)&lt;br /&gt;
	local value = math.modf(low*(99-level)/98) + math.modf(high*(level-1)/98) + 1&lt;br /&gt;
	return math.min(math.max(value / 256, 0), 1)	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function bonusInterp(low, high, bonuslow, bonushigh, level)&lt;br /&gt;
	local value = interp(low, high, level)&lt;br /&gt;
	return value + (1-value)*interp(bonuslow, bonushigh, level)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function exponentInterp(low, high, exponent, level)&lt;br /&gt;
	return interp(low, high, level) ^ exponent&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function cascadeInterp(bounds, level, index)&lt;br /&gt;
	local rate = 1.0&lt;br /&gt;
	for i, v in ipairs(bounds) do&lt;br /&gt;
		local low = (level &amp;gt;= v.altreq) and v.altlow or v.low&lt;br /&gt;
		local high = (level &amp;gt;= v.altreq) and v.althigh or v.high&lt;br /&gt;
		if i == index then&lt;br /&gt;
			rate = rate * interp(low, high, level)&lt;br /&gt;
			return rate&lt;br /&gt;
		end&lt;br /&gt;
		if level &amp;gt;= v.req then&lt;br /&gt;
			rate = rate * (1 - interp(low, high, level))&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function birdhouseInterp(high, level)&lt;br /&gt;
	local level = math.max(50, level)&lt;br /&gt;
	local value = math.modf(high*(level-1)/98)&lt;br /&gt;
	return value / 1000&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function ctsYield(low, high, level, lives)&lt;br /&gt;
	return lives / (1-interp(low, high, level))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function scriptInterp(low, high, level)&lt;br /&gt;
	local value = math.modf(low*(99-level)/98 + high*(level-1)/98)&lt;br /&gt;
	return math.min(math.max(value / 256, 0), 1)	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function caviarInterp(level, denom)&lt;br /&gt;
	return math.min(level, denom) / denom&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p._calculateDataSets(args)&lt;br /&gt;
	local dataSets = {}&lt;br /&gt;
	local inputs = {}&lt;br /&gt;
	local i = 1&lt;br /&gt;
	while args[&amp;#039;label&amp;#039; .. i] do&lt;br /&gt;
		table.insert(inputs, {&lt;br /&gt;
			label = args[&amp;#039;label&amp;#039; .. i],&lt;br /&gt;
			low = args[&amp;#039;low&amp;#039; .. i] or 0,&lt;br /&gt;
			high = args[&amp;#039;high&amp;#039; .. i],&lt;br /&gt;
			bonuslow = args[&amp;#039;bonuslow&amp;#039; .. i] or nil,&lt;br /&gt;
			bonushigh = args[&amp;#039;bonushigh&amp;#039; .. i] or nil,&lt;br /&gt;
			altlow = args[&amp;#039;altlow&amp;#039; .. i] or args[&amp;#039;low&amp;#039; .. i] or 0,&lt;br /&gt;
			althigh = args[&amp;#039;althigh&amp;#039; .. i] or args[&amp;#039;high&amp;#039; .. i],&lt;br /&gt;
			altreq = tonumber(args[&amp;#039;altreq&amp;#039; .. i] or math.huge),&lt;br /&gt;
			denom = args[&amp;#039;denom&amp;#039; .. i],&lt;br /&gt;
			req = tonumber(args[&amp;#039;req&amp;#039; .. i] or 1),&lt;br /&gt;
			image = args[&amp;#039;image&amp;#039; .. i] or &amp;#039;hi&amp;#039;,&lt;br /&gt;
			color = args[&amp;#039;color&amp;#039; .. i] or &amp;#039;&amp;#039;,&lt;br /&gt;
			exponent = args[&amp;#039;exponent&amp;#039; .. i] or 1,&lt;br /&gt;
			lives = args[&amp;#039;lives&amp;#039; .. i] or 0&lt;br /&gt;
		})&lt;br /&gt;
		i = i + 1&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	args.lowLevel = tonumber(args.lowLevel or 1)&lt;br /&gt;
	args.highLevel = tonumber(args.highLevel or 99)&lt;br /&gt;
&lt;br /&gt;
	for i, input in ipairs(inputs) do&lt;br /&gt;
		local cutoffLevel = nil&lt;br /&gt;
		local data = {}&lt;br /&gt;
		for x = 1, input.req do&lt;br /&gt;
			local y&lt;br /&gt;
			if args.cascade then&lt;br /&gt;
				y = cascadeInterp(inputs, x, i)&lt;br /&gt;
			elseif args.birdhouse then&lt;br /&gt;
				y = birdhouseInterp(input.high, x)&lt;br /&gt;
			elseif (input.lives ~= 0) then&lt;br /&gt;
				y = ctsYield(input.low, input.high, x, input.lives)&lt;br /&gt;
			elseif args.script then&lt;br /&gt;
				y = scriptInterp(input.low, input.high, x)&lt;br /&gt;
			elseif args.caviar then&lt;br /&gt;
				y = caviarInterp(x, input.denom)&lt;br /&gt;
			elseif (input.exponent ~= 1) then&lt;br /&gt;
				y = exponentInterp(input.low, input.high, input.exponent, x)&lt;br /&gt;
			elseif input.bonuslow then&lt;br /&gt;
				y = bonusInterp(input.low, input.high, input.bonuslow, input.bonushigh, x)&lt;br /&gt;
			else&lt;br /&gt;
				y = interp(input.low, input.high, x)&lt;br /&gt;
			end&lt;br /&gt;
			if args.showbefore ~= &amp;#039;no&amp;#039; or input.req == x or (y &amp;gt;= 0.999 and input.lives == 0) then&lt;br /&gt;
				table.insert(data, {x=x, y=y})&lt;br /&gt;
			end&lt;br /&gt;
			if y &amp;gt;= 0.999 and input.lives == 0  then&lt;br /&gt;
				cutoffLevel = x&lt;br /&gt;
				break&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		table.insert(dataSets, {&lt;br /&gt;
	        data = data,&lt;br /&gt;
	        label = input.label .. &amp;quot;  &amp;quot;,&lt;br /&gt;
	        borderDash = {5, 5},&lt;br /&gt;
	        borderCapStyle = &amp;#039;round&amp;#039;,&lt;br /&gt;
	        pointRadius = 0,&lt;br /&gt;
	        baseColor = input.color,&lt;br /&gt;
	        pointStyleImg = input.image,&lt;br /&gt;
	    })&lt;br /&gt;
&lt;br /&gt;
	    data = {}&lt;br /&gt;
		for x = input.req, args.highLevel do&lt;br /&gt;
			if cutoffLevel ~= nil then&lt;br /&gt;
				break&lt;br /&gt;
			end&lt;br /&gt;
			local y&lt;br /&gt;
			if args.cascade then&lt;br /&gt;
				y = cascadeInterp(inputs, x, i)&lt;br /&gt;
			elseif args.birdhouse then&lt;br /&gt;
				y = birdhouseInterp(input.high, x)&lt;br /&gt;
			elseif (input.lives ~= 0) then&lt;br /&gt;
				y = ctsYield(input.low, input.high, x, input.lives)&lt;br /&gt;
			elseif args.script then&lt;br /&gt;
				y = scriptInterp(input.low, input.high, x)&lt;br /&gt;
			elseif args.caviar then&lt;br /&gt;
				y = caviarInterp(x, input.denom)&lt;br /&gt;
			elseif (input.exponent ~= 1) then&lt;br /&gt;
				y = exponentInterp(input.low, input.high, input.exponent, x)&lt;br /&gt;
			elseif input.bonuslow then&lt;br /&gt;
				y = bonusInterp(input.low, input.high, input.bonuslow, input.bonushigh, x)&lt;br /&gt;
			else&lt;br /&gt;
				y = interp(input.low, input.high, x)&lt;br /&gt;
			end&lt;br /&gt;
			if y &amp;gt;= 0.999 and cutoffLevel == nil and input.lives == 0 then&lt;br /&gt;
				cutoffLevel = x&lt;br /&gt;
			end&lt;br /&gt;
			table.insert(data, {x=x, y=y})&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		table.insert(dataSets, {&lt;br /&gt;
	        data = data,&lt;br /&gt;
	        label = input.label .. &amp;quot;  &amp;quot;,&lt;br /&gt;
	        borderDash = {},&lt;br /&gt;
	        borderCapStyle = &amp;#039;round&amp;#039;,&lt;br /&gt;
	        baseColor = input.color,&lt;br /&gt;
	        pointRadius = 0,&lt;br /&gt;
	    })&lt;br /&gt;
&lt;br /&gt;
	    if cutoffLevel ~= nil then&lt;br /&gt;
	    	table.insert(dataSets, {&lt;br /&gt;
		        data = {{x = cutoffLevel, y = 1}},&lt;br /&gt;
		        borderDash = {},&lt;br /&gt;
		        borderCapStyle = &amp;#039;round&amp;#039;,&lt;br /&gt;
		        baseColor = input.color,&lt;br /&gt;
		        pointRadius = 5,&lt;br /&gt;
	    	})&lt;br /&gt;
	    else&lt;br /&gt;
			table.insert(dataSets, {})&lt;br /&gt;
	    end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return dataSets&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.main(frame)&lt;br /&gt;
	local args = frame:getParent().args&lt;br /&gt;
	&lt;br /&gt;
	return p._main(args)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p._main(args)&lt;br /&gt;
&lt;br /&gt;
    local plot = chart.newChart{ type = &amp;#039;scatter&amp;#039; }&lt;br /&gt;
        :setTitle( args.label )&lt;br /&gt;
        :setDimensions( &amp;#039;540px&amp;#039;, &amp;#039;400px&amp;#039;, &amp;#039;540px&amp;#039;, &amp;#039;400px&amp;#039;, true )&lt;br /&gt;
        :setXLabel( args.xlabel or &amp;#039;Level&amp;#039; )&lt;br /&gt;
        :setYLabel( args.ylabel or &amp;#039;Success rate&amp;#039; )&lt;br /&gt;
        :setXLimits( nil, nil, 1 )&lt;br /&gt;
        :setDatasetsPerGroup(3)&lt;br /&gt;
        &lt;br /&gt;
    if args.lives1 == nil then&lt;br /&gt;
    	plot:setYFormat( &amp;#039;percent&amp;#039; )&lt;br /&gt;
        :setYLimits( nil, nil, 0.1 )&lt;br /&gt;
        :setTooltipFormat( &amp;#039;skillingSuccess&amp;#039; )&lt;br /&gt;
    else&lt;br /&gt;
    	plot:setYLimits( 0, nil, (tonumber(args.ystep) or 5))&lt;br /&gt;
        :setTooltipFormat( &amp;#039;harvestLives&amp;#039; )&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
	local dataSets = p._calculateDataSets(args)&lt;br /&gt;
	for i, dataSet in ipairs(dataSets) do&lt;br /&gt;
		plot:newDataSet(dataSet)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
    return plot&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Alex</name></author>
	</entry>
</feed>