Generators are a neat way of being able to have a function returns and resumes where it left off, keeping all local variables and position in the function in tact for the next call. This makes things like AI states and animation much easier to handle, as the logic is made simpler.
I was thinking it might be possible to add such functionality into verge, with a bit of mucking around.
Here's a somewhat confusing example, but it should hopefully help explain the concept and how it could be added into Verge.
void MyGameLoop()
{
int enemy_index = 3;
// int GeneratorNew(string function) would be called
// similar to CallFunction, except for the fact that
// a handle that refers to the generator function's state
// would be returned.
int enemy_state = GeneratorNew("SlimeIdle");
// Pass an argument to the function as an initial value,
// after which it's stored in the generator pointer.
GeneratorPassInt(enemy_state, enemy_index);
// As long as the generator function isn't "done", call it.
// Pretend that I do the right thing and do the calls according
// to the timer.
while (!GeneratorDone(enemy_state) && !b3)
{
Render();
GeneratorCall(enemy_state);
ShowPage();
}
GeneratorFree(enemy_state);
}
// First argument is always the generator point,
// which can be altered by the function.
void SlimeIdle(int state, int enemy_index)
{
int idle_flag;
while(1)
{
// High chance of doing nothing, which lasts for a second.
if (Random(0, 100) < 75)
{
idle_flag = 100;
}
// If we're idling, count down until we can act again.
if (idle_flag)
{
// Returning out of the loop, sure, but this loop continues
// each time the generator is called.
return;
// This statement is reachable on the next call, and it
// counts things down.
idle_flag--;
}
else
{
// Otherwise, let's attack by changing state functions.
// Now that the generator state has changed
// functions, the generator data relating to position in
// current function and local variables will be forgotten
// and replaced.
GeneratorSet(state, "SlimeAttack");
// Pass our enemy index again.
GeneratorPassInt(state, enemy_index);
// Return, but this time, for good, like a regular function.
return;
}
}
}
void SlimeAttack(int state, int enemy_index)
{
int i;
enemy[enemy_index].frame = 0;
// There are ten frames in the animation
while (enemy[enemy_index].frame < 10)
{
enemy[enemy_index].frame++;
// Each frame lasts thirty ticks.
for (i = 0; i < 10; i++)
{
// If the touch the player, the player's in for some pain.
if (PlayerTouchesEnemy(enemy_index))
{
HurtPlayer();
}
return;
}
}
// Back to idling.
GeneratorSet(state, "SlimeIdle");
// Pass our enemy index again.
GeneratorPassInt(state, enemy_index);
}
So what do you people think? I know my example sucked, but I think the idea of state machines for AI made easy is sexy.