Jump to content
View in the app

A better way to browse. Learn more.

Horizon Community

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

This is a basic write-up of the main routines and main system functions of Horizon emulator. This is in essence the most important part of the core. Horizon was made to first just outline the basic needs of a software before it introduced different threading environments with its new design. With the new design, we introduced 5 different components of the Horizon Kernel and its architecture -

  1. The Console Module - 1 Thread only

  2. The Network Module

  3. The Script-VM Module

  4. The Game Logic Module

  5. The Persistence Module

What is Horizon System Management?

With these 5 modules, the Horizon system Kernel was designed and made to be a superior multi-threaded environment. Each of these modules divide the workload between multiple threads to provide a "load-balancing" mechanism in the system. Once the modules are loaded, they provide each other a way of communicating. Every thread in each module can send work to another thread and receive work from another thread in any of the modules. This system of providing and receiving work is called the Horizon System Management.

Horizon System Management gives rise to a new concept called the Horizon System Functions, which are basically runtime routines that are passed to the Kernel at runtime. These functions are basically the business logic of the software and those which are responsible for the synchronization and communication of threads in Horizon's System. For example -

void ZoneClientInterface::login(int account_id, int client_version, int session_id)
{
	// all account_id, client_version and session_id are passed to this function
	LoginRoutine r1 = new LoginRoutine();
	r1->set_account_id(account_id);
	r1->set_client_version(client_version);
	//...
	//...
	
	GameLogicModule()->push_routine(r1); // This line basically tells the GameLogic thread to process LoginRoutine.
		
	while (r1->no_result()) { 
		// wait for work to complete.
	};
	
	ClientLoginResponse r2 = new ClientResponse(r1->result()); // with the result of r1 we send the response to the client by queuing the work into the NetworkModule.
	NetworkModule()->push_routine(r2); // Sends the result to the client 
}

In the above code example we synchronize the main thread which executes ZoneClientInterface::login with the 2 Kernel Module threads.

  1. The work is created

  2. It is pushed to the module thread

  3. The response is received by the main thread

  4. Response is carried forward and sent to the network thread.

In these 4 steps, the main responsibility of the ZoneServer is carried out. The ZoneServer will synchronize all module threads and carry out their base system functions. These are the higher system functions which are prime and central to all other functions in Horizon. This is the basic outline of the Horizon System Management component and Horizon System Functions. This is the design and architecture regarding the system functions. Any other questions related to the details of the implementation are a different concern from what we're addressing in this topic. This is essentially the most important part of the core which deals with thread synchronization and tackles large potential issues such as - Deadlocks, Data Races and so on.

What are our concerns regarding the potential deadlocking and data-race issues?

The Horizon System Management is designed in such a way that the scope and functionality of each routine is clearly visible and kept in clear control of the programmer. It is the programmers duty to ensure that data read/writes are made within the context of the mutual exchange that is provided in each runtime routine. The runtime_synchronization_mutex is available for individual runtime routines so that any data that is passed to and from the routine class and control will be clearly visible to the programmer and kept and used for 1. The critical sections of the runtime routine and 2. the critical sections of the main thread.

What is a critical-section?

Any code that is within the boundaries and scope of a mutual exchange, from the time the lock is acquired to the time the lock is released is called the critical-section of the application.

Any data that is accessed or changed outside these boundaries are prone to data races.

What are deadlocks?

Deadlocks are when the application has two thread running and the following scenario takes place -

  1. the first thread acquires a lock

  2. The second thread waits for the lock

  3. The first thread returns to the same critical section because of some incorrect logic and waits to acquire the same lock

This can cause the system to hang and cause an infinite waiting period in the program. Beware of such kind of programming issues and make sure that these problems are considered when writing your logic.

Horizon System Functions are written with the capacity to encapsulate all the logic within a threading environment. For example,

  1. we ensure that the data is secure by providing a runtime_synchronization_mutex exclusive to the runtime routine itself, to synchronize its data with the main thread.

  2. We ensure that the lifetime of one runtime routine is limited to the scope of a main thread function and not exceeding it at any given point unless really required in which case the system will be extended to provide a mechanism for data retrieval from one routine to another.

  3. we ensure that the functionality of a routine is limited to the scope of a Kernel module and not extending it. Kernel modules define the scope and contextual usage of a runtime routine.

  4. Each routine is designed to work in only one kernel environment. For example - the PlayerCreationRoutine will be only relevant to the GameLogic Module. However, its use will be determined by the player login functionality.

  5. Each routine provides a result of its work. The result is captured in the routine itself and the work is available to be obtained by the main thread or any other thread depending on the use-case complexity.

I hope this clarifies the scope and functionality of the Horizon System Routines for any developers contributing to the project. This system is vital and very powerful in the software ecosystem that Horizon provides. Now that we've bottomed down and cleared our thoughts about what is the core functionality of the core, we're ready to move toward the support functionality and make sure that we have the intended business logic that we need for the software to function in its production environment. Although we won't be directly moving to the production phase we're merely estimating what it needs to work in the production stage.

The major part of the concept of threads and the logic of parallel processing was dealt with in this part of the software, the core of Horizon. The concept of parallelism was simplified to make sure that all possible states of the program were captured and made easy to control in the code that was written. The code is generic, easy to use and simplified.

User Feedback

Recommended Comments

There are no comments to display.

Recently Browsing 0

  • No registered users viewing this page.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.