Builtin Library
README.md
component_utils
Helpers for Luau-backed components that mirror Rust ECS components. The
Luau side declares camelCase keys on a public table; the Rust side
expects snake_case. This module centralises the (almost entirely
mechanical) name conversion and the projection of a public table down
to the reactive subset that the native side actually wants.
Exports
M.toSnake(key: string, overrides: Overrides?) -> string— convert a camelCase Luau key to its snake_case Rust counterpart. Splits on lower→upper and lower→digit transitions;overrides[key]short-circuits the rules for one-off renames liketype → body_type.M.projectKeys(public: { [string]: any }, reactive: ReactiveSet, overrides: Overrides?) -> { [string]: any }— build a snake_case-keyed payload by reading everyreactivekey offpublicand renaming viatoSnake. Keys outsidereactiveare skipped.
Types:
Overrides = { [string]: string }— Luau-key → explicit Rust-key map.ReactiveSet = { [string]: any }— used as a set; only the keys matter.
Usage
local CU = require("@builtin::modules.component_utils")
CU.toSnake("angularDamping") -- "angular_damping"
CU.toSnake("colorR") -- "color_r"
CU.toSnake("layerUI") -- "layer_ui"
CU.toSnake("is2D") -- "is_2d"
CU.toSnake("type", { type = "body_type" }) -- "body_type"
local data = CU.projectKeys(public, REACTIVE, { type = "body_type" })
__native.insert(data)
Notes
- Pure functions; no engine state. Safe to call from any context.
projectKeysreturns a fresh table on every call. Mutate the result freely (e.g. apply per-component value transforms likedata.body_type = capitalize(public.type)).- Consecutive uppercase letters are treated as one word
(
layerUI → layer_UI → layer_ui,parseURL → parse_URL → parse_url). This matches the Rust snake_case convention for identifier-embedded acronyms.