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

Split regions into separate files #356

Closed
TokisanGames opened this issue Apr 22, 2024 · 2 comments · Fixed by #374
Closed

Split regions into separate files #356

TokisanGames opened this issue Apr 22, 2024 · 2 comments · Fixed by #374
Assignees
Labels
big terrains Issues that need to be addressed for big terrains enhancement New feature or request important High priority
Milestone

Comments

@TokisanGames
Copy link
Owner

TokisanGames commented Apr 22, 2024

Description

After discussing with my Out of the Ashes team, I'm now convinced multiple storage .res files is the way to go, one per region, with foliage transforms stored inside. Eventually we'll support region sizes other than 1024k, and more than 256 regions (16k^2), up to 2048 (45-90k), the opengl limit for texture arrays on many cards.

Separate files will allow us to get under the 1gb limit for res files (#GodotEngine currently crashes above this), finally allowing us to save 16k terrains.

But the biggest benefit is for team development. With only a 2k terrain in OOTA, we already have challenges handing off the baton to edit the terrain between me and my level and environment artists so we don't conflict on git.

I thought about making the foliage instances its own resource file so one could paint foliage independent of sculpting/texturing. But the reality is an environment artist needs to sculpt, texture, and foliate simultaneously.

It would be insanely impractical if we had a 16k terrain and several more people working on it, where one dev has the entire terrain checked out. Plus it does suck to upload the entire terrain data, when you've only been working in one small area.

There will be an automatic upgrade process for your data as there has been on every change since 0.8.

Related #77
This would fix #159


Here's how I think it should look:

  • Inspector: change visible storage variable to a directory with a select folder dialog.
  • File name format: change from userspecified.res to userspecified_00_00.res where these numbers represent vector2i region offset. With the 1024x1024 regions, region offset is basically global position / 1024. But get it from storage.get_region_offset(). There's an OpenGL max of 2048 texture layers, which tops out at 45 x 45, so 2 digits is enough.
  • Data structure: current foliage terrain_3d_storage.h
	PackedInt32Array _region_map; // 16x16 Region grid with index into region_offsets (1 based array)
* 	TypedArray<Vector2i> _region_offsets; // Array of active region coordinates

*	TypedArray<Image> _height_maps;
*	TypedArray<Image> _control_maps;
*	TypedArray<Image> _color_maps;

	// Foliage Instancer contains MultiMeshes saved to disk
	// Dictionary[region:int] -> Dictionary[mesh_id:int] -> MultiMesh
*	Dictionary _instances;

Asterisked items are currently stored in the storage file. Region map is not. region_map and region_offsets work together to define where regions are. Region IDs have no bearing on location. They are only indices into region_offsets, which has the location.

By storing the region location in the filename, upon loading its location can be inserted into region_offsets, and that index is its region number. So we no longer need to store _region_offsets in the files, as it is apparent by looking at the files and their names on disk.

We only need to store the maps and instances dictionary. Storage is currently a Resource so it can be loaded or saved directly to disk using engine functions. Instancer is an object so it cannot be saved to disk or displayed in the inspector. Instead it's an object that Terrain3D loads, then it manages data inside of Storage::_instances.

Like how Storage currently works, make a small subclass that extends Resource and only has the image maps and instancer data. However you only need one Image for each type, instead of a TypedArray. When loaded into Storage the maps can be inserted into the existing TypedArrays for minimal code change. Then Storage can be converted to an Object, like Instancer.

Like the maps, the instances dictionary will also need to be separated by region and merged on load and save. But don't worry about foliage until my PR is merged. Don't worry about upgrading users for now. First just envision starting a new user from scratch.

@TokisanGames TokisanGames added enhancement New feature or request big terrains Issues that need to be addressed for big terrains labels Apr 22, 2024
@TokisanGames TokisanGames added this to the Beta 0.9.x milestone Apr 22, 2024
@TokisanGames TokisanGames self-assigned this Apr 22, 2024
@TokisanGames TokisanGames added the important High priority label Jul 29, 2024
@TokisanGames TokisanGames self-assigned this Jul 29, 2024
@icebamboo97
Copy link

I just wanted to say I love you.❤️It's what I rely on for my 16km x 16km maps.

@TokisanGames
Copy link
Owner Author

This has been fixed in #374 and #476.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
big terrains Issues that need to be addressed for big terrains enhancement New feature or request important High priority
Projects
Status: Done
Development

Successfully merging a pull request may close this issue.

2 participants