Rulesets for table-based function params#143
Conversation
| tooltip: How long this particle system should last, 0.0 means forever. | ||
| type: integer | ||
| value: 19 | ||
| value-type: float |
There was a problem hiding this comment.
yes. this is where I was hoping you'd put this data, rather than in the ruleset section
| _TABLE_RULESET_TYPE_MAP: dict[str, str] = { | ||
| "float": "number", | ||
| "integer": "number", | ||
| "vector": "vector", | ||
| "string": "string", | ||
| "key": "(string | uuid)", | ||
| "asset": "(string | uuid)", | ||
| } |
There was a problem hiding this comment.
I'll formalize this better in a future PR. I do like this structure over all the loose -semantics fields laying around
| apply_fn = ruleset_data["apply-fn"] | ||
| apply_link_fn = ruleset_data["apply-link-fn"] |
There was a problem hiding this comment.
this will definitely need improvement at some point (now, later, whatever)
apply_fn has the right signature for
- llCreateCharacter
- llParcelMediaCommandList
- llSetCameraParams
- llSetGroundTexture
- llUpdateCharacter
apply_link_fn doesn't have the right signature for any function except for llLinkParticleSystem, but it's close for these (it's missing face):
- llSetLinkGLTFOverrides
- llSetLinkMedia
- llSetPrimMediaParams
neither one has the right signature for
- llRezObjectWithParams
- llSetAgentEnvironment
- llSetEnvironment
- llCastRay
- llEvade (no params yet)
- llFindNotecardTextCount (no params yet)
- llFindNotecardTextSync (no params yet)
- llFleeFrom (no params yet)
- llGetAgentList (no params yet)
- llGetAttachListFiltered
- llGetClosestNavPoint
- llGetStaticPath
- llGiveAgentInventory
- llHTTPRequest
- llMapBeacon
- llNavigateTo
- llPatrolPoints
- llPursue
- llSetKeyframeMotion
- llSetParcelForSale
- llTransferOwnership (no params yet)
- llWanderWithin
| @@ -0,0 +1,47 @@ | |||
| // particle-params | |||
| static const FluentParamDescriptor kParticleParamsDescs[] = { | |||
| {"flags", 'i', 0}, | |||
There was a problem hiding this comment.
if both flags and booleans are given, they are ored together?
| type: '{[string]: any}?' | ||
| return-type: ParticleParams | ||
| methods: | ||
| - name: apply |
There was a problem hiding this comment.
from Harold:
Is the builder itself necessary there? What utility does it provide over an exported declared type for the dict-like table and a function that accepts tables of that shape? That's generally how similar APIs work in other Luau projects, the "builder-ness" of SPP isn't something that's really needed elsewhere.
That way serialization is easier as well, since you don't need to preserve the type
I don't know if a fluent wrapper is really what we want / need here. Just declaring an expected table shape and a function that consumes it should be fine, since that's really all the builder does
There was a problem hiding this comment.
yeah. that's true. most lua api's would be like
llprim.particleSystem{
emissive = true,
target_linear = true,
pattern = PSYS_SRC_PATTERN_EXPLODE,
start_color = vector(0, 0, 1),
src_max_age = 10,
burst_rate = 0.1,
burst_count = 10,
target_key = ll.GetOwner()
}"just a function" would work better for most of the param-dict wrappers: #143 (comment)
There was a problem hiding this comment.
I'm unsure whether those functions should look like 1.
function llprim.setMedia(link: number, face: number, params: {})to match the lsl function, or like 2.
function llprim.setMedia(params: {}, link: number?, face: number?)so the link/face can be optional (defaulting to LINK_THIS and ALL_SIDES, or
3. mix the two and make a mess like table.insert does:
llprim.setMedia: ((link: number, face: number, params: {}) -> ())
& ((face: number, params: {}) -> ())
& ((params: {}) -> ())or, 4. just add link number/face number as optional dict params, and leave positional params out of it entirely
There was a problem hiding this comment.
oh. the dict parameter should be optional too, and work the same as an empty list. Most of the param-dict functions make sense with an empty param list
There was a problem hiding this comment.
nil and an empty table should both behave like an empty list.
| body = "\n".join(desc_lines) | ||
| section = ( | ||
| f"// {ruleset_name}\n" | ||
| f"static const FluentParamDescriptor {array_name}[] = {{\n{body}\n}};\n" |
There was a problem hiding this comment.
Is it still true that the bulk of the code to generate the builder lives in lsl-definitions, and slua/tools/gen_primparams_methods.py calls that code and then converts it to c struct format? just thinking ahead to what changing the structure of rulesets in the yaml file would actually look like given that it's growing in capability
There was a problem hiding this comment.
from Rider:
I believe that yes, gen_primparams_methods is called out of the slua repo.
I'm not entirely happy with that design since it means that slua needs to match the simulator.
That implies that ANY change to lsl_definitions requires a recompile on the VM as well.
(spelling correction to a tooltip? new VM)
There was a problem hiding this comment.
I got the idea somewhere in my mind that there was an intermediate json file that gen_all_definitions wrote and that gen_primparams_methods read, but, I can't find anything like that in reality
would probably be better if that was reality, so that slua only needed the lsl-definitions build, not lsl-definitions itself
but, I can understand why it isn't that way right now. PrimParams isn't even in beta yet, unless I missed it
There was a problem hiding this comment.
from Rider:
It has to do with autobuild and version numbers. build lsl_definitions and the version goes up. Update the simulator and the version no longer matches the one use to build the VM and autobuild screams about version mismatches.
There was a problem hiding this comment.
from Harold:
prior feedback RE the codegen for those wrappers being in slua proper so particles can be mocked / re-implemented for local dev / testing as with the SPP wrapper. There's not really a better place to put them other than slua that keeps the local dev story sane. Ideally people should only have to re-implement the very low-level implementation details of the thing that our wrappers wrap (ll.ParticleSystem here, since that's the thing that does the work) so things like do local simulation a la LSLForge can work correctly without a ton of work on their part.
| value: '0x400' | ||
| PSYS_PART_START_ALPHA: | ||
| member-of: [ParticleParam] | ||
| pretty-name: alpha_begin |
There was a problem hiding this comment.
nice. I like pretty-name better than method-name used in rulesets
c674662 to
0aadd71
Compare
There was a problem hiding this comment.
Pull request overview
Adds “table rulesets” to generate typed SLua/Luau table-param interfaces (and corresponding fluent serialization descriptors) for structured list-based LSL APIs, with initial coverage for particles, prim media, and HTTP requests.
Changes:
- Introduces
builder-rulesetsoftype: tableplusvalue-type/pretty-namemetadata to derive stable, typed table keys from enum-member constants. - Extends SLua/Luau generation to emit
ParticleParams,MediaParams, andHttpRequestParamstypes and new SLua module/functions (llhttp.request,llprim.particleSystem,llprim.setMedia). - Adds a new generator for C++ fluent descriptor arrays + dispatch wrappers, and updates Mono C# generation to escape reserved keywords.
Reviewed changes
Copilot reviewed 8 out of 19 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| slua_definitions.yaml | Adds exported table-param type aliases and new SLua module/function signatures. |
| lsl_definitions/slua.py | Adds table-ruleset type mapping and generation of typed table aliases/properties from rulesets. |
| lsl_definitions/rulesets.py | Generalizes ruleset expansion and adds table-ruleset expansion helpers + semantic mapping. |
| lsl_definitions/lsl.py | Extends constant model with value_type / pretty_name and adjusts ruleset validation for table rulesets. |
| lsl_definitions/generators/lscript.py | Adds C# keyword escaping and generates fluent builder descriptor C++ fragments for table rulesets. |
| lsl_definitions.yaml | Updates enums/constants with value-type/pretty-name and declares the new table rulesets (http/particles/media). |
| lsl_definitions.schema.json | Extends schema to support both builder and table rulesets and new constant metadata fields. |
| generated/templated/LslLibrary.cs | Regenerates Mono bindings with escaped identifiers (e.g., @params). |
| generated/syntax/slua.tmLanguage.json | Regenerates syntax highlighting to include new modules/functions/types. |
| generated/syntax/slua.tmLanguage | Regenerates syntax highlighting to include new modules/functions/types. |
| generated/secondlife.docs.json | Regenerates docs to include new llhttp and new llprim functions and updated constant docs. |
| generated/secondlife.d.luau | Regenerates Luau definitions with the new exported param-table types and function signatures. |
| generated/secondlife_selene.yml | Regenerates Selene std definitions with new functions and updated constant descriptions. |
| generated/lua_keywords_pretty.xml | Regenerates viewer keyword/tooltip output with new types/functions and updated tooltips. |
| generated/lsl_keywords_pretty.xml | Regenerates viewer keyword/tooltip output with updated constant tooltips. |
| generated/experimental/enums.txt | Regenerates experimental enum listing (incl. ParticleSourcePattern as enum). |
| generated/cpp/fluent_builder_descriptors.cpp | Adds generated fluent param/flag descriptors and wrapper registrations for the new table rulesets. |
| gen_all_definitions.sh | Updates generator invocation to prefer python3 when available. |
| .gitignore | Ignores *.code-workspace files. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
| type LLJsonDecodeOptions = LLJsonDecodeOptionsWithoutPath | LLJsonDecodeOptionsWithPath | ||
| export type ParticleParams = { | ||
| flags: number?, | ||
| color_begin: vector?, |
There was a problem hiding this comment.
reckon it's possible to document the defaults some of these values have?
There was a problem hiding this comment.
@Suzanna-Linn Has a PR with an RFC proposing that: #160
Generates a lua interface for functions requiring structured lists of parameters with an initial implementation for
llprim.particleSystem,llprim.setMedia, andllhttp.requestI selected each of those three because each had a subtly different catch.
related PRs:
secondlife/slua#86
https://github.com/secondlife/server/pull/2574
setMediaends up looking like this:http request: