And without further ado, here's my plan:
Phase 1. - Re-structure current Simkin scripting implementation:
1a. - Refactor all scripted objects to utilize hashed pointers-to-members/member-functions:
Explanation:
While this would have been a tremendous performance boost over previous releases, it's likely only a minor(or non-existent) improvement over the current numeric switch hashing. It does, however, improve the readability of the scripting code, and make it slightly easier to add to it.
1b. - Removal of High-Level pawn behavior to seperate mechanism:
Explanation:
My idea here, is to remove the seperate execution levels, and provide high-level functionality through a mechanism I'm calling the ActionQueue. I know people are going to ask the ultimate question on this one, why? So...
Why:
1b-1. To reduce the confusion caused by some command being accessible from only a single level. I've seen a lot of new users ask about a command not working, and in the end it's because they called it from the wrong execution level. Personally, I believe this is partly a side-effect of intuition, since it's usually with one-frame commands that don't actually require the high-level behavior.
1b-2. Flexibility. The ActionQueue will provide support for executing low-level style orders as part of the queue, both on a per-frame basis and in-between built-in commands(in other words, as if they were a high-level command), and it'll allow the user to exit the queue to low-level operation, and then resume the queue(even multiple queues, should they desire...) where it left off.
1c. - Add support for built-in scriptable object types:
Explanation:
I mentioned this in one of my first threads upon returning to the community. The basic idea here is provide types for commonly used constructs(such as the vector), with a scripting interface. And change the commands to use them. This will help reduce the number of parameters needed for many commands, and reduce the overall number of pawn commands significantly, without sacrificing the functionality. From what I gather, the Simkin-integrated components will also provide a performance boost compared to their pawn-command counterparts. Of course, this means users will have to learn about and put the dot operator to use...
Examples:
Some examples of possible usage...
Code: Select all
Strafe[(strafe_distance, invert)
{
LOOKVECTOR = self.GetLookVector();
LOOKVECTOR.Normalize();
STRAFEVECTOR = LOOKVECTOR.Cross(Vector(0, 1, 0)); // Cross against up axis
if(invert)
{
STRAFEVECTOR.Invert();
}
STRAFEVECTOR.y = 0; // sanity check to stay on the ground
self.Move(STRAFEVECTOR * strafe_distance);
}]
Code: Select all
{
Health [100]
InDanger [false]
DangerLevel [30]
Lifebar
DangerSound
DS_Counter [0]
DS_Rate [2000]
LB_Images
{
Background
Alpha
NormalBar
DangerBar
}
Spawn[()
{
LB_Images.Background = Image.Load("HUD/lifebar.bmp");
LB_Images.Alpha = Image.Load("HUD/lifebar_a.bmp");
LB_Images.NormalBar = Image.Load("HUD/lifebar_grad.bmp").ColorBlend(0, 0, 230, 128); // blend to blue
LB_Images.DangerBar = Image.Load("HUD/lifebar_grad.bmp").ColorBlend(230, 0, 0, 128); // blend to red
Lifebar = New.HudElement(Health, 100, "vertical", LB_Images.Background, LB_Images.Alpha, LB_Images.NormalBar, 12, 12);
DangerSound = Sound.Load("danger.wav");
think = "Run";
}]
Run[()
{
if(health < DangerLevel)
{
if(not InDanger)
{
InDanger = true;
Lifebar.gradient = LB_Images.DangerBar;
DangerSound.Play();
}
else
{
if(InDanger)
{
InDanger = false;
Lifebar.gradient = LB_Images.NormalBar;
DS_Counter = 0;
}
}
if(InDanger)
{
DS_Counter = DS_Counter + (self.time - self.last_time);
if(DS_Counter > DS_Rate)
{
DangerSound.Play();
DS_Counter = DS_Counter - DS_Rate; // keep consistent timing to prevent player insanity
}
}
}]
}
1d. - Provide documentation and support.
Explanation:
Documentation is self-explanatory. As for support, since these changes will spawn a scripting system that's incompatible with the current one, I'm prepared to either moderate a forum category on-site, or host a seperate forum off-site if necessary.
Overall Status:
1a: Complete.
1b: In progress. (~55% complete)
1c: In progress. (~20% complete)
1d: To-do.
End of Phase 1 objectives.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Phase 2. - Entity management restructure:
2a. - Fix apparent(I may be wrong...) problem with geEntity in Genesis code:
Explanation:
As far I can tell, the geEntity/geEntity_Set constructs weren't intended for use during actual level execution. I'm making this inference based the fact that there is a function in the G3D API to unload them after loading a level, and the fact that the only places I can find them within Genesis itself seem to bugfixes and features added after it was released to the world at large. I believe their sole purpose was be used to acquire entity initialization data added in the editor.
Note: I could really use some insight into this issue from someone more familiar with Genesis than I.
2b. - Add support for multi-index intrusive containers for entities:
Explanation:
This is dependent upon 2a. Should that be accomplished, the next step will be to alter the managers to load the entities from levels into custom constructs, and store them in custom containers. My objective for the containers is to provide a combination of hash-table & linked-list access, allowing for entities to be both iterated through, and looked up by name, in an efficient fashion. The container mechanism itself will integrated into the entity constructs(intrusive), as this(theoretically) will reduce cache misses(and improve performance.) This should also make dynamic entity creation a cinch.
2c. - Background preloading of levels:
Explanation:
And this is somewhat dependent on 2b. Changing the entity management will facilitate providing support for thread-loading levels in the background, allowing for rapid level changes. It might even make it possible to change levels seamlessly.
2d. - Extend RFEditPro to allow for embedded initializer functions:
Explanation:
It occured to me that it would be really useful to be able to write spawn orders on a per-entity basis, from within the level editor. That way, the level designer can configure the behavior of an entity, without having to edit the script itself. So, we'll be able to add a few pawns, run them all off a single script, then add orders in the editor to change health values, weapons, etc... It also occurs to me, that it would be useful to extend this concept to ScriptPoints, to allow embedding methods into them. That would allow a pawn to call orders embedded in the script point directly. I foresee major AI functionality improvements with this feature...
End of Phase 2 Objectives.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Phase 3. - Make it all scriptable:
3a. - Provide interpreted interfaces to most entity types.
Explanation:
The groundwork for this will be laid during the release 2 development cycle, as a part of the entity management restructure(the custom entity constructs are needed to make this happen in an effective fashion.) The idea here is to allow scripted access to the public data and functions of entities, at least the ones that would benefit the most from it. This will allow the scripter to do any necessary "power-tweaking" to the internal state of the engine.
3b. - Develop or integrate a GUI toolkit:
Explanation:
This seems to me like the next logical step to take, and I feel that RF "REALLY" needs this. This will allow users to do all those fancy menus and such they're dreaming of, and expand RF into many other game genres.
3c. - Engine core script:
Explanation:
And lastly, once all the above is in place... Allow the user to write a script to manage the initialization and flow of the engine itself. Use a custom startup menu, choose what gets loaded and unloaded, and when, etc... With this final piece of the puzzle, RF should be a viable solution for the development of just about any type of game.
Note: This development phase will be very time consuming, and I'll probably make multiple releases as I make progress.
End of Phase 3 Objectives.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Positive feedback will be appreciated, constructive criticisms will be assessed... And flaming will be promptly ignored.