X
Xatio
Guest
GM Version: 2.1.5
Target Platform: All
Download: https://app.box.com/s/l37dzzftkku9ob0iqg0rhe17ox3oxnar
Links: N/A
Summary:
We're going to implement the basis of a service based game engine/system.
Tutorial:
First, I'd like to define what I mean by a service. A service is some part or function of your game that can be thought of as it's own thing. Some examples are User Settings, Physics, or even Rendering.
When we separate parts of the game this way, a few great things happen:
Next we're going to create a separate room at the top of our room list called eRoom and place eEngine in it.(We place it at the top to ensure that it always runs first).
The Engine (eEngine)
That's a fair amount of code, let's walk through what's happening.
The Service (eService):
That's also a lot of code, but fortunately that's all of it! Let's walk through this one too:
In the case of a physics service, it is here that you would call the update event on all of your physics objects. A nice bonus is that if you ever want to disable physics, you only need to go to one place: the service.
Target Platform: All
Download: https://app.box.com/s/l37dzzftkku9ob0iqg0rhe17ox3oxnar
Links: N/A
Summary:
We're going to implement the basis of a service based game engine/system.
Tutorial:
First, I'd like to define what I mean by a service. A service is some part or function of your game that can be thought of as it's own thing. Some examples are User Settings, Physics, or even Rendering.
When we separate parts of the game this way, a few great things happen:
- Debugging becomes a lot easier (bugs are always isolated to that specific service)
- Services are easy to import into new projects
- We have more control over updates (more on this shortly)
Next we're going to create a separate room at the top of our room list called eRoom and place eEngine in it.(We place it at the top to ensure that it always runs first).
The Engine (eEngine)
Code:
// eEngine Create Event
#region Define Properties
// Time passed since the last step
global.deltaTime = 0;
// List of active services
global.serviceList = ds_list_create();
global.serviceCount = 0;
// List of services to be added at runtime
coreServices = [eService];
#endregion
#region Create Core Services
var i;
var inst;
var sCount = array_length_1d(coreServices);
for (i=0; i<sCount; i++) {
inst = instance_create_depth(0, 0, 0, coreServices[i]);
inst.persistent = true;
}
#endregion
Code:
// eEngine Step Event
global.deltaTime = delta_time;
var i;
for (i=0; i<global.serviceCount; i++) {
with (global.serviceList[| i]) {
event_user(0);
}
}
- We create a list of all services that currently exist
- We add all service defined in 'coreServices' (and ensure they don't disappear unless we tell them to)
- Every step we determine the time since the last step (using delta_time)
- We then tell each service to update (which is what event_user(0) will do)
The Service (eService):
Code:
eService Create Event:
#region Add To Service List
ds_list_add(global.serviceList, id);
global.serviceCount++;
#endregion
#region Define Properties
// How many updates should occur per seconds?
rate = 30;
#endregion
#region Allow Customization
// event_user(2) is where we will allow changes to the service's rate
event_user(2);
#endregion
#region Define Derivative Properties
interval = 1000000 /rate;
counter = 0;
updates = 0;
#endregion
Code:
eService Cleanup Event:
#region Remove From Service List
var pos = ds_list_find_index(global.serviceList, id);
ds_list_delete(global.serviceList, pos);
global.serviceCount--;
#endregion
Code:
eService event_user(0):
#region Catchup Counter (to real time)
counter += global.deltaTime;
updates = counter div interval;
#endregion
#region Perform Updates
var i;
for (i=0; i<updates; i++) {
event_user(1);
}
#endregion
#region Remove Completed Updates
counter %= interval;
#endregion
Code:
eService event_user(1):
show_message("This is a test message");
- When created, a service adds itself to the list of active services
- When destroyed, it removes itself from the list of active services
- The services rate (30 by default) is the number of updates per second. There are 1,000,000 ms in 1 second, so 1,000,000 / rate = the number of ms between updates
- Each update we add the time elapsed since the last step and calculate how many updates should have occurred
- We then perform those updates (the code for which would be written in event_user(1))
In the case of a physics service, it is here that you would call the update event on all of your physics objects. A nice bonus is that if you ever want to disable physics, you only need to go to one place: the service.