Coroutines / Generator Functions
Displaying 1-3 of 3 total.
1
Please enter a numerical value for the importance of this sticky.
Enter 0 to unsticky.
Overkill

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.

Posted on 2006-07-20 13:23:11 (last edited on 2006-07-20 14:00:47)

janus

It'd be a lot cooler if these used existing function semantics and just had a new statement or something. Is there some particular reason there can't just be a 'yield' statement, ala python/C#?

Posted on 2006-07-22 19:21:48

Overkill

I thought about it more, and yeah, I'm probably not saving much work just by avoiding adding statements to the compiler. Heh.

Although, I'm not really sure how it'd work without iterators/enumerators being in the code, which Python and C# both seem to use... Would be relatively trivial if there were actually things besides ints and strings in VergeC. :D

Posted on 2006-07-22 19:44:31


Displaying 1-3 of 3 total.
1
 
Newest messages

Ben McGraw's lovingly crafted this website from scratch for years.
It's a lot prettier this go around because of Jon Wofford.
Verge-rpg.com is a member of the lunarnet irc network, and would like to take this opportunity to remind you that regardless how babies taste, it is wrong to eat them.