Skip to content

Commit df3507f

Browse files
committed
feat: add support for splat routes in documentation and add Luau SDK documentation with configuration, events, and records sections.
1 parent 45e7978 commit df3507f

17 files changed

Lines changed: 610 additions & 20 deletions
File renamed without changes.

src/content/docs/project-settings.mdx renamed to src/content/docs/dashboard/project-settings.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ The Project ID is a stable, read-only identifier for your project (e.g. `proj_a1
2121

2222
## API Keys
2323

24-
The Settings page links directly to the [API Keys page](/docs/api-keys) where you can view, add, and revoke individual keys.
24+
The Settings page links directly to the [API Keys page](/docs/getting-started/api-keys) where you can view, add, and revoke individual keys.
2525

2626
<Callout type="info" title="Revoking all keys">
2727
The Danger Zone also has a **Revoke All API Keys** action. This deletes every existing key and immediately creates a fresh `Default` key. Any game server using an old key loses access instantly — update your Roblox Secret before revoking.
File renamed without changes.

src/content/docs/api-keys.mdx renamed to src/content/docs/getting-started/api-keys.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,5 +89,5 @@ Plain strings are readable by anyone with file access to your published place. S
8989

9090
## Next steps
9191

92-
- [Events overview](/docs/events) — start tracking what's happening in your game.
93-
- [Records overview](/docs/records) — read and write structured data from the server.
92+
- [Events overview](/docs/events/overview) — start tracking what's happening in your game.
93+
- [Records overview](/docs/records/overview) — read and write structured data from the server.
File renamed without changes.

src/content/docs/quick-start.mdx renamed to src/content/docs/getting-started/quick-start.mdx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ StackFox.init({
4040
})
4141
```
4242

43-
Add your API key as a Secret in **Game Settings → Security → Secrets** with the key `STACKFOX_API_KEY`. See [API Keys & Secrets](/docs/api-keys) for the full setup, including using a separate key for Studio vs production.
43+
Add your API key as a Secret in **Game Settings → Security → Secrets** with the key `STACKFOX_API_KEY`. See [API Keys & Secrets](/docs/getting-started/api-keys) for the full setup, including using a separate key for Studio vs production.
4444

4545
<Callout type="warning" title="Keep your key server-side">
4646
Never initialize StackFox in a LocalScript. Your API key must stay on the server.
@@ -93,5 +93,5 @@ Records are accessible over the REST API too. Any external system with your API
9393

9494
## Next steps
9595

96-
- [Events overview](/docs/events) — learn what you can track and how events are structured.
97-
- [Records overview](/docs/records) — understand collections, keys, and external access.
96+
- [Events overview](/docs/events/overview) — learn what you can track and how events are structured.
97+
- [Records overview](/docs/records/overview) — understand collections, keys, and external access.
File renamed without changes.
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
---
2+
title: Configuration
3+
description: All options available when initializing the Luau SDK.
4+
section: Luau SDK
5+
order: 2
6+
---
7+
8+
`StackFox.init()` accepts a single config table. Only `apiKey` is required.
9+
10+
```lua
11+
StackFox.init({
12+
apiKey = HttpService:GetSecret("STACKFOX_API_KEY"),
13+
baseUrl = "https://api.stackfox.dev", -- optional
14+
})
15+
```
16+
17+
## Options
18+
19+
| Option | Type | Required | Default | Description |
20+
|---|---|---|---|---|
21+
| `apiKey` | `string \| Secret` | Yes || Your project's API key. Prefer `HttpService:GetSecret()` in production. |
22+
| `baseUrl` | `string` | No | `"https://api.stackfox.dev"` | Override the API base URL (e.g. for a self-hosted instance). |
23+
24+
## Using Roblox Secrets
25+
26+
Pass a `Secret` from `HttpService:GetSecret()` instead of a plain string. Roblox secrets are never exposed in memory dumps or Studio output, making them safer for production use.
27+
28+
```lua
29+
-- Preferred: uses a Roblox Secret
30+
StackFox.init({
31+
apiKey = HttpService:GetSecret("STACKFOX_API_KEY"),
32+
})
33+
34+
-- Acceptable during local development only
35+
StackFox.init({
36+
apiKey = "sk-live-...",
37+
})
38+
```
39+
40+
Set the secret in **Game Settings → Security → Secrets**. The string passed to `GetSecret()` is the key name, not the value.
41+
42+
<Callout type="tip" title="Separate keys for Studio vs production">
43+
Create two API keys in your StackFox project — one for Studio playtests and one for live servers. Use `HttpService:GetSecret()` with different key names to swap them via environment. See [API Keys & Secrets](/docs/getting-started/api-keys) for step-by-step instructions.
44+
</Callout>
45+
46+
## Custom base URL
47+
48+
If you're running a self-hosted StackFox instance or routing requests through a proxy, pass `baseUrl`:
49+
50+
```lua
51+
StackFox.init({
52+
apiKey = HttpService:GetSecret("STACKFOX_API_KEY"),
53+
baseUrl = "https://api.your-instance.example.com",
54+
})
55+
```
56+
57+
Trailing slashes are stripped automatically. All SDK requests are relative to this URL.
58+
59+
## Return value
60+
61+
`StackFox.init()` returns the `StackFox` module itself so you can chain calls if needed, but this is optional:
62+
63+
```lua
64+
-- Both are equivalent
65+
StackFox.init({ apiKey = "..." })
66+
67+
local sf = StackFox.init({ apiKey = "..." })
68+
sf.events:track("server_started", {})
69+
```
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
---
2+
title: Events
3+
description: Track game events with the StackFox Luau SDK.
4+
section: Luau SDK
5+
order: 3
6+
---
7+
8+
Events are immutable, timestamped records of things that happened in your game. Once tracked, they cannot be edited or deleted — they form an append-only log.
9+
10+
## `events:track()`
11+
12+
```lua
13+
StackFox.events:track(name, payload?)
14+
```
15+
16+
| Parameter | Type | Required | Description |
17+
|---|---|---|---|
18+
| `name` | `string` | Yes | Event name. Must be a non-empty string. Use `snake_case`. |
19+
| `payload` | `{[string]: any}?` | No | Flat key-value table of additional data. Values must be strings, numbers, or booleans. |
20+
21+
**Returns:** `EventResponse`
22+
23+
```lua
24+
type EventResponse = {
25+
id: string,
26+
event_name: string,
27+
payload_json: { [string]: any },
28+
created_at: string, -- ISO 8601 timestamp
29+
}
30+
```
31+
32+
### Example
33+
34+
```lua
35+
local result = StackFox.events:track("item_purchased", {
36+
userId = tostring(player.UserId),
37+
itemId = "sword_iron",
38+
currency = "coins",
39+
amount = 250,
40+
})
41+
42+
print(result.id) -- "evt_01j..."
43+
print(result.created_at) -- "2024-11-12T08:30:00Z"
44+
```
45+
46+
## Payload rules
47+
48+
Payload values must be **primitives**: `string`, `number`, or `boolean`. Nested tables and arrays are not supported and will cause an error or be dropped.
49+
50+
```lua
51+
-- Valid
52+
StackFox.events:track("level_up", {
53+
userId = tostring(player.UserId),
54+
newLevel = 12,
55+
firstTime = false,
56+
})
57+
58+
-- Invalid — nested table
59+
StackFox.events:track("level_up", {
60+
rewards = { "sword", "shield" }, -- not allowed
61+
})
62+
```
63+
64+
<Callout type="warning">
65+
Payload fields with unsupported types are silently dropped. Validate your payload shape before tracking if the data is important.
66+
</Callout>
67+
68+
Omitting the payload is fine — many events carry meaning just in their name:
69+
70+
```lua
71+
StackFox.events:track("server_started")
72+
StackFox.events:track("round_ended")
73+
```
74+
75+
## Naming conventions
76+
77+
Use `snake_case`. Group related events with a shared prefix:
78+
79+
```
80+
player_joined
81+
player_left
82+
player_banned
83+
84+
match_started
85+
match_ended
86+
87+
item_purchased
88+
item_equipped
89+
item_dropped
90+
91+
economy_coins_spent
92+
economy_gems_earned
93+
```
94+
95+
<Callout type="tip" title="Decide before you ship">
96+
Event names are stored as-is. A mix of `playerJoined`, `player_joined`, and `Player Joined` will show up as three separate event types in your dashboard. Pick a convention early and stick with it.
97+
</Callout>
98+
99+
## Rate limits
100+
101+
Each project allows **1,000 events per minute**. Requests that exceed the limit receive a `429` response and are retried once by the SDK (after ~200 ms). If the retry also fails, the call raises an error.
102+
103+
Avoid calling `track()` inside tight loops or on every `Heartbeat`. Batch state changes into a single event at natural transition points (e.g. on round end, not on every hit).
104+
105+
## Viewing events
106+
107+
Tracked events appear in the **Events** tab of your StackFox dashboard. You can filter by event name and inspect the full payload for each entry.
108+
109+
Events are stored in arrival order. There is no deduplication — calling `track()` twice with the same arguments creates two separate records.
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
---
2+
title: Overview
3+
description: Install and set up the StackFox Luau SDK for Roblox.
4+
section: Luau SDK
5+
order: 1
6+
---
7+
8+
The Luau SDK lets your Roblox game send events and read/write records through StackFox — all from a server-side Script with no extra dependencies.
9+
10+
## Requirements
11+
12+
- Roblox Studio with **HTTP requests enabled** (Game Settings → Security → Allow HTTP Requests)
13+
- A StackFox project with an API key ([create one here](/dashboard))
14+
15+
## Installation
16+
17+
### Via Wally
18+
19+
Add the SDK to your `wally.toml`:
20+
21+
```toml
22+
[dependencies]
23+
StackFox = "stackfox/sdk-luau@0.1.0"
24+
```
25+
26+
Run `wally install`, then sync with Rojo. The package will appear under `Packages` in your workspace.
27+
28+
### Manual
29+
30+
Download the latest `StackFox.rbxm` from the [GitHub Releases page](https://github.com/stackfox/sdk-luau/releases) and drag it into `ReplicatedStorage` in Studio.
31+
32+
Your Explorer tree should look like:
33+
34+
```
35+
ReplicatedStorage
36+
└── StackFox (ModuleScript)
37+
```
38+
39+
## Initialization
40+
41+
Call `StackFox.init()` once at the top of a **Server Script** in `ServerScriptService`. The SDK is not safe to use from a `LocalScript` — your API key must stay on the server.
42+
43+
```lua
44+
local HttpService = game:GetService("HttpService")
45+
local ReplicatedStorage = game:GetService("ReplicatedStorage")
46+
47+
local StackFox = require(ReplicatedStorage.StackFox)
48+
49+
StackFox.init({
50+
apiKey = HttpService:GetSecret("STACKFOX_API_KEY"),
51+
})
52+
```
53+
54+
Add your key in **Game Settings → Security → Secrets** with the name `STACKFOX_API_KEY`. See [API Keys & Secrets](/docs/getting-started/api-keys) for the full setup guide.
55+
56+
<Callout type="warning" title="Server-side only">
57+
Never call `StackFox.init()` or use `StackFox.events` / `StackFox.records` from a LocalScript. Your API key would be exposed to clients.
58+
</Callout>
59+
60+
`init()` returns `StackFox` so you can chain if you want, but it also mutates module state — subsequent `require()` calls in the same server context share the same initialized instance.
61+
62+
## Usage at a glance
63+
64+
```lua
65+
local StackFox = require(ReplicatedStorage.StackFox)
66+
67+
StackFox.init({ apiKey = HttpService:GetSecret("STACKFOX_API_KEY") })
68+
69+
-- Track an event
70+
StackFox.events:track("player_joined", { userId = tostring(player.UserId) })
71+
72+
-- Read a record
73+
local profile = StackFox.records:get("profiles", tostring(player.UserId))
74+
75+
-- Write a record
76+
StackFox.records:set("profiles", tostring(player.UserId), { coins = 100 })
77+
```
78+
79+
## Next steps
80+
81+
- [Configuration](/docs/sdk/luau/configuration) — all `init()` options
82+
- [Events](/docs/sdk/luau/events) — tracking events with payloads
83+
- [Records](/docs/sdk/luau/records) — reading and writing persistent data

0 commit comments

Comments
 (0)