# Development Stub

You can put this above your script to make Luraph & Luaprot macros & runtime variables work during testing with source code.

{% hint style="info" %}
The storage macros in the development stub (obfuscate script macros do work!) are not functional at the moment, we're working to add development functionality for these ASAP! (LP\_SAVE\_VALUE, LP\_GET\_VALUE and LP\_DELETE\_VALUE)
{% endhint %}

```luau
if not LPH_OBFUSCATED then -- This block of code is automatically removed by Luraph upon obfuscation, you can keep it in your script.
	-- Required for LP_DASHBOARD & Storage macros
	local DevApiKey = "" -- Your dev API key from https://luaprot.net/dashboard/account/api
	local ScriptId = "" -- Your script ID
	local Key = "" -- Your script key, just a normal script key

	LPH_ENCNUM = function(toEncrypt, ...)
		assert(type(toEncrypt) == "number" and #{...} == 0, "LPH_ENCNUM only accepts a single double or integer as an argument.")
		return toEncrypt
	end
	LPH_NUMENC = LPH_ENCNUM

	LPH_ENCSTR = function(toEncrypt, ...)
		assert(type(toEncrypt) == "string" and #{...} == 0, "LPH_ENCSTR only accepts a single string as an argument.")
		return toEncrypt
	end
	LPH_STRENC = LPH_ENCSTR

	LPH_ENCFUNC = function(toEncrypt, encKey, decKey, ...)
		assert(type(toEncrypt) == "function" and type(encKey) == "string" and #{...} == 0, "LPH_ENCFUNC accepts a function, constant string, and string variable as arguments.")
		return toEncrypt
	end
	LPH_FUNCENC = LPH_ENCFUNC

	LPH_JIT = function(f, ...)
		assert(type(f) == "function" and #{...} == 0, "LPH_JIT only accepts a single function as an argument.")
		return f
	end
	LPH_JIT_MAX = LPH_JIT

	LPH_NO_VIRTUALIZE = function(f, ...)
		assert(type(f) == "function" and #{...} == 0, "LPH_NO_VIRTUALIZE only accepts a single function as an argument.")
		return f
	end

	LPH_NO_UPVALUES = function(f, ...)
		assert(type(setfenv) == "function", "LPH_NO_UPVALUES can only be used on Lua versions with getfenv & setfenv")
		assert(type(f) == "function" and #{...} == 0, "LPH_NO_UPVALUES only accepts a single function as an argument.")
		return f
	end

	LPH_CRASH = function(...)
		assert(#{...} == 0, "LPH_CRASH does not accept any arguments.")
		error("LPH_CRASH called")
	end

	LP_BLACKLIST = function(s, ...)
		assert(#{...} == 0, "LP_BLACKLIST only accepts 1 argument.")
		assert(type(s) == "string", "LP_BLACKLIST requires 1 string argument.")
		error("LP_BLACKLIST called: " .. s)
	end

	LP_VMIFY = function(f, ...)
		assert(type(f) == "function" and #{...} == 0, "LP_VMIFY only accepts a single function as an argument.")
		return f
	end

	LP_INIT = function(f, ...)
		assert(type(f) == "function" and #{...} == 0, "LP_INIT only accepts a single function as an argument.")
		task.spawn(f)
	end

	LP_DISCORD = "unknown"
	LP_DISCORD_ID = 0
	LP_KEYNOTE = ""
	LP_EXECUTIONS = 1
	LP_SCRIPT_EXECUTIONS = 1
	LP_FINGERPRINT = gethwid and gethwid() or "unknown"
	LP_TIMELEFT = 0
	LP_PREMIUM = true
	LP_SCRIPT_NAME = "Development Stub"
	LP_SCRIPT_VERSION = 1
	LP_SESSION_ID = "unknown"
	LP_SESSION_COUNT = 1

	LP_SECURE_REQUEST = (http and http.request) or request

	LP_DASHBOARD = loadstring(game:HttpGet("https://sdk.luaprot.net/dashboard-library.lua"))()
	LP_DASHBOARD.ScriptId = ScriptId
	LP_DASHBOARD.Key = Key
	LP_DASHBOARD.DevApiKey = DevApiKey

	LP_SAVE_VALUE = function(key, value, overwrite)
		assert(type(key) == "string", "LP_SAVE_VALUE requires a string as first argument.")
		assert(type(value) ~= "string" and type(value) ~= "number" and type(value) ~= "boolean", "LP_SAVE_VALUE requires a string, number or boolean as second argument.")
	end

	LP_GET_VALUE = function(key)
		assert(type(key) == "string", "LP_GET_VALUE requires a string key.")
	end

	LP_DELETE_VALUE = function(key)
		assert(type(key) == "string", "LP_DELETE_VALUE requires a string key.")
	end
end
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.luaprot.net/luaprot/macro-documentation/development-stub.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
