What is your preferred method of function creation?
-
I have seen some objects that run their own @startup that scans and registers functions. I assume it should be possible to create an object that scans all objects in a location, such as an auxiliary room, and registers the functions.
I would be interested to hear how others have handled it, and any lessons learned along the way. It seems like a measure of control versus duplicated work.
-
@Hexagon
I used to use an object that had all the hand-made functions and it had a startup. I primarily use Penn, and Penn keeps user-defined functions from restart to restart now, so it's superfluous. I still use it out of convenience, and paranoia of something going crazy and the functions missing.Why would you use multiple objects, out of curiousity? To me, that just creates a 'shit, where did I put the function?' thing. Not hard to find, but why spread them overm ultiple objects? And yes, it's doable, you'd just either set a startup on each object or have a startup on some object that grabs all the DBREFs you need, but them you have to mess with adding the DBREFs to the object every time.
-
@Bobotron The multiple objects usually comes when I implement other people's code. For instance, I just spawned a new TinyMUX instance from the 2.12 branch and the SGP globals weren't loaded in at startup, so I had to @startup. I have my own block of extended game functions that I tote around, which also has its own. Were I to implement something else, like @Thenomain's GMCCG code, there's a function object there that also needs to belong to the custom functions list.
So it could be a long entry under #1, it could be @startup on multiple objects, or it could potentially be an object that scans its contents. I was just curious what other people do.
-
The best way to create user-side functions in Mu* is via a controlled system. The lazy way, the easy way, is to open @function access to all wizbits, and allow each object to define their own via the @startup attribute. SGP does this, and it's fine.
The more common way is to load the #1 with a @startup that is very picky about where it looks. This is only a little safer because anyone with a wizbit can add to the object and hit @restart anyway, and comes with the added drawback that you may have to call code on a different object without the function residing on that object.
My own "secure" (imply the "???" after that) method is to give a the "@startup on #1" system a list of wizard character dbrefs who are allowed to have objects with functions on them, then scan all their objects for attributes to run with @function. You can make an attribute God Only (#1) if you want to limit who's allowed to own objects that can build user-defined functions, but because there's @chown even that is limited.
You could specifically list the dbrefs/attr on #1 on an attribute that's locked God-Only, then run it via the method mentioned in paragraph two, above. This seems like the only idea that would be secure.
On the whole, expecting True Security out of Mu* is a bit of a mug's game, so pick your favorite method, or methods. I tend to take Mu* code as "you care to hack my pretendy funtime game because ... why?", knowing that I can patch most holes. I've used all but the last idea, which I just came up with now because I wasn't happy if I didn't come up with a true secure option.
-
@Thenomain What method was your intended case for Stat Functions Prototype in GMCCG? That was what prompted me to wonder. I had SGP, my own Extended Global Functions, and then your global functions. The #1 case seems like a good one to do after the initial implementation of the core systems.
-
@Hexagon said in What is your preferred method of function creation?:
@Thenomain What method was your intended case for Stat Functions Prototype in GMCCG?
The SGP method of putting all functions on a single object. I am not convinced that was a good idea.
-
@Hexagon said in What is your preferred method of function creation?:
I have seen some objects that run their own @startup that scans and registers functions. I assume it should be possible to create an object that scans all objects in a location, such as an auxiliary room, and registers the functions.
I would be interested to hear how others have handled it, and any lessons learned along the way. It seems like a measure of control versus duplicated work.
I would say it depends on the codebase.
Penn's a bit harder for organization of where objects, attributes, functions, etc are.
MUX and Rhost are a bit easier to identify where they are with @function/list.
For my own use I tend to use an object with a single @startup that parses attributes based on prefix if it's /priv, /pres, /local, etc and sets up the user function table on startup.
Rhost also has a way for normal users to define functions on the fly themselves that are sandboxed to them and their own belongings via @lfunction.
So it depends greatly on the codebase that is being used.
-
@Ashen-Shugar Penn has a function list too showing the DB# and MU* function for all of the global functions.
APPEND 16 FUN_APPEND
My code attempts to be modular, so I use separate Command/Function/Data objects for each softcode system. The function object's @startup will register any of its functions it wants to make global.
@startup FS3 Skill Functions=@function roll_ability=me/fun_roll_ability
-
@Ashen-Shugar Thanks for the input. I want to try an Rhost instance at some point. I seem to recall it handles multi word names well. I was concerned with that at one point, but my interests wander everywhere as I'm not yet completely jaded by being a psychocoder.
-
@faraday I think I prefer this approach, having different blocks of drop-in code register their own functions, but it might be good to look at the function list at the end and then tell #1 to register the functions on just those objects once the initial setup is complete.
-
@Hexagon
Multi-word names aren't typically a difficult thing, unless your code doesn't use pmatch() to verify. Or at least in my experience. -
@Bobotron What concerned me at the time was seeing a John, Johnathan, Jonathan, and Jon all on the same game. Last names give us a chance to differentiate ourselves. I've had problems with internal functions like page, and softcode like +finger, when using them with @names that contain a space. I remember thinking it would be great if they could all have a sort of &last.name and &first.name that together composed the @name, and alternately an @alias because typing the extra characters could be irritating.
-
@Hexagon said in What is your preferred method of function creation?:
@Bobotron What concerned me at the time was seeing a John, Johnathan, Jonathan, and Jon all on the same game. Last names give us a chance to differentiate ourselves. I've had problems with internal functions like page, and softcode like +finger, when using them with @names that contain a space. I remember thinking it would be great if they could all have a sort of &last.name and &first.name that together composed the @name, and alternately an @alias because typing the extra characters could be irritating.
You could potentially do something fairly cool with this, actually; while the @name itself remains whichever short variant it is (because first+last can get to look incredibly awkward in posing), something like +glance or in the room contents, which typically lists name and shortdesc, could list the &first.name &last.name variance in place of simply @name. That would be pretty dang cool, really.
-
@surreality Pretty much my thought but inverted. Show the First and Last, but +glance would give the @alias and shortdesc. I guess it doesn't really matter which is the default. Sadly, I think this probably has repercussions I'm not thinking of.
-
@Hexagon Mostly to do with paging, @mail, etc. I'd think. That could get tricky. Setting it up for display in room and other informational commands, though, is probably something that could be done pretty easily.
-
I personally create a function object for each big bit of code, because really there's not that much additional code I really need but I am a blasphemous SGP person. I then put those function objects where they get hit by the @startup of the game. Not the most secure, but, functions shouldn't run outside of those I put in place that way.
Assuming I eventually get another coder then that may change, but I am pretty frugal with Wizbits, when it's pretty unnecessary for most things since My staff commands look not only for rank but for dbref.
-
@Bobotron said in What is your preferred method of function creation?:
@Hexagon
Multi-word names aren't typically a difficult thing, unless your code doesn't use pmatch() to verify. Or at least in my experience.Yeah, this. Any code that wants a list of names, e.g. "page", is going to be more difficult to parse multi-word names, but since we have grammar tokens like quote-marks and commas, it's not hard to code for.
The only reason why The Reach/Fallcoast won't accept multi-word names is because one code system wasn't set up this way, and the only times I wasn't on burnout I couldn't remember what it was to fix it.
-
@Thenomain I've definitely seen games use it and quotation marks work. I know it's doable, I was thinking about graceful. I remembered looking at Rhost and Penn to see how they handled it.
-
@Hexagon That's assuming you want every function on that object to be global. My function objects hold both private and public functions. Only the public ones are registered via @function.
Of course you could get around that with naming conventions like FUN_x versus FUNPUB_x or something. I just find it easier to have the objects register what they need.
Side note about multi-word player names. @Thenomain hit on the main reason why I have chosen not to allow them in my codebases. It's just a PITA for the players to have to put junk in quotes or separate it with commas all the time, and double PITA to parse a quote-encapsulated list versus a space-separated one.
Having six variants of "John" on your game is going to be confusing to people whether you have John Smith/John Doe/Jon Snow or John/Johnny/Jonathan. I find enforcing single-word names to be the lesser of two evils personally. YMMV.
-
@faraday said in What is your preferred method of function creation?:
It's just a PITA for the players to have to put junk in quotes or separate it with commas all the time, and double PITA to parse a quote-encapsulated list versus a space-separated one.
Hm. Good question.
iter( %0, pmatch( %i0 ), if( strmatch( %0, \,* ), \,, %b )
I bet you could make this "lpmatch()" and use that.
Still annoying, but much more possible than parsing "...", and it only parses when the player enters it that way so it doesn't have to be "all the time".
I'm sure it's easier in Penn than Mux to do "..." parsing as well and throw that into this new lpmatch() global, but as I've not done much token-based processing I don't know just how hard it would be. I'd probably stick to the code I have above, because I'm lazy.