There's some code in there that may be of use to you.
Like you, I initially just wanted to read some function names as strings from a table. But eventually ended up using the same macros to enable code changes at runtime.
Just beware of the law of unintended consequences. :)
My antique DikuMUD used several different fixed tables for lookups, which nearly identical code to access each. At one point, decades ago, I decided to optimize things a bit by merging all of this into one table, sorted alphabetically, so I could use a binary tree lookup to get from command name -> function name, and thus to function pointer.
Boy, were players surprised when 'k bob' suddenly started kissing bob instead of killing him!
(Because, of course, even though kill comes first in the list, the first k prefix the binary search happened to hit was kiss)
The moral of the story is, the more you automate things for simplicity and easy of maintenance, the less full control you have over them, unless you're careful. :)
Just beware of the law of unintended consequences. :)
My antique DikuMUD used several different fixed tables for lookups, which nearly identical code to access each. At one point, decades ago, I decided to optimize things a bit by merging all of this into one table, sorted alphabetically, so I could use a binary tree lookup to get from command name -> function name, and thus to function pointer.
Boy, were players surprised when 'k bob' suddenly started kissing bob instead of killing him!
(Because, of course, even though kill comes first in the list, the first k prefix the binary search happened to hit was kiss)
The moral of the story is, the more you automate things for simplicity and easy of maintenance, the less full control you have over them, unless you're careful. :)
I decided to optimize things a bit by merging all of this into one table, sorted alphabetically…
Boy, were players surprised when 'k bob' suddenly started kissing bob instead of killing him! …
The moral of the story is, the more you automate things for simplicity and easy of maintenance, the less full control you have over them, unless you're careful. :)
It's a good moral, but I don't think the story quite fits it. You removed part of the logic, which is why you got different behavior. You didn't have any less control after vs. before.
Generally, being able to store references to methods in a database / table paves the road to simplicity and ease of maintenance w/o losing control. If you do it properly, you would even be gaining control. You could for example un-publish commands until fixed, change what a skill does, etc. All kinds of things become easier and safer to do if all you have to do is modify a database field without touching the code itself.
Just beware of the law of unintended consequences. :)
My antique DikuMUD used several different fixed tables for lookups, which nearly identical code to access each. At one point, decades ago, I decided to optimize things a bit by merging all of this into one table, sorted alphabetically, so I could use a binary tree lookup to get from command name -> function name, and thus to function pointer.
Boy, were players surprised when 'k bob' suddenly started kissing bob instead of killing him!
(Because, of course, even though kill comes first in the list, the first k prefix the binary search happened to hit was kiss)
The moral of the story is, the more you automate things for simplicity and easy of maintenance, the less full control you have over them, unless you're careful. :)
I think this is a great example of why muds could benefit greatly from test driven development. If there were a unit test around each of the commands you'd expect a player to be able to input you'd instantly know when something breaks "k bob"
I think this is a great example of why muds could benefit greatly from test driven development. If there were a unit test around each of the commands you'd expect a player to be able to input you'd instantly know when something breaks "k bob"
Or, you could just throw some good old human resources at the problem and have a handy little sweatshop somewhere in Bangalore do all your command regression testing for ya!
Alter Aeon has automated regression testing for a bunch of the core libraries, but to do it on the per-command level would be a lot more time and effort than is reasonable given the type of project.
What are some of the better options these days, in C or C++, for avoiding hundreds/thousands of lines of "tables" for commands, skills, etc.?