Lua Quick Start
Integrate Indieop API into your Lua games using LÖVE, Corona, or Defold.
Prerequisites
Before you begin, make sure you have:
- Created an Indieop account
- Created a game and obtained your API key from the game settings
- Installed a JSON library for Lua (most frameworks include one)
Overview
This guide shows you how to send player feedback and form submissions from your Lua game to the Indieop API. Compatible with:
- LÖVE (Love2D): Using socket.http library
- Corona SDK: Using network.request
- Defold: Using http.request
LÖVE (Love2D) Implementation
Step 1: Install Dependencies
First, ensure you have LuaSocket and a JSON library. For LÖVE, you can use the built-in or add these libraries to your project.
Step 2: Create the API Client
Create a new file called indieop.lua:
-- indieop.lua
local https = require("https")
local json = require("json") -- or dkjson, cjson, etc.
local IndieOp = {}
IndieOp.__index = IndieOp
function IndieOp:new(apiKey)
local client = {
apiKey = apiKey,
baseURL = "https://indieop.com/api/sdk"
}
setmetatable(client, IndieOp)
return client
end
function IndieOp:submitForm(submissionData, callback)
local url = self.baseURL .. "/submit"
local jsonData = json.encode(submissionData)
local headers = {
["Content-Type"] = "application/json",
["X-API-Key"] = self.apiKey,
["Content-Length"] = tostring(#jsonData)
}
https.request(url, {
method = "POST",
headers = headers,
body = jsonData
}, function(code, body, headers)
if code == 200 or code == 201 then
local response = json.decode(body)
print("Submission successful: " .. response.message)
if callback then callback(true, response) end
else
local errorResponse = json.decode(body)
print("Submission failed: " .. errorResponse.message)
if callback then callback(false, errorResponse) end
end
end)
end
function IndieOp:createField(key, label, fieldType, value, options)
local field = {
key = key,
label = label,
type = fieldType,
value = value
}
if options then
field.options = options
end
return field
end
return IndieOp
Step 3: Use the Client in Your Game
Here's how to use it in your LÖVE game:
-- main.lua
local IndieOp = require("indieop")
local client = IndieOp:new("your_game_api_key_here")
local feedbackSubmitted = false
function love.load()
-- Game initialization
love.window.setTitle("My Awesome Game")
end
function submitPlayerFeedback(rating, comments)
local submission = {
form_name = "Player Feedback",
tag = "feedback",
form_type = "feedback",
player_identifier = love.system.getOS() .. "_player",
game_version = "1.0.0",
fields = {
client:createField("rating", "Overall Rating", "rating", rating),
client:createField("comments", "Your Feedback", "text", comments),
client:createField("enjoyed", "Did you enjoy?", "checkbox", true)
}
}
client:submitForm(submission, function(success, response)
if success then
print("Thank you for your feedback!")
feedbackSubmitted = true
else
print("Failed to submit feedback. Please try again.")
end
end)
end
function love.keypressed(key)
if key == "f" then
-- Submit feedback when player presses 'F'
submitPlayerFeedback(5, "This game is amazing!")
end
end
function love.draw()
love.graphics.print("Press 'F' to submit feedback", 10, 10)
if feedbackSubmitted then
love.graphics.print("Feedback submitted! Thank you!", 10, 30)
end
end
Corona SDK Implementation
Corona SDK has built-in network support. Create indieop.lua:
-- indieop.lua (Corona SDK)
local json = require("json")
local IndieOp = {}
IndieOp.__index = IndieOp
function IndieOp:new(apiKey)
local client = {
apiKey = apiKey,
baseURL = "https://indieop.com/api/sdk"
}
setmetatable(client, IndieOp)
return client
end
function IndieOp:submitForm(submissionData, callback)
local url = self.baseURL .. "/submit"
local headers = {
["Content-Type"] = "application/json",
["X-API-Key"] = self.apiKey
}
local params = {
headers = headers,
body = json.encode(submissionData)
}
local function networkListener(event)
if event.isError then
print("Network error: " .. event.response)
if callback then callback(false, nil) end
else
local response = json.decode(event.response)
if event.status == 200 or event.status == 201 then
print("Submission successful!")
if callback then callback(true, response) end
else
print("Submission failed: " .. response.message)
if callback then callback(false, response) end
end
end
end
network.request(url, "POST", networkListener, params)
end
function IndieOp:createField(key, label, fieldType, value, options)
local field = {
key = key,
label = label,
type = fieldType,
value = value
}
if options then
field.options = options
end
return field
end
return IndieOp
Usage in Corona SDK
-- main.lua (Corona SDK)
local IndieOp = require("indieop")
local client = IndieOp:new("your_game_api_key_here")
local function submitBugReport(description)
local submission = {
form_name = "Bug Report",
tag = "bugs",
form_type = "bug_report",
player_identifier = system.getInfo("deviceID"),
game_version = "1.0.0",
repository_version = "main@abc123",
fields = {
client:createField("description", "Bug Description", "text", description),
client:createField("severity", "Severity", "dropdown", "Medium",
{"Low", "Medium", "High", "Critical"}),
client:createField("reproducible", "Can Reproduce?", "checkbox", true)
}
}
client:submitForm(submission, function(success, response)
if success then
native.showAlert("Thank You", "Bug report submitted successfully!", {"OK"})
else
native.showAlert("Error", "Failed to submit bug report", {"OK"})
end
end)
end
-- Example: Submit bug report when button is tapped
local submitButton = display.newText({
text = "Report Bug",
x = display.contentCenterX,
y = display.contentCenterY,
font = native.systemFont,
fontSize = 24
})
submitButton:addEventListener("tap", function()
submitBugReport("Player character gets stuck in wall at level 2")
end)
Defold Implementation
Defold uses its own HTTP module. Create indieop.lua:
-- indieop.lua (Defold)
local M = {}
M.api_key = nil
M.base_url = "https://indieop.com/api/sdk"
function M.init(api_key)
M.api_key = api_key
end
function M.submit_form(submission_data, callback)
local url = M.base_url .. "/submit"
local json_data = json.encode(submission_data)
local headers = {
["Content-Type"] = "application/json",
["X-API-Key"] = M.api_key
}
http.request(url, "POST", function(self, id, response)
if response.status == 200 or response.status == 201 then
local result = json.decode(response.response)
print("Submission successful: " .. result.message)
if callback then callback(true, result) end
else
local error_result = json.decode(response.response)
print("Submission failed: " .. error_result.message)
if callback then callback(false, error_result) end
end
end, headers, json_data)
end
function M.create_field(key, label, field_type, value, options)
local field = {
key = key,
label = label,
type = field_type,
value = value
}
if options then
field.options = options
end
return field
end
return M
Usage in Defold
-- feedback_script.script (Defold)
local indieop = require("indieop")
function init(self)
-- Initialize the client
indieop.init("your_game_api_key_here")
end
function submit_feedback(rating, comments, difficulty)
local submission = {
form_name = "Player Feedback",
tag = "feedback",
form_type = "feedback",
player_identifier = sys.get_sys_info().device_ident,
game_version = sys.get_config("project.version"),
fields = {
indieop.create_field("rating", "Overall Rating", "rating", rating),
indieop.create_field("comments", "Comments", "text", comments),
indieop.create_field("difficulty", "Difficulty", "dropdown", difficulty,
{"Easy", "Medium", "Hard"})
}
}
indieop.submit_form(submission, function(success, response)
if success then
print("Feedback submitted successfully!")
-- Update UI to show success
else
print("Failed to submit feedback")
-- Show error message
end
end)
end
function on_message(self, message_id, message, sender)
if message_id == hash("submit_feedback") then
submit_feedback(message.rating, message.comments, message.difficulty)
end
end
Field Types Reference
The Indieop API supports four field types:
| Field Type | Lua Type | Example |
|---|---|---|
| text | string | "Great game!" |
| rating | number (1-5) | 5 |
| checkbox | boolean | true |
| dropdown | string (from options) | "Medium" |
Error Handling
Always handle errors gracefully in your game:
local failedSubmissions = {}
local function storeFailedSubmission(data)
table.insert(failedSubmissions, {
data = data,
timestamp = os.time()
})
print("Submission stored locally for retry")
end
local function submitWithRetry(client, submission, maxRetries)
maxRetries = maxRetries or 3
local attempts = 0
local function attemptSubmit()
attempts = attempts + 1
client:submitForm(submission, function(success, response)
if success then
print("Submission successful after " .. attempts .. " attempts")
elseif attempts < maxRetries then
print("Attempt " .. attempts .. " failed, retrying...")
-- Wait and retry
timer.performWithDelay(1000 * attempts, attemptSubmit)
else
print("All retry attempts failed")
storeFailedSubmission(submission)
end
end)
end
attemptSubmit()
end
-- Retry failed submissions later
local function retryFailedSubmissions(client)
for i = #failedSubmissions, 1, -1 do
local item = failedSubmissions[i]
client:submitForm(item.data, function(success, response)
if success then
table.remove(failedSubmissions, i)
print("Successfully submitted queued submission")
end
end)
end
end
Best Practices
- Store API key securely: Don't hardcode it in version control
- Handle network errors: Implement retry logic and offline queueing
- Validate data locally: Check field values before sending
- Rate limiting: Don't exceed 100 requests per minute
- Use appropriate JSON library: Different Lua environments have different JSON libraries
- Test thoroughly: Test both success and failure cases