README.md |
Table of Contents
- Overview
- Engine Table
- Renderer Table
- Utility Functions
- Example Lua Scripts
- Best Practices
- Troubleshooting
Overview
This documentation outlines the Lua API exposed by your C++ application, allowing Lua scripts to interact with the engine's functionalities and perform rendering operations using ImGui. The API is organized into two primary tables:
- Engine: Provides utility functions related to logging, coordinate transformations, and settings management.
- Renderer: Offers a suite of drawing functions to render shapes, images, and text on the screen.
Additionally, utility functions like GetPlayers
facilitate data retrieval from the C++ side to Lua.
Engine Table
The Engine
table encapsulates functions related to debugging, coordinate transformations, screen information, and settings management. These functions are accessible in Lua as Engine.<FunctionName>
.
1. Engine.LogDebug
Description: Logs a debug message to the engine's logging system.
Usage:
Engine.LogDebug(message)
Parameters:
message
(string
): The debug message to log.
Example:
Engine.LogDebug("This is a debug message.")
Notes:
- Primarily used for development and debugging purposes.
- Depending on your logging configuration, debug messages may be visible only in development builds.
2. Engine.LogError
Description: Logs an error message to the engine's logging system.
Usage:
Engine.LogError(message)
Parameters:
message
(string
): The error message to log.
Example:
Engine.LogError("An error has occurred in the script.")
Notes:
- Use this function to report errors that should be visible to users or developers.
- Errors are typically more prominent in logs and may trigger alerting mechanisms if implemented.
3. Engine.WorldToScreen
Description: Transforms world coordinates (x, y, z)
to screen coordinates (screenX, screenY)
.
Usage:
success, screenX, screenY = Engine.WorldToScreen(x, y, z)
Parameters:
x
(number
): The X-coordinate in the world space.y
(number
): The Y-coordinate in the world space.z
(number
): The Z-coordinate in the world space.
Returns:
success
(boolean
):true
if the transformation was successful;false
otherwise.screenX
(number
): The resulting X-coordinate on the screen (valid ifsuccess
istrue
).screenY
(number
): The resulting Y-coordinate on the screen (valid ifsuccess
istrue
).
Example:
local success, sx, sy = Engine.WorldToScreen(100.0, 200.0, 50.0)
if success then
Renderer.DrawCircle(sx, sy, 10, 255, 0, 0, 255) -- Draw a red circle at the screen position
else
Engine.LogError("WorldToScreen transformation failed.")
end
Notes:
- Ensure that the provided world coordinates are valid and within the visible range.
- The function relies on an external view matrix (
g_ViewMatrix
) for the transformation.
4. Engine.GetScreenSize
Description: Retrieves the current screen's width and height.
Usage:
width, height = Engine.GetScreenSize()
Returns:
width
(number
): The width of the screen in pixels.height
(number
): The height of the screen in pixels.
Example:
local screenWidth, screenHeight = Engine.GetScreenSize()
Renderer.DrawBox(screenWidth - 100, screenHeight - 50, 90, 40, 0, 255, 0, 255) -- Draw a green box near the bottom-right corner
Notes:
- Useful for positioning UI elements relative to the screen dimensions.
- Reflects the current display size; changes due to window resizing are updated accordingly.
5. Engine.Settings.Set
Description: Sets the value of a specified engine setting, particularly color configurations.
Usage:
Engine.Settings.Set(identifier, colorTable)
Parameters:
identifier
(string
): The name of the color setting to modify (e.g.,"g_GlobalColor"
).colorTable
(table
): A table containing four numerical values representing RGBA components, each ranging from0
to255
.
Color Identifiers:
"g_GlobalColor"
"g_RectangleColor"
"g_SkeletonColor"
"g_HealthColorLow"
"g_HealthColorHigh"
"g_GlowColor"
"g_OffscreenArrowColor"
"g_BombCircleColor"
"g_CircleColor"
"g_NameColor"
"g_FlagsColor"
Example:
-- Set the global color to blue with full opacity
Engine.Settings.Set("g_GlobalColor", {0, 0, 255, 255})
-- Set the health color low threshold to red with half opacity
Engine.Settings.Set("g_HealthColorLow", {255, 0, 0, 128})
Notes:
- The
colorTable
must contain exactly four numerical values corresponding to red (r
), green (g
), blue (b
), and alpha (a
) channels. - Values must be within the range
[0, 255]
. Out-of-range values will result in an error. - Changing these settings may immediately affect rendering elements that rely on these color configurations.
Renderer Table
The Renderer
table provides a collection of functions to draw various shapes, images, and text on the screen. These functions leverage ImGui's drawing capabilities and are accessible in Lua as Renderer.<FunctionName>
.
1. Renderer.DrawBox
Description: Draws a filled rectangle (box) on the screen.
Usage:
Renderer.DrawBox(x, y, width, height, r, g, b, a)
Parameters:
x
(number
): The X-coordinate of the top-left corner.y
(number
): The Y-coordinate of the top-left corner.width
(number
): The width of the box in pixels.height
(number
): The height of the box in pixels.r
(number
): Red component of the color (0
-255
).g
(number
): Green component of the color (0
-255
).b
(number
): Blue component of the color (0
-255
).a
(number
): Alpha (opacity) component of the color (0
-255
).
Example:
-- Draw a semi-transparent blue box at (50, 50) with size 100x150
Renderer.DrawBox(50, 50, 100, 150, 0, 0, 255, 128)
Notes:
- The box is drawn relative to the screen's coordinate system.
- Alpha (
a
) controls the transparency;0
is fully transparent, and255
is fully opaque.
2. Renderer.DrawCircle
Description: Draws a filled circle on the screen.
Usage:
Renderer.DrawCircle(x, y, radius, r, g, b, a)
Parameters:
x
(number
): The X-coordinate of the circle's center.y
(number
): The Y-coordinate of the circle's center.radius
(number
): The radius of the circle in pixels.r
(number
): Red component of the color (0
-255
).g
(number
): Green component of the color (0
-255
).b
(number
): Blue component of the color (0
-255
).a
(number
): Alpha (opacity) component of the color (0
-255
).
Example:
-- Draw a solid red circle at (200, 200) with a radius of 50
Renderer.DrawCircle(200, 200, 50, 255, 0, 0, 255)
Notes:
- The circle is filled with the specified color and opacity.
- The number of segments (
24
in the C++ code) determines the smoothness of the circle.
3. Renderer.DrawLine
Description: Draws a straight line between two points on the screen.
Usage:
Renderer.DrawLine(x1, y1, x2, y2, r, g, b, a)
Parameters:
x1
(number
): The X-coordinate of the starting point.y1
(number
): The Y-coordinate of the starting point.x2
(number
): The X-coordinate of the ending point.y2
(number
): The Y-coordinate of the ending point.r
(number
): Red component of the line color (0
-255
).g
(number
): Green component of the line color (0
-255
).b
(number
): Blue component of the line color (0
-255
).a
(number
): Alpha (opacity) component of the line color (0
-255
).
Example:
-- Draw a green line from (300, 300) to (400, 400)
Renderer.DrawLine(300, 300, 400, 400, 0, 255, 0, 255)
Notes:
- Lines are drawn with a default thickness (
2.0f
in the C++ code). - The color's alpha value affects the line's transparency.
4. Renderer.DrawText
Description: Renders text at a specified position on the screen.
Usage:
Renderer.DrawText(x, y, text, r, g, b, a)
Parameters:
x
(number
): The X-coordinate where the text begins.y
(number
): The Y-coordinate where the text begins.text
(string
): The text string to render.r
(number
): Red component of the text color (0
-255
).g
(number
): Green component of the text color (0
-255
).b
(number
): Blue component of the text color (0
-255
).a
(number
): Alpha (opacity) component of the text color (0
-255
).
Example:
-- Draw white text at (500, 500)
Renderer.DrawText(500, 500, "Hello, World!", 255, 255, 255, 255)
Notes:
- The text uses ImGui's current font and font size.
- Ensure that the
text
parameter is a valid string to avoid rendering issues.
5. Renderer.DrawEllipse
Description: Draws a filled ellipse on the screen.
Usage:
Renderer.DrawEllipse(x, y, rx, ry, r, g, b, a)
Parameters:
x
(number
): The X-coordinate of the ellipse's center.y
(number
): The Y-coordinate of the ellipse's center.rx
(number
): The horizontal radius of the ellipse.ry
(number
): The vertical radius of the ellipse.r
(number
): Red component of the ellipse color (0
-255
).g
(number
): Green component of the ellipse color (0
-255
).b
(number
): Blue component of the ellipse color (0
-255
).a
(number
): Alpha (opacity) component of the ellipse color (0
-255
).
Example:
-- Draw a semi-transparent yellow ellipse at (600, 600) with radii 80 and 40
Renderer.DrawEllipse(600, 600, 80, 40, 255, 255, 0, 128)
Notes:
- The number of segments (
24
in the C++ code) determines the smoothness of the ellipse. - Similar to
DrawCircle
, the alpha value controls transparency.
6. Renderer.DrawPolygon
Description: Draws a filled convex polygon with a specified number of vertices.
Usage:
Renderer.DrawPolygon(n, x1, y1, x2, y2, ..., r, g, b, a)
Parameters:
n
(number
): The number of vertices (must be at least3
).x1
,y1
(number
): Coordinates of the first vertex.x2
,y2
(number
): Coordinates of the second vertex....
(number
): Coordinates of subsequent vertices (x3
,y3
, etc.).r
(number
): Red component of the polygon color (0
-255
).g
(number
): Green component of the polygon color (0
-255
).b
(number
): Blue component of the polygon color (0
-255
).a
(number
): Alpha (opacity) component of the polygon color (0
-255
).
Example:
-- Draw a green rectangle as a polygon
Renderer.DrawPolygon(4, 700, 700, 800, 700, 800, 800, 700, 800, 0, 255, 0, 255)
Notes:
- The polygon must be convex. Non-convex polygons may not render correctly.
- Ensure that the number of coordinates matches
n * 2
. - Alpha (
a
) controls the transparency of the polygon.
7. Renderer.DrawArc
Description: Draws an arc between two angles around a center point.
Usage:
Renderer.DrawArc(x, y, radius, start_angle, end_angle, r, g, b, a)
Parameters:
x
(number
): The X-coordinate of the arc's center.y
(number
): The Y-coordinate of the arc's center.radius
(number
): The radius of the arc.start_angle
(number
): The starting angle of the arc in degrees.end_angle
(number
): The ending angle of the arc in degrees.r
(number
): Red component of the arc color (0
-255
).g
(number
): Green component of the arc color (0
-255
).b
(number
): Blue component of the arc color (0
-255
).a
(number
): Alpha (opacity) component of the arc color (0
-255
).
Example:
-- Draw a blue arc from 0 to 180 degrees at (900, 900) with radius 100
Renderer.DrawArc(900, 900, 100, 0, 180, 0, 0, 255, 255)
Notes:
- Angles are specified in degrees. Ensure correct angle calculations when scripting.
- The arc is drawn as an outline with a default thickness (
2.0f
in the C++ code). - Alpha (
a
) controls the transparency of the arc.
8. Renderer.DrawBezierCurve
Description: Draws a cubic Bezier curve between two points with two control points.
Usage:
Renderer.DrawBezierCurve(x1, y1, cx1, cy1, cx2, cy2, x2, y2, r, g, b, a)
Parameters:
x1
,y1
(number
): Coordinates of the starting point.cx1
,cy1
(number
): Coordinates of the first control point.cx2
,cy2
(number
): Coordinates of the second control point.x2
,y2
(number
): Coordinates of the ending point.r
(number
): Red component of the curve color (0
-255
).g
(number
): Green component of the curve color (0
-255
).b
(number
): Blue component of the curve color (0
-255
).a
(number
): Alpha (opacity) component of the curve color (0
-255
).
Example:
-- Draw a yellow Bezier curve from (1000, 1000) to (1100, 1100) with control points
Renderer.DrawBezierCurve(1000, 1000, 1050, 950, 1150, 1150, 1100, 1100, 255, 255, 0, 255)
Notes:
- The curve is drawn with a default thickness (
2.0f
in the C++ code). - Control points influence the curvature; adjusting them alters the shape of the curve.
- Alpha (
a
) controls the transparency of the curve.
9. Renderer.DrawTriangle
Description: Draws a filled triangle defined by three vertices.
Usage:
Renderer.DrawTriangle(x1, y1, x2, y2, x3, y3, r, g, b, a)
Parameters:
x1
,y1
(number
): Coordinates of the first vertex.x2
,y2
(number
): Coordinates of the second vertex.x3
,y3
(number
): Coordinates of the third vertex.r
(number
): Red component of the triangle color (0
-255
).g
(number
): Green component of the triangle color (0
-255
).b
(number
): Blue component of the triangle color (0
-255
).a
(number
): Alpha (opacity) component of the triangle color (0
-255
).
Example:
-- Draw a purple triangle
Renderer.DrawTriangle(1200, 1200, 1250, 1250, 1200, 1300, 128, 0, 128, 255)
Notes:
- The triangle is filled with the specified color and opacity.
- Ensure that the three points do not lie on a straight line to form a valid triangle.
10. Renderer.DrawPolyline
Description: Draws a series of connected lines (polyline) between multiple points.
Usage:
Renderer.DrawPolyline(n, x1, y1, x2, y2, ..., r, g, b, a)
Parameters:
n
(number
): The number of points (must be at least2
).x1
,y1
(number
): Coordinates of the first point.x2
,y2
(number
): Coordinates of the second point....
(number
): Coordinates of subsequent points (x3
,y3
, etc.).r
(number
): Red component of the polyline color (0
-255
).g
(number
): Green component of the polyline color (0
-255
).b
(number
): Blue component of the polyline color (0
-255
).a
(number
): Alpha (opacity) component of the polyline color (0
-255
).
Example:
-- Draw a cyan polyline forming a V shape
Renderer.DrawPolyline(3, 1300, 1300, 1350, 1350, 1400, 1300, 0, 255, 255, 255)
Notes:
- The polyline is not closed; it connects each point sequentially without forming a loop.
- The line thickness is set to
2.0f
in the C++ code. - Alpha (
a
) controls the transparency of the polyline.
Utility Functions
GetPlayers
Description: Retrieves a table of player information from the C++ side. This function is exposed globally to Lua as GetPlayers
.
Usage:
players, error = GetPlayers()
Returns:
players
(table
): A table containing player data. Each entry corresponds to a player with various attributes.error
(string
, optional): An error message if the retrieval fails.nil
if successful.
Player Attributes: Each player table includes the following fields:
name
(string
): Player's name.ping
(number
): Player's ping in milliseconds.health
(number
): Player's health points.armor
(number
): Player's armor points.team
(number
): Player's team identifier.distance
(number
): Distance from the player to a reference point.hasDefuser
(boolean
): Indicates if the player has a defuser.hasHelmet
(boolean
): Indicates if the player has a helmet.position
(table
): Player's current position withx
,y
,z
coordinates.headPosition
(table
): Player's head position withx
,y
,z
coordinates.
Example:
local players, err = GetPlayers()
if not players then
Engine.LogError("Failed to retrieve players: " .. err)
else
for i, player in ipairs(players) do
Renderer.DrawText(player.position.x, player.position.y, player.name, 255, 255, 255, 255)
Renderer.DrawCircle(player.position.x, player.position.y, 10, 0, 255, 0, 255) -- Green circle for each player
end
end
Notes:
- The function returns
nil
and an error message if the players' data pointer is invalid. - Ensure that the
players
pointer is valid and that player data is populated on the C++ side.
Example Lua Scripts
Below are example Lua scripts demonstrating how to utilize the Engine
and Renderer
APIs to perform various tasks.
Example 1: Simple Debug Logging and Drawing
-- Log a debug message
Engine.LogDebug("Script initialized successfully.")
-- Get screen size
local width, height = Engine.GetScreenSize()
-- Draw a red box at the center of the screen
Renderer.DrawBox(width / 2 - 50, height / 2 - 50, 100, 100, 255, 0, 0, 255)
-- Draw a blue circle at the top-left corner
Renderer.DrawCircle(50, 50, 30, 0, 0, 255, 255)
-- Draw white text inside the box
Renderer.DrawText(width / 2 - 40, height / 2 - 20, "Hello!", 255, 255, 255, 255)
Example 2: Dynamic Player Indicators
function onTick()
local players, err = GetPlayers()
if not players then
Engine.LogError("Error retrieving players: " .. err)
return
end
for _, player in ipairs(players) do
if player.health > 0 then
Renderer.DrawCircle(player.position.x, player.position.y, 15, 0, 255, 0, 255) -- Green circle for alive players
Renderer.DrawText(player.position.x + 20, player.position.y, player.name, 255, 255, 255, 255)
else
Renderer.DrawCircle(player.position.x, player.position.y, 15, 255, 0, 0, 255) -- Red circle for dead players
Renderer.DrawText(player.position.x + 20, player.position.y, player.name, 255, 255, 255, 255)
end
end
end
Example 3: Drawing Complex Shapes
-- Draw an ellipse with semi-transparent purple color
Renderer.DrawEllipse(400, 400, 80, 40, 128, 0, 128, 128)
-- Draw a polygon (triangle) with yellow color
Renderer.DrawPolygon(3, 500, 500, 550, 500, 525, 550, 255, 255, 0, 255)
-- Draw an arc representing a 90-degree section
Renderer.DrawArc(600, 600, 60, 0, 90, 0, 255, 255, 255)
-- Draw a Bezier curve for a smooth path
Renderer.DrawBezierCurve(700, 700, 750, 650, 850, 750, 900, 700, 0, 255, 255, 255)
-- Draw a filled triangle
Renderer.DrawTriangle(1000, 1000, 1050, 1050, 1000, 1100, 255, 0, 255, 255)
-- Draw a polyline forming a zig-zag pattern
Renderer.DrawPolyline(4, 1100, 1100, 1150, 1150, 1200, 1100, 1250, 1150, 0, 255, 255, 255)
Best Practices
To ensure optimal performance, maintainability, and stability when using the Lua API, adhere to the following best practices:
-
Validate Inputs:
- Always provide the correct number and type of arguments when calling API functions.
- Utilize error handling (e.g., checking return values) to manage unexpected scenarios.
-
Optimize Drawing Calls:
- Minimize the number of drawing calls within high-frequency functions like
onTick
to prevent performance degradation. - Batch multiple drawing operations where possible.
- Minimize the number of drawing calls within high-frequency functions like
-
Manage Resources Wisely:
- Ensure that any resources (e.g., textures) used in drawing functions are properly loaded and managed on the C++ side.
- Avoid memory leaks by adhering to proper ownership and lifecycle management of objects.
-
Use Meaningful Logging:
- Leverage
Engine.LogDebug
andEngine.LogError
to trace script execution and debug issues. - Provide clear and concise log messages to facilitate troubleshooting.
- Leverage
-
Coordinate Systems Awareness:
- Understand the screen coordinate system where
(0,0)
typically represents the top-left corner. - Account for screen resizing by dynamically retrieving screen dimensions using
Engine.GetScreenSize
.
- Understand the screen coordinate system where
-
Thread Safety:
- If interacting with shared resources or multi-threaded systems, ensure that proper synchronization mechanisms are in place to prevent race conditions.
-
Consistent Style and Naming:
- Follow consistent naming conventions for variables and functions to enhance code readability.
- Structure your scripts logically, grouping related operations together.
-
Documentation and Comments:
- Comment your Lua scripts to explain complex logic or drawing sequences.
- Refer to this documentation as needed to understand the API functions and their usages.
Troubleshooting
Common Issues and Solutions
-
Error: "Invalid color identifier: "
Cause: The provided
identifier
string does not match any recognized color settings.Solution:
- Verify that the
identifier
matches one of the predefined color identifiers exactly (case-sensitive). - Refer to the Engine.Settings.Set documentation for available identifiers.
Example:
-- Correct identifier Engine.Settings.Set("g_GlobalColor", {255, 255, 255, 255}) -- Incorrect identifier (case-sensitive) Engine.Settings.Set("G_GlobalColor", {255, 255, 255, 255}) -- This will cause an error
- Verify that the
-
Error: "Renderer. expects numerical arguments at position "
Cause: One or more arguments provided to a drawing function are not numbers.
Solution:
- Ensure all positional arguments are of type
number
. - Check the order and count of arguments as per the function's documentation.
Example:
-- Correct usage Renderer.DrawBox(100, 100, 50, 50, 0, 0, 255, 255) -- Incorrect usage (non-number argument) Renderer.DrawBox(100, "100", 50, 50, 0, 0, 255, 255) -- Second argument should be a number
- Ensure all positional arguments are of type
-
Error: "Renderer. expects a lightuserdata for textureID"
Cause: The
textureID
provided toRenderer.DrawImage
is not a light userdata.Solution:
- Ensure that
textureID
is a validImTextureID
passed as light userdata from the C++ side. - Confirm that the texture is properly loaded and accessible.
Example:
-- Correct usage (assuming 'texture' is a valid ImTextureID) Renderer.DrawImage(texture, 300, 300, 100, 100, 255, 255, 255, 255) -- Incorrect usage Renderer.DrawImage("invalid_texture", 300, 300, 100, 100, 255, 255, 255, 255) -- Should be lightuserdata, not string
- Ensure that
-
Text Not Rendering or Positioned Incorrectly
Cause: The text position may be outside the visible screen area or the
text
string is empty.Solution:
- Verify that the
x
andy
coordinates are within the screen bounds. - Ensure that the
text
parameter contains a valid string.
Example:
-- Correct usage Renderer.DrawText(500, 500, "Player Name", 255, 255, 255, 255) -- Incorrect usage (out-of-bounds coordinates) Renderer.DrawText(-10, -10, "Hidden Text", 255, 255, 255, 255)
- Verify that the
-
No Visible Drawings Despite Correct Function Calls
Cause: The drawing functions rely on ImGui's drawing system, which may not be initialized or may have rendering issues.
Solution:
- Ensure that ImGui is properly initialized in your C++ application.
- Verify that the drawing occurs within a valid rendering loop.
- Check for any ImGui-related errors in the C++ logs.
Example:
// Ensure ImGui is initialized before running scripts ImGui::CreateContext(); // ... other ImGui setup code
Additional Information
Extending the API
You can further enhance the Lua API by adding more functions to both the Engine
and Renderer
tables. Follow the established patterns for consistency and maintainability. Ensure that each new function includes thorough argument validation and adheres to best practices outlined above.
Security Considerations
- Sandboxing: If Lua scripts are sourced from untrusted inputs, consider sandboxing the environment to prevent malicious operations.
- Resource Limits: Implement limits on script execution time and resource usage to prevent scripts from degrading application performance.
Performance Optimization
- Minimize Drawing Calls: Reduce the number of drawing calls within high-frequency loops to enhance performance.
- Batch Rendering: Where possible, batch multiple drawing operations into a single call.
- Profile Scripts: Use profiling tools to identify and optimize slow-performing scripts.