Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

World streaming #90

Open
gecko0307 opened this issue Sep 17, 2023 · 0 comments
Open

World streaming #90

gecko0307 opened this issue Sep 17, 2023 · 0 comments
Assignees
Milestone

Comments

@gecko0307
Copy link
Owner

gecko0307 commented Sep 17, 2023

A system that allows the game to load and unload fixed-sized parts of the map as the player travels through the game world.

The system assumes that the player travels predominantly on a planar surface, such as a land. The world is divided into a 2D grid with a predefined cell size (for example, 100x100 meters). Each cell is loaded as an independent asset. By default, the game only loads the home cell (where the player is at the start of the game) and its 8 neighboring cells. The player can see one adjacent cell at each direction. If the player moves to an adjacent cell, the game loads new "visible" neighboring cells and unloads "unvisible" ones. Loading is done at the background using thread-safe functions.

Core concepts

  • WorldCell. An abstract class, a container for user-defined cell-specific data. For example, a WorldCell implementation can store assets and entitites, include their initilization code, physics code, sound code, and some game-specific logic. Typically the world will be built from cells of the same type (but with different data), but this is not necessary, some cells may require special initialization code.
  • WorldMap. A class that defines cell positions. It stores a mapping of grid coordinates to CellSource objects.
  • CellSource is used to abstractize the way cells are loaded. It is an interface with "load" and "release" methods that take WorldCell object as a parameter. How the cell source is constructed is completely up to the implementation. A typical scenario is to initialize CellSource from a certain filename.
  • WorldStreamer class manages cells using a WorldMap. It loads cells using cell sources from the map based on the Traveller object's location. It also determines which cells are to be rendered by the graphics engine at certain worldspace positions.
  • Traveller is a proxy for the player-controlled character that moves through the world. It stores player's position as two vectors: cell coordinates (integer x, y) + offset vector (floating point x, y relative to the cell origin). When player crosses a border between cells, map coordinates are updated accordingly, and offset vector is wrapped, so that the traveller can only move in a fixed portion of space - for example in -50..50 meters range. The map geometry is always rendered at the worldspace origin (0, 0). This allows to keep coordinate precision consistent while maintaining an illusion of large travel distances.

How this system should be integrated into existing API

In its current state Dagon renders Scene objects that store entities using World class. The level streaming system can seamlessly fit its workflow to Dagon's renderer by using a drop-in World replacement, StreamedWorld. This class will provide a different entity list based on the currently visible cells.

It should also store an array of global entities that are permanently present in the scene, as usual. For example, a character object and a camera are both persistent entities. The character's position will be used to update the Traveller state. When Traveller enters a new cell, it must broadcast a wrap event, which will be used in the scene to update the character's position. This way, the game logic will be continuous throughout the streamed world.

@gecko0307 gecko0307 added this to the Dagon 1.0.0 milestone Sep 17, 2023
@gecko0307 gecko0307 self-assigned this Sep 17, 2023
@gecko0307 gecko0307 changed the title Level streaming World streaming Jan 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant