Documentation
¶
Overview ¶
Package pile provides a compact single-file world provider for dragonfly built on the pile v2 format.
Index ¶
- Constants
- Variables
- func DimPath(dir string, dim world.Dimension) string
- func ExportMCDB(src, dst string, opts ...Option) (int, error)
- func FileMode(path string) (uint8, error)
- func ImportMCDB(src, dst string, opts ...Option) (int, error)
- func IsMCDB(dir string) bool
- func IsPile(dir string) bool
- func MCDBBlockStates(dir string) ([]format.BlockState, error)
- func RegisterBlockState(reg world.BlockRegistry, s format.BlockState) (bool, error)
- func RegisterMCDBStates(dir string, reg world.BlockRegistry) (int, error)
- func WorldBlockStates(dir string, opts ...format.ReadOption) ([]format.BlockState, error)
- func WorldBounds(p *Provider, dim world.Dimension) (lo, hi cube.Pos, ok bool)
- type Builder
- func (b *Builder) AddBlockEntity(pos cube.Pos, data map[string]any)
- func (b *Builder) AddEntity(data map[string]any)
- func (b *Builder) Fill(lo, hi cube.Pos, bl world.Block)
- func (b *Builder) FillBiome(lo, hi cube.Pos, bio world.Biome)
- func (b *Builder) Provider(opts ...Option) *Provider
- func (b *Builder) Save(dir string, opts ...Option) error
- func (b *Builder) SetBlock(pos cube.Pos, bl world.Block)
- func (b *Builder) SetUserData(data []byte)
- func (b *Builder) Settings(s *world.Settings)
- type DimFile
- type MoveOptions
- type MoveReport
- type Option
- func AppendMode() Option
- func CacheColumns(n int) Option
- func Compression(level format.CompressionLevel) Option
- func FastSaves() Option
- func FilterBlockEntity(f func(chunk.BlockEntity) bool) Option
- func FilterColumn(f func(world.ChunkPos, world.Dimension) bool) Option
- func FilterEntity(f func(chunk.Entity) bool) Option
- func LoadSkip(m SkipMask) Option
- func MaxDecodedBytes(n int64) Option
- func ReadOnly() Option
- func Registry(reg world.BlockRegistry) Option
- func Skip(m SkipMask) Option
- func StoreLight() Option
- func WithSpawnStore(s SpawnStore) Option
- type Provider
- func (p *Provider) AutoSave(interval time.Duration) (stop func())
- func (p *Provider) ChunkCount(dim world.Dimension) int
- func (p *Provider) ChunkUserData(pos world.ChunkPos, dim world.Dimension) []byte
- func (p *Provider) Close() error
- func (p *Provider) Columns(dim world.Dimension) iter.Seq2[world.ChunkPos, *chunk.Column]
- func (p *Provider) DeleteSnapshot(name string) error
- func (p *Provider) Dir() string
- func (p *Provider) IsReadOnly() bool
- func (p *Provider) IterError() error
- func (p *Provider) LoadColumn(pos world.ChunkPos, dim world.Dimension) (*chunk.Column, error)
- func (p *Provider) LoadPlayerSpawnPosition(id uuid.UUID) (cube.Pos, bool, error)
- func (p *Provider) Rollback(name string) error
- func (p *Provider) Save() error
- func (p *Provider) SaveAs(dir string) error
- func (p *Provider) SaveAsync()
- func (p *Provider) SavePlayerSpawnPosition(id uuid.UUID, pos cube.Pos) error
- func (p *Provider) SaveSettings(s *world.Settings)
- func (p *Provider) SetChunkUserData(pos world.ChunkPos, dim world.Dimension, b []byte) error
- func (p *Provider) SetUserData(b []byte)
- func (p *Provider) Settings() *world.Settings
- func (p *Provider) Snapshot(name string) error
- func (p *Provider) Snapshots() ([]string, error)
- func (p *Provider) StoreColumn(pos world.ChunkPos, dim world.Dimension, col *chunk.Column) error
- func (p *Provider) UserData() []byte
- type SkipMask
- type SpawnStore
- type Structure
- func (s *Structure) At(x, y, z int, _ func(x, y, z int) world.Block) (world.Block, world.Liquid)
- func (s *Structure) Data() *format.StructureData
- func (s *Structure) Dimensions() [3]int
- func (s *Structure) PasteInto(p *Provider, dim world.Dimension, at cube.Pos) error
- func (s *Structure) Rotate(quarters int) *Structure
- func (s *Structure) Save(path string) error
- type StructureLibrary
- type StructureOption
- type Template
- type WorldFiles
Constants ¶
const ( CompressionNone = format.CompressionNone CompressionFast = format.CompressionFast CompressionDefault = format.CompressionDefault CompressionBest = format.CompressionBest )
Compression levels, re-exported from the format package.
Variables ¶
var ( // ErrNotFound reports that no column is stored at a position. LoadColumn // returns it, under the name world.Provider's contract requires: it is // dragonfly's leveldb.ErrNotFound, and every provider signals a missing // chunk with it whatever it is backed by. ErrNotFound = leveldb.ErrNotFound // ErrCorrupt reports that a file is not a valid pile file. Every decode // failure wraps it except ErrDecodeBudget, which is the point of the two // being separate. ErrCorrupt = format.ErrCorrupt // ErrDecodeBudget reports that a decode was stopped by the ceiling set // with MaxDecodedBytes. It deliberately does not wrap ErrCorrupt: the file // is larger than this provider was told to decode, not broken, and a // caller that quarantines corrupt worlds must not quarantine this one. ErrDecodeBudget = format.ErrDecodeBudget )
The errors a caller branches on, re-exported so that branching on them does not mean importing the codec and dragonfly's leveldb package alongside this one. They are the same values, so errors.Is against either name works.
var ErrReadOnly = errors.New("pile: provider is read-only")
ErrReadOnly is returned by the mutating operations that can report an error at all — Save, SetChunkUserData, Snapshot, DeleteSnapshot and Rollback — when the provider was opened with ReadOnly. The mutators with no error to return (StoreColumn, SaveSettings, SetUserData) are silent no-ops instead, as ReadOnly's own documentation says; IsReadOnly is how a caller tells the two situations apart before it relies on a write.
var ErrUnmovableUserData = errors.New("pile: world carries user data, which pile cannot translate")
ErrUnmovableUserData is returned by MoveWorld when the world carries application metadata and MoveOptions.KeepUserData is false.
User data is opaque to pile: whatever coordinates it holds -- spawn points, regions, NPC positions -- cannot be found, let alone translated. Moving the blocks and leaving them behind is a silent failure, and the coordinates go on resolving to whatever now occupies their old positions, so it is one that surfaces long after the move as a map that is subtly wrong rather than as an error. The move refuses instead, and KeepUserData is how a caller says it will re-anchor the data itself.
var ErrWouldClip = errors.New("pile: move would clip content outside the world's vertical range")
ErrWouldClip is returned by MoveWorld when the offset would push content outside the dimension's vertical range and MoveOptions.Clip is false.
Functions ¶
func DimPath ¶ added in v0.2.0
DimPath returns the file path of a dimension inside a world directory: overworld.pile, nether.pile, end.pile (dim<id>.pile for custom dimensions).
func ExportMCDB ¶ added in v0.2.0
ExportMCDB converts a pile world into a freshly created leveldb world and returns the number of columns converted.
dst must not already hold an mcdb world, so the result contains only live keys rather than whatever was there plus this world on top.
Options are the provider options the *source* is opened with. A caller converting a world it did not write should pass MaxDecodedBytes: this walks every column of every dimension, so it is exactly the operation a hostile file makes expensive.
func FileMode ¶ added in v0.2.0
FileMode reads the mode byte of a pile file header: format.ModeSolid or format.ModeIndexed.
func ImportMCDB ¶ added in v0.2.0
ImportMCDB converts a dragonfly leveldb world into a fresh pile world and returns the number of columns converted.
The output is garbage-free by construction: only live columns are visited, and a pile save is a canonical full rewrite, so the result is byte-identical to any other conversion of the same content. That is the property worth converting for -- an mcdb world accumulates dead keys that a copy preserves.
dst must not already hold a pile world. Refusing rather than merging is deliberate: a conversion into an existing world would mix two worlds' columns and leave no way to tell which came from where.
Options are the provider options the destination is opened with, so a caller can choose compression, append mode or a block registry. Reading the source takes none: it is a leveldb world and its cost is bounded by its own files.
func MCDBBlockStates ¶ added in v0.2.1
func MCDBBlockStates(dir string) ([]format.BlockState, error)
MCDBBlockStates returns every distinct block state stored in a Bedrock world, read straight from the sub-chunk palettes.
No registry is involved and none is needed: a palette entry carries the identifier and the properties, which is the whole of a state. That is what makes this usable on a world holding blocks from a behaviour pack, where resolving anything against a vanilla registry is exactly what fails.
The database is opened READ-ONLY. goleveldb's default is read-write and rewrites the manifest and journal on open even when nothing is stored, which is a change to somebody's world that reading it must not make.
func RegisterBlockState ¶ added in v0.2.1
func RegisterBlockState(reg world.BlockRegistry, s format.BlockState) (bool, error)
RegisterBlockState registers a state on reg unless it is already there, and reports whether it added one. It is RegisterMCDBStates for a caller that got its states from somewhere else -- a pile world's own palette, say.
func RegisterMCDBStates ¶ added in v0.2.1
func RegisterMCDBStates(dir string, reg world.BlockRegistry) (int, error)
RegisterMCDBStates registers, on reg, every block state in the Bedrock world at dir that reg does not already know, and returns how many it added.
This is what makes a world holding custom blocks convertible without the behaviour pack. dragonfly's chunk decoder resolves each palette entry against the registry and fails outright on one it cannot find -- "cannot get runtime ID of block state" -- so a single block from a pack stops the conversion at whichever chunk happens to hold it.
What is registered is the bare state, through RegisterBlockState, which is dragonfly's own placeholder for a block nothing implements. That is enough to decode, and it is all that is wanted here: pile stores a palette entry as its identifier and properties, so the file that comes out carries the real cubecraft:portal_side and not a substitute. A server that registers the block properly later resolves it from the same file.
It is not a way to make the block behave. A placeholder has no model, no collision and no behaviour; nothing short of implementing the pack gives it those. It is a way to move the world.
The registry must not be finalized yet, since registration is what Finalize closes off.
func WorldBlockStates ¶ added in v0.2.1
func WorldBlockStates(dir string, opts ...format.ReadOption) ([]format.BlockState, error)
WorldBlockStates returns every block state in a pile world's palettes, across every dimension file, deduplicated and sorted.
No registry is involved: pile stores a palette entry as its identifier and properties, so a state nothing can resolve is still one the file states plainly. That is what makes this usable on a converted world holding blocks from a behaviour pack.
Types ¶
type Builder ¶ added in v0.2.0
type Builder struct {
// contains filtered or unexported fields
}
Builder creates worlds programmatically without a running server: void or flat arenas, generated lobbies, island templates. Build the content, then hand it over with Provider (in-memory world) or Save (write to disk).
A Builder is single-goroutine; after Provider or Save it hands ownership of its chunks over and resets to empty.
func NewBuilder ¶ added in v0.2.0
func NewBuilder(reg world.BlockRegistry, rng cube.Range) *Builder
NewBuilder creates a Builder for worlds with the given vertical range. A nil registry uses world.DefaultBlockRegistry.
func (*Builder) AddBlockEntity ¶ added in v0.2.0
AddBlockEntity attaches block entity NBT to a position.
func (*Builder) AddEntity ¶ added in v0.2.0
AddEntity adds an entity from NBT data. The data must contain a "Pos" list; a "UniqueID" is assigned sequentially when absent.
func (*Builder) Fill ¶ added in v0.2.0
Fill places a block in every position of the box [lo, hi] (inclusive). The chunk lookup is hoisted per column, so large fills stay cheap.
func (*Builder) FillBiome ¶ added in v0.2.0
FillBiome sets the biome in every position of the box [lo, hi].
func (*Builder) Provider ¶ added in v0.2.0
Provider hands the built world over as an in-memory provider. The Builder resets to empty; the chunks are transferred without copying.
func (*Builder) SetBlock ¶ added in v0.2.0
SetBlock places a block. Positions outside the vertical range are ignored.
func (*Builder) SetUserData ¶ added in v0.2.0
SetUserData sets the world's application metadata blob.
type DimFile ¶ added in v0.2.0
type DimFile struct {
Dim world.Dimension
// Indexed reports the file's mode, preserved when writing back.
Indexed bool
// StoreLight reports whether the source file stored baked light,
// preserved when writing back.
StoreLight bool
Columns []format.Column
}
DimFile is one dimension file of a world, loaded for offline tooling.
type MoveOptions ¶ added in v0.2.0
type MoveOptions struct {
// Offset is the block translation applied to everything in the world.
Offset cube.Pos
// Clip permits cutting content that lands outside the vertical range.
// Without it, a move that would lose anything fails with ErrWouldClip.
Clip bool
// DryRun computes the report without writing anything.
DryRun bool
// Backup copies the current files into snapshots/pre-move before writing.
Backup bool
// KeepUserData permits moving a world that carries application metadata,
// which pile copies through untranslated. Without it such a move fails
// with ErrUnmovableUserData.
KeepUserData bool
// Registry used for block resolution; nil uses world.DefaultBlockRegistry.
Registry world.BlockRegistry
// MaxDecoded bounds the live decoded state the world's files may produce,
// in bytes, as MaxDecodedBytes does for a provider. 0 is the format's own
// ceiling.
MaxDecoded int64
}
MoveOptions configures MoveWorld.
type MoveReport ¶ added in v0.2.0
type MoveReport struct {
Offset cube.Pos
// Chunks is the number of columns translated across all dimensions.
Chunks int
// FastPath is true when the offset was chunk-aligned horizontally with no
// vertical component, so blocks were re-keyed without being rewritten.
FastPath bool
// Clipped content counts (non-air blocks, and entries dropped).
ClippedBlocks int
ClippedBlockEntities int
ClippedEntities int
ClippedTicks int
}
MoveReport describes what a move did (or, for a dry run, would do).
func MoveWorld ¶ added in v0.2.0
func MoveWorld(dir string, opt MoveOptions) (*MoveReport, error)
MoveWorld translates a pile world on disk: all blocks, biomes, entities, block entities, scheduled ticks and the spawn position. Files keep their mode (solid or indexed) and are replaced atomically. The move is all-or-nothing across dimensions.
What it does not translate is user data, world-level or per-chunk, because the format stores it as an opaque blob and has no way to find a coordinate inside one. A world carrying any is refused unless MoveOptions.KeepUserData says the caller will re-anchor it: see ErrUnmovableUserData.
func (*MoveReport) ClippedTotal ¶ added in v0.2.0
func (r *MoveReport) ClippedTotal() int
ClippedTotal sums all clipped content.
type Option ¶ added in v0.2.0
type Option func(*config)
Option configures a Provider.
func AppendMode ¶ added in v0.2.0
func AppendMode() Option
AppendMode opens the world as indexed/append files instead of solid ones: stores append immediately, saves are cheap checkpoints, columns are decoded on demand and memory stays at directory-plus-palette level. Use for large or frequently saved worlds. Garbage accumulates between compactions; Close compacts automatically past a garbage threshold. Solid files cannot be opened in append mode (convert with `pile mode` first) and vice versa.
func CacheColumns ¶ added in v0.2.0
CacheColumns keeps up to n decoded columns per dimension in an LRU cache (append mode only), with Morton-neighbour readahead. 0 disables caching.
func Compression ¶ added in v0.2.0
func Compression(level format.CompressionLevel) Option
Compression sets the zstd level used for saves. Default: CompressionBest.
func FastSaves ¶ added in v0.2.0
func FastSaves() Option
FastSaves compresses saves with multiple threads. Saves get faster; solid files are no longer byte-deterministic across runs, which weakens the "identical content = identical file" property.
func FilterBlockEntity ¶ added in v0.2.0
func FilterBlockEntity(f func(chunk.BlockEntity) bool) Option
FilterBlockEntity keeps only block entities for which f returns true when storing.
func FilterColumn ¶ added in v0.2.0
FilterColumn refuses entire columns when storing: columns for which f returns false are silently not persisted.
func FilterEntity ¶ added in v0.2.0
FilterEntity keeps only entities for which f returns true when storing.
func LoadSkip ¶ added in v0.2.0
LoadSkip drops data categories when columns are loaded, even if present in the file. Useful for template worlds whose entities are spawned by code.
It is not a bound and must not be used as one. The file is decoded in full first: the categories are dropped from the column LoadColumn hands back, with every entity already built, and in solid mode the provider goes on holding them for its lifetime. It removes nothing from the peak cost of opening a hostile world. MaxDecodedBytes is the dial for that, "Loading a file somebody sent you", says what it does and does not cover.
func MaxDecodedBytes ¶ added in v0.2.0
MaxDecodedBytes bounds the live decoded state a world file may produce, in bytes. 0 (the default) is the format's own ceiling, which is where §8 of the specification sets it: near what the format can represent, not near what a deployment wants to spend. A legal 1,161-byte file decodes into 1.12 GiB, and the ceiling above it is four times higher again.
Set it when the worlds being opened are not worlds you wrote. A value above the format's ceiling is clamped down to it, so this can tighten the limit and cannot loosen it.
A file refused under this ceiling is not a corrupt file. The error satisfies errors.Is(err, format.ErrDecodeBudget) and deliberately does not satisfy errors.Is(err, format.ErrCorrupt): it says the file is larger than this provider was told to decode, not that anything is wrong with it.
In append mode the limit is per open world file rather than per column read: it covers the directory the file keeps resident plus one decoded column.
What it charges is decoded columns and decoded section storages. It charges nothing for entities, block entities or scheduled updates, and one legal column may hold 1,048,576 of each: a 4,764-byte file of two such columns decodes into 774 MB under a 64 KiB ceiling, and no setting refuses it that does not also refuse a three-column world. That gap is measured and recorded bound; a caller opening worlds it did not write needs a bound outside the process as well as this one.
func ReadOnly ¶ added in v0.2.0
func ReadOnly() Option
ReadOnly opens the provider in read-only mode: all mutating operations are no-ops and the files are never written.
func Registry ¶ added in v0.2.0
func Registry(reg world.BlockRegistry) Option
Registry sets the block registry used for encoding and decoding. It is finalized on open. Default: world.DefaultBlockRegistry.
func Skip ¶ added in v0.2.0
Skip drops whole data categories when columns are stored. Dropped data never reaches the file, so output stays deterministic regardless of the filtered content.
func StoreLight ¶ added in v0.2.0
func StoreLight() Option
StoreLight stores baked light data in saved files. Never needed for correctness (dragonfly recalculates light on chunk load regardless); useful only for consumers that skip that recalculation.
func WithSpawnStore ¶ added in v0.2.0
func WithSpawnStore(s SpawnStore) Option
WithSpawnStore plugs an external player spawn store into the provider.
type Provider ¶
type Provider struct {
// contains filtered or unexported fields
}
Provider implements world.Provider backed by pile files, one per dimension (overworld.pile, nether.pile, end.pile). The whole world is held in memory; saves are full deterministic rewrites (temp file + atomic rename), so a saved file never contains garbage.
func NewMemory ¶ added in v0.2.0
NewMemory creates a provider with no backing files: a pure in-memory world. Save and Close are no-ops; use SaveAs to write it to disk explicitly.
func Open ¶ added in v0.2.0
Open creates a provider for the world directory dir, loading any existing pile files in it. The directory is created on first save when absent.
func (*Provider) AutoSave ¶ added in v0.2.0
AutoSave starts a background ticker that schedules a coalesced save every interval. The returned stop function halts it; it also stops on Close.
It saves through SaveAsync, so a failed autosave is reported by the next Save or Close and not at the moment it happens, and only the most recent failure is kept. A process that autosaves and ignores Close's return value never learns that any of them failed.
func (*Provider) ChunkCount ¶
ChunkCount returns the number of stored columns in a dimension, including base-provider columns not shadowed locally.
func (*Provider) ChunkUserData ¶ added in v0.2.0
ChunkUserData returns a copy of the per-chunk metadata blob, or nil.
func (*Provider) Close ¶
Close saves pending changes (unless read-only) and marks the provider closed. It waits for any in-flight background save to finish first. In append mode, dimension files past the garbage threshold are compacted.
A Close that fails does not close the provider: the error is returned, the state stays dirty, and Close may be retried once the underlying problem (a full disk, say) is resolved.
func (*Provider) Columns ¶ added in v0.2.0
Columns iterates over copies of all stored columns of a dimension, including base-provider columns not shadowed locally.
The set of positions is fixed when iteration starts, so storing a column at a new position during iteration is safe and not observed. Each column is produced when it is reached, one at a time: iterating does not require memory for the whole dimension, and a caller that stops early pays only for what it took. In append mode that means a column overwritten during the iteration may be yielded with its new content.
func (*Provider) DeleteSnapshot ¶ added in v0.2.0
DeleteSnapshot removes a snapshot.
func (*Provider) IsReadOnly ¶
IsReadOnly reports whether the provider was opened read-only.
func (*Provider) IterError ¶ added in v0.2.0
IterError returns and clears the first error a Columns iteration hit. An iterator cannot report errors itself, so any caller for which a short iteration would mean data loss (conversion, export, backup) must check this after iterating.
func (*Provider) LoadColumn ¶
LoadColumn returns a copy of the stored column at pos, falling back to the base provider for instances. If none exists, the error matches ErrNotFound (dragonfly's leveldb.ErrNotFound) as the world.Provider contract requires.
func (*Provider) LoadPlayerSpawnPosition ¶
LoadPlayerSpawnPosition delegates to the configured SpawnStore; without one, no spawn exists. Pile files never contain player data.
func (*Provider) Rollback ¶ added in v0.2.0
Rollback replaces the world's current state with a snapshot. All unsaved and saved changes since the snapshot are discarded; the provider reloads from the restored files.
func (*Provider) Save ¶
Save synchronously writes all dirty dimensions. Unchanged dimensions are not rewritten unless world metadata changed (metadata is duplicated into every dimension file). A failure from an earlier background save is surfaced here (and cleared). Encoding and file I/O run outside the provider lock, so a save does not stall the world.
func (*Provider) SaveAs ¶ added in v0.2.0
SaveAs writes the provider's complete current state (including base-provider columns for instances) as a fresh world at dir. The provider itself is unchanged; an in-memory instance stays in memory. Works on read-only providers: it writes a copy, not the source.
func (*Provider) SaveAsync ¶
func (p *Provider) SaveAsync()
SaveAsync schedules a background save. Multiple calls coalesce; the last scheduled save always observes the latest state. No-op when read-only.
It reports nothing, because there is nobody to report to. A background save that fails is remembered and returned by the next Save or Close, so the failure is not lost — but only the most recent one is kept, and a process that only ever calls SaveAsync never observes any of them. Anything that must know a save succeeded has to call Save.
func (*Provider) SavePlayerSpawnPosition ¶
SavePlayerSpawnPosition delegates to the configured SpawnStore, if any.
func (*Provider) SaveSettings ¶
SaveSettings stores the world settings, persisted on the next save.
func (*Provider) SetChunkUserData ¶ added in v0.2.0
SetChunkUserData stores a per-chunk metadata blob. It is a no-op if no column is stored at pos.
func (*Provider) SetUserData ¶ added in v0.1.6
SetUserData stores the world's application metadata blob.
func (*Provider) Settings ¶
Settings returns the world settings.
The pointer is the provider's own, not a copy: world.Provider's contract has dragonfly take it at startup, mutate it as the world runs and hand it back to SaveSettings at shutdown. A caller that changes settings outside that cycle must still call SaveSettings, because nothing observes a write through this pointer and the world would not be marked dirty.
func (*Provider) Snapshot ¶ added in v0.2.0
Snapshot saves the current state and copies the world's files into snapshots/<name>, replacing any snapshot of the same name. Not supported on read-only or in-memory providers.
func (*Provider) StoreColumn ¶
StoreColumn stores a copy of col at pos, applying the configured skip mask and filters. Read-only providers ignore the call.
type SkipMask ¶ added in v0.2.0
type SkipMask uint32
SkipMask selects data categories to drop when storing columns.
const ( // SkipEntities drops all entities. SkipEntities SkipMask = 1 << iota // SkipBlockEntities drops all block entities. SkipBlockEntities // SkipScheduledTicks drops all scheduled block updates. SkipScheduledTicks // SkipBiomes stores no biome data; loading yields biome 0 everywhere. SkipBiomes // SkipChunkUserData drops per-chunk user data. SkipChunkUserData )
type SpawnStore ¶ added in v0.2.0
type SpawnStore interface {
LoadPlayerSpawn(id uuid.UUID) (pos cube.Pos, exists bool, err error)
SavePlayerSpawn(id uuid.UUID, pos cube.Pos) error
}
SpawnStore is an optional external store for player spawn positions. Pile keeps no player data in its files; without a SpawnStore the provider reports no spawn for every player.
type Structure ¶ added in v0.2.0
type Structure struct {
// contains filtered or unexported fields
}
Structure is a block region stored in the pile structure format. It implements world.Structure, so it can be built with tx.BuildStructure; the PasteInto fast path additionally carries entities and block entity NBT, which the world.Structure interface cannot express.
func ExtractStructure ¶ added in v0.2.0
func ExtractStructure(p *Provider, dim world.Dimension, lo, hi cube.Pos, opts ...StructureOption) (*Structure, error)
ExtractStructure copies the block region [lo, hi] (inclusive) of a dimension from a provider into a new Structure, including block entities and entities inside the region. Options apply to the resulting structure.
func LoadStructure ¶ added in v0.2.0
func LoadStructure(path string, opts ...StructureOption) (*Structure, error)
LoadStructure reads a structure file.
func (*Structure) At ¶ added in v0.2.0
At returns the block at a structure-local position, implementing world.Structure. Blocks carrying NBT (chests, signs, ...) are returned with their block entity data decoded into the block.
func (*Structure) Data ¶ added in v0.2.0
func (s *Structure) Data() *format.StructureData
Data exposes the underlying structure data. It is the Structure's own, not a copy: mutating it mutates the Structure, and the encoder requires Cells to stay exactly CellDims(Size) long, so a caller that resizes one without the other has built a value that will not save.
func (*Structure) Dimensions ¶ added in v0.2.0
Dimensions returns the structure's size, implementing world.Structure.
func (*Structure) PasteInto ¶ added in v0.2.0
PasteInto writes the structure into a provider's stored world at position `at` (the structure's origin offset is applied). Blocks, block entities and entities are carried; with SkipAir, air positions leave existing blocks untouched. Positions outside the dimension's range are dropped.
func (*Structure) Rotate ¶ added in v0.2.0
Rotate returns a copy of the structure rotated clockwise (viewed from above) by quarters*90 degrees around the Y axis. Positions of blocks, block entities and entities rotate exactly; the paste anchor resets to zero.
Block state rotation is best effort: the common Bedrock direction properties (facing_direction, direction, weirdo_direction, pillar_axis, ground_sign_direction, minecraft:cardinal_direction and string facing properties) rotate correctly, which covers stairs, logs, signs, doors, furnaces, chests and most other rotatable blocks. Exotic properties (rail curves and similar) keep their state and may need manual fixing.
type StructureLibrary ¶ added in v0.2.0
type StructureLibrary struct {
// contains filtered or unexported fields
}
StructureLibrary is a set of structures loaded from a directory, looked up by file basename (without the .pile extension).
func LoadStructureLibrary ¶ added in v0.2.0
func LoadStructureLibrary(dir string, opts ...StructureOption) (*StructureLibrary, error)
LoadStructureLibrary loads every *.pile structure in a directory. Options apply to each structure. Non-structure pile files fail the load: a library directory holds structures only.
func (*StructureLibrary) Get ¶ added in v0.2.0
func (l *StructureLibrary) Get(name string) (*Structure, bool)
Get returns a structure by name.
func (*StructureLibrary) Len ¶ added in v0.2.0
func (l *StructureLibrary) Len() int
Len returns the number of structures.
func (*StructureLibrary) Names ¶ added in v0.2.0
func (l *StructureLibrary) Names() []string
Names returns all structure names, sorted.
type StructureOption ¶ added in v0.2.0
type StructureOption func(*Structure)
StructureOption configures a Structure.
func SkipAir ¶ added in v0.2.0
func SkipAir() StructureOption
SkipAir makes At return nil for air cells, so building the structure onto a world leaves existing blocks in air positions untouched. PasteInto honours it the same way.
func StructureMaxDecodedBytes ¶ added in v0.2.0
func StructureMaxDecodedBytes(n int64) StructureOption
StructureMaxDecodedBytes bounds the live decoded state LoadStructure may produce, in bytes. It is MaxDecodedBytes for structure files: 0 (the default) is the format's own ceiling, a value above it is clamped down, and a refusal reports format.ErrDecodeBudget rather than claiming the file is corrupt.
It has the same blind spot the provider's does, and it matters more here because a structure is a single object: the ceiling charges decoded cells and section storages, and charges nothing for the block entities and entities a structure carries.
func StructureRegistry ¶ added in v0.2.0
func StructureRegistry(reg world.BlockRegistry) StructureOption
StructureRegistry sets the block registry used to resolve blocks. Default: world.DefaultBlockRegistry.
type Template ¶ added in v0.2.0
type Template struct {
// contains filtered or unexported fields
}
Template is a shared, read-only base world from which any number of independent instances can be created. The template's decoded state is shared by all instances copy-on-write: an instance only holds the columns it modified.
func OpenTemplate ¶ added in v0.2.0
OpenTemplate opens a world directory as a read-only template.
func (*Template) Instance ¶ added in v0.2.0
Instance creates an in-memory world.Provider backed by the template. Loads fall through to the template until a column is stored; stores stay in the instance. Close discards the instance; SaveAs persists it as a new world. Options configure the instance (filters, compression for SaveAs).
type WorldFiles ¶ added in v0.2.0
WorldFiles is a world directory loaded for offline tooling (move, diff, patch, prune). It holds every dimension's columns plus the world metadata blobs.
func LoadWorldFiles ¶ added in v0.2.0
func LoadWorldFiles(dir string, reg world.BlockRegistry, opts ...Option) (*WorldFiles, error)
LoadWorldFiles loads all dimension files of a world directory, regardless of their mode. Intended for offline tools; servers use Open.
Options are accepted so a tool reading a world it did not write can set MaxDecodedBytes; only the decode policy is read, since everything else an Option carries is about a running provider. It has no ceiling by default, which is the same position Open is in and for the same reason.
func (*WorldFiles) Backup ¶ added in v0.2.0
func (wf *WorldFiles) Backup(dir, name string) error
Backup copies the world's current dimension files into snapshots/<name>, replacing any previous backup of that name.
func (*WorldFiles) Dim ¶ added in v0.2.0
func (wf *WorldFiles) Dim(dim world.Dimension) *DimFile
Dim returns the loaded data for a dimension, or nil.
func (*WorldFiles) Write ¶ added in v0.2.0
func (wf *WorldFiles) Write(dir string, reg world.BlockRegistry) error
Write writes every dimension back into dir. All dimensions are encoded and fsynced to temporary files first and only then renamed into place, so a failure while encoding or writing any dimension leaves the whole world untouched. The renames themselves are not a single atomic transaction: a crash inside the rename phase can leave a world with some dimensions updated (each individual file is always intact and consistent).
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
pile
command
Command pile is the tooling CLI for the pile world format: conversion to and from dragonfly's leveldb format (mcdb), inspection and verification.
|
Command pile is the tooling CLI for the pile world format: conversion to and from dragonfly's leveldb format (mcdb), inspection and verification. |
|
Package format implements the Pile v2 world file format: a compact, deterministic, single-file world container designed around dragonfly's chunk types.
|
Package format implements the Pile v2 world file format: a compact, deterministic, single-file world container designed around dragonfly's chunk types. |
|
internal
|
|
|
lru
Package lru holds the bounded least-recently-used map used by both the provider's column and metadata caches and the format package's shared zstd dictionary codecs.
|
Package lru holds the bounded least-recently-used map used by both the provider's column and metadata caches and the format package's shared zstd dictionary codecs. |