DivePong

Since there aren’t really any samples on how to use Dive to actually make a game, I decided to start doing that myself. For the first sample, I have started working on a very simple pong clone. You can find the repository here.

Right now all that is implemented are the components for the player to control their paddle. You can test it out by setting up the project, launching the engine, and running the command “entity_create_template Pong.Player”. Use the up and down arrow keys to control the paddle. Not much, but it’s a start. I should have the sample done pretty soon.

Update: The game is almost fully implemented. It allows you to play a basic game of pong and it keeps score. There are a few bugs with the ball movement, but it is playable.

New Dive Engine feature: game assembly

This is something I’ve wanted to implement for a while but only just got around to doing, but Dive engine now separates engine logic from game logic.

As of the most recent commit (at the time of this writing), the engine code is in a separate project from the game code. The engine still compiles to an executable, but the game code now resides inside of a dll. This is a breaking change; anything on Dive engine previously will likely not work after updating to the latest version. It should be simple to port old code over, but it is just something to keep in mind.

In other news, I have removed the old tutorials as they are now very out of date, and it would be better to either just look through the code or to wait until I get around to writing new tutorials.

Dive’s new scheduler

Just a few minutes ago, I committed some changes to Dive’s scheduler. No longer does the scheduler execute all expiring tasks willy-nilly; now it actually thinks!

Now the scheduler can delay the execution of tasks if previous tasks took up too much of the game loop. The scheduler is fed the time of the next expected frame (update call), and runs tasks until it is either out of tasks to run or it hits the next frame.

That isn’t all, though. The scheduler exhibits a few properties:

Not guaranteed to execute tasks on-time

Because the scheduler can defer execution of tasks when it runs out of time in the current frame, tasks might not always execute as soon as they expire.

Guaranteed to execute tasks after they expire

…but tasks will always execute after their expiry, never before.

Guaranteed to run at least one task per frame

There will always be at least one task that runs in a frame.

Task execution order is not guaranteed

Just because task a was scheduled before task b and they both expire at the same time, task b might execute before task a.

Tasks that were meant to expire a long time ago will be executed before tasks that just expired

To make sure a task doesn’t get held off forever, tasks are sorted by when they expired before the scheduler tries to execute them.

Testing the new scheduler

I tested out this new scheduler, and got some interesting results. Note that this test doesn’t give “real” results, because I can’t imagine anyone using this situation.

Before I wrote the new scheduling system, I used Dive’s new scripting system to write this bit of code:

alias(repeater, "timer(\"1\",\"repeater() repeater()\")")
repeater

This creates an alias (see: function) which spawns timers at 1-second intervals that in turn spawn 2 more timers and so on and so forth.

When running, the old scheduler would freeze the engine after around 25 seconds and 30,000 scheduled tasks. The new scheduler, on the other hand, doesn’t freeze the engine at all and simply slows down the execution of the tasks, such that after about 25 seconds and 69,000 tasks the engine slows down to about 10 FPS but doesn’t crash (at least until it runs completely out of memory, which I have not left it open to do).

Update: It seems the slowdown isn’t even caused directly by the scheduler, but by .net’s memory management. Sometimes it takes 30 seconds and 70,000 tasks to bring the engine to just 30 FPS, but sometimes it starts at 65,000 and gets to 10 FPS.

Interestingly enough, the TPS (“ticks per second” or number of update calls per second) is barely affected, and the engine instead sacrifices draw calls. I realized later that this due to the way that the game loop is designed. When the engine starts coming under heavy load, it drops draw calls in favor of update calls.

If you have the debug overlay open, you will notice a “FrameSkip” value that when the engine is running normally is zero but when the engine is under load will usually hit up to 5. This is the number of frames per second that are being skipped. You can set a maximum for this value (which, when hit, will force a frame to be drawn) in config/engine.ini (the default is 5).

That’s all for now!

This is a bad idea. Don’t do it.

Updated: New syntax was introduced in a recent commit. Specifically, semicolons were removed and arguments must now be specified in a C-like style (though if there are no arguments, you don’t have to use parenthesis).

While playing around with Dive’s new scripting system, I decided to do some self-multiplying timers…

alias(repeater, "timer(\"1\",\"repeater() repeater()\")")
repeater

Don’t do this. If you have the debug overlay enabled, you will watch the task count increase exponentially until the engine freezes, trying to create more and more infinitely respawning tasks.

Actually, this should show why a better scheduler is needed within Dive. Right now, the scheduler tries to execute all tasks that have expired, no matter how long it takes. Instead, it should take into account how long tasks take, order them by when they expire, and execute them until it runs out of time in the current tick (pushing off other tasks for next tick). This wouldn’t solve this specific set of commands completely, as you are still going to hit memory limitations and a backlog of expired tasks, but it should hold off the freezes for a bit longer.

Oh look! I recently pushed a commit that changes how the scheduler handles execution time! The changes I talked about in the above paragraph have been implemented!

Dive Scripting!

I have recently implemented a simple scripting system into Dive, which is similar to existing console command systems found in engines like UDK and Source, but has a few slightly more advanced features in it.

Take this for example:

set foo "Hello World!"

Here I’m using Dive’s scripting system to set a variable “foo” to “Hello World!”. Simple enough, but what if I want to use the value of foo in another command? This isn’t possible with other console command systems, but here I can do this:

echo "I want to say: " $foo

Excuse the php lookalike variables, but this allows you to embed the value of variables for more dynamic console command scripts.

One of the first uses of the new console command system involves the semi-deprecation of the StartupGameState attribute. I say semi, as the attribute won’t be removed, but it is now preferred (especially for development purposes) to edit scripts/init.ds and add the following line:

# Dive init script
changestate Dive.Game.States.Tutorials.Tutorial3.MyFirstGameState

You can change the state of the game without recompiling code! How about that? There will be plenty more features to come, such as the ability use timers from the console, an actual visual console in the game window, and more!

A few minor Dive engine updates

Been neglecting this blog a bit, but oh well. I have a few minor updates to Dive, mainly dealing with a minor bugfix and a change in how certain debug functions work.

First of all, the bugfix: I had assumed that Visual Studio defined RELEASE when building in release mode. Apparently this is not the case, and as such I have changed the use of RELEASE to !DEBUG.

Then comes the more major change. The engine can now have a DebugHandler class attached to it, which now contains all of the debug drawing code (physics debugging, the debug overlay, etc). This marks a bit of a shift in focus away from the currently monolithic Engine class. I’m trying to move more properties and methods away from it a bit while also allowing you to hook into more of its functions without explicitly changing the class (or inheriting from it).

Additionally, the DebugHandler that is being used can be specified in the engine configuration, so you can create your own to get custom debug overlays. This is nice, as the DebugHandler’s Draw function is always called after the engine’s main draw functions, guaranteeing any drawing that occurs will appear on top of everything else (as long as you draw directly to the game window and don’t use the engine’s drawing functions).

That’s all for now!