Class ScyllaSparseHexGrid<TCell>
Sparse, dictionary-backed hexagonal grid storing per-cell data of type TCell.
Cells are addressed by HexCoord with O(1) average-case access.
Optionally bounded; unbounded grids can grow dynamically to any extent.
Unsynchronized by default; use AsSynchronized(object) to obtain a thread-safe wrapper.
Inherited Members
Namespace: Scylla.Core.Structures
Assembly: ScyllaCore.dll
Syntax
public sealed class ScyllaSparseHexGrid<TCell> : IScyllaGrid<HexCoord, TCell>, IScyllaCollection
Type Parameters
| Name | Description |
|---|---|
| TCell | The type of data stored in each grid cell. May be a value or reference type. |
Remarks
Unlike ScyllaHexGrid<TCell>, this grid only stores cells that have been explicitly set via the indexer, TrySet(HexCoord, TCell), or equivalent. Unset cells do not exist in the backing dictionary and are not returned by any query. Removing a cell is supported via TryRemove(HexCoord, out TCell).
Two construction modes are available:
- Unbounded: Any axial coordinate may be written. HasBounds returns false and IsInBounds(HexCoord) always returns true. Use when the extent of the grid is unknown ahead of time (e.g., procedurally generated terrain discovered at runtime).
- Bounded: Writes outside the defined Q/R range are rejected. HasBounds returns true and out-of-bounds writes via the indexer throw ArgumentOutOfRangeException; TrySet(HexCoord, TCell) returns false silently.
The grid implements IScyllaGrid<TCoord, TCell> and reports the capabilities
SupportsContains | SupportsKeyLookup. It does NOT report HasCapacity or
SupportsRandomAccess (unbounded grids have no fixed capacity; the indexer requires
an existing key for reads via the dictionary).
Constructors
ScyllaSparseHexGrid(HexGridLayout)
Creates a new unbounded sparse hex grid with the specified layout. Any axial coordinate may be written; HasBounds is false.
Declaration
public ScyllaSparseHexGrid(HexGridLayout layout)
Parameters
| Type | Name | Description |
|---|---|---|
| HexGridLayout | layout | The spatial layout used for world-space conversions. |
ScyllaSparseHexGrid(HexGridLayout, int, int, int, int)
Creates a new bounded sparse hex grid with the specified layout and inclusive axial bounds. Writes to coordinates outside the bounds are rejected. HasBounds is true and IsInBounds(HexCoord) enforces the range.
Declaration
public ScyllaSparseHexGrid(HexGridLayout layout, int qMin, int rMin, int qMax, int rMax)
Parameters
| Type | Name | Description |
|---|---|---|
| HexGridLayout | layout | The spatial layout used for world-space conversions. |
| int | qMin | The minimum Q value (inclusive). |
| int | rMin | The minimum R value (inclusive). |
| int | qMax | The maximum Q value (inclusive). Must be greater than or equal to |
| int | rMax | The maximum R value (inclusive). Must be greater than or equal to |
Exceptions
| Type | Condition |
|---|---|
| ArgumentOutOfRangeException | Thrown when |
Properties
Capabilities
Gets the feature and capability flags supported by this collection instance.
Declaration
public ScyllaCollectionCapabilities Capabilities { get; }
Property Value
| Type | Description |
|---|---|
| ScyllaCollectionCapabilities | A bitfield of ScyllaCollectionCapabilities flags describing which optional operations the concrete instance supports. The value None indicates that only the base contract (Count, IsEmpty, Clear()) is available. |
Remarks
Use Capabilities for feature detection in place of type-casting. For example:
if ((collection.Capabilities & ScyllaCollectionCapabilities.SupportsPeek) != 0)
{
// safe to call TryPeek through IScyllaCollection<T>
}
Synchronized wrappers cache the capability flags of their inner collection at construction time, so the value returned is stable and does not require synchronization.
See Also
CellCount
Gets the number of populated (logically active) cells in the grid.
Declaration
public int CellCount { get; }
Property Value
| Type | Description |
|---|---|
| int | For dense grids, this always equals Count - every cell slot is pre-allocated and considered populated regardless of its stored value. The value is fixed at construction and never changes. For sparse grids, this equals the number of cells that have been explicitly written via TrySet(TCoord, TCell) and not yet removed. The value may be zero on a freshly created or cleared sparse grid. |
See Also
Count
Gets the number of items currently contained in the collection.
Declaration
public int Count { get; }
Property Value
| Type | Description |
|---|---|
| int | A non-negative integer representing the current element count.
Returns |
Remarks
On unsynchronized collections, Count is not thread-safe and may return a stale
value when accessed concurrently. On synchronized wrappers, reading Count is
protected by the internal lock.
HasBounds
Gets whether this grid has defined bounds.
Declaration
public bool HasBounds { get; }
Property Value
| Type | Description |
|---|---|
| bool |
Height
Gets the inclusive range of the grid in the R direction (RMax - RMin + 1).
Only valid when HasBounds is true.
Declaration
public int Height { get; }
Property Value
| Type | Description |
|---|---|
| int |
Exceptions
| Type | Condition |
|---|---|
| InvalidOperationException | Thrown when the grid is unbounded. |
IsEmpty
Gets a value indicating whether the collection contains no items.
Declaration
public bool IsEmpty { get; }
Property Value
| Type | Description |
|---|---|
| bool |
|
Remarks
This is a convenience property equivalent to Count == 0. Prefer it over comparing
Count directly when the actual count is not needed, as some implementations may
compute it more efficiently.
this[HexCoord]
Gets or sets the cell value at the specified coordinate.
Declaration
public TCell this[HexCoord coord] { get; set; }
Parameters
| Type | Name | Description |
|---|---|---|
| HexCoord | coord | The hex coordinate to access. |
Property Value
| Type | Description |
|---|---|
| TCell |
Remarks
Get: Retrieves the value stored at coord. The coordinate
must have been previously set; use TryGet(HexCoord, out TCell) for a non-throwing alternative.
Set: Stores a value at coord. If this grid is bounded and
the coordinate is outside the defined bounds, an exception is thrown. Use
TrySet(HexCoord, TCell) for a non-throwing alternative.
Exceptions
| Type | Condition |
|---|---|
| KeyNotFoundException | Thrown by the getter when |
| ArgumentOutOfRangeException | Thrown by the setter when the grid is bounded and |
Layout
Gets the layout used for world-space conversion.
Declaration
public HexGridLayout Layout { get; }
Property Value
| Type | Description |
|---|---|
| HexGridLayout |
QMax
Declaration
public int QMax { get; }
Property Value
| Type | Description |
|---|---|
| int |
Exceptions
| Type | Condition |
|---|---|
| InvalidOperationException | Thrown when the grid is unbounded. |
QMin
Declaration
public int QMin { get; }
Property Value
| Type | Description |
|---|---|
| int |
Exceptions
| Type | Condition |
|---|---|
| InvalidOperationException | Thrown when the grid is unbounded. |
RMax
Declaration
public int RMax { get; }
Property Value
| Type | Description |
|---|---|
| int |
Exceptions
| Type | Condition |
|---|---|
| InvalidOperationException | Thrown when the grid is unbounded. |
RMin
Declaration
public int RMin { get; }
Property Value
| Type | Description |
|---|---|
| int |
Exceptions
| Type | Condition |
|---|---|
| InvalidOperationException | Thrown when the grid is unbounded. |
SyncRoot
Gets the synchronization root object used to externally coordinate multi-step operations with this collection.
Declaration
public object SyncRoot { get; }
Property Value
| Type | Description |
|---|---|
| object | A non-null object suitable for use with |
Remarks
When this collection is a synchronized wrapper, SyncRoot must be non-null and
stable for the entire lifetime of the wrapper. All internal operations on the wrapper
must lock on this same object. This allows callers to perform atomic multi-step
sequences:
lock (collection.SyncRoot)
{
if (!collection.IsEmpty)
typedCollection.TryRemove(out var item);
}
For unsynchronized collections (SyncRoot == null), callers are responsible for
supplying and consistently applying their own external synchronization mechanism.
A null SyncRoot does not mean the collection is thread-safe;
consult ThreadSafety for the authoritative guarantee.
See Also
ThreadSafety
Gets the thread-safety guarantees provided by this collection instance.
Declaration
public ScyllaCollectionThreadSafety ThreadSafety { get; }
Property Value
| Type | Description |
|---|---|
| ScyllaCollectionThreadSafety | A ScyllaCollectionThreadSafety value indicating whether the collection is unsynchronized, synchronized via a lock, or safe for lock-free concurrent access. Most core implementations return Unsynchronized. Synchronized wrappers return Synchronized. |
Remarks
Always check this property (or SyncRoot) before assuming a collection is
safe for concurrent use. Do not rely solely on the absence of a non-null SyncRoot
to infer thread safety; use this property as the authoritative source.
See Also
Width
Gets the inclusive range of the grid in the Q direction (QMax - QMin + 1).
Only valid when HasBounds is true.
Declaration
public int Width { get; }
Property Value
| Type | Description |
|---|---|
| int |
Exceptions
| Type | Condition |
|---|---|
| InvalidOperationException | Thrown when the grid is unbounded. |
Methods
AsSynchronized(object)
Creates and returns a ScyllaSparseHexGrid<TCell>.SynchronizedScyllaSparseHexGrid wrapper that synchronizes all read and write operations on this grid using a single lock object.
Declaration
public ScyllaSparseHexGrid<TCell>.SynchronizedScyllaSparseHexGrid AsSynchronized(object syncRoot = null)
Parameters
| Type | Name | Description |
|---|---|---|
| object | syncRoot | Optional external lock object. Pass a shared lock to coordinate across multiple collections atomically. If null, the wrapper creates its own private lock. |
Returns
| Type | Description |
|---|---|
| ScyllaSparseHexGrid<TCell>.SynchronizedScyllaSparseHexGrid | A ScyllaSparseHexGrid<TCell>.SynchronizedScyllaSparseHexGrid wrapping this grid instance. |
Clear()
Removes all items from the collection and resets it to an empty state.
Declaration
public void Clear()
Remarks
Implementations that store reference-type elements should null out internal slots after
clearing to avoid retaining object references and preventing garbage collection.
After Clear returns, Count must be 0 and
IsEmpty must be true.
On synchronized wrappers this operation is protected by the collection's internal lock. On unsynchronized collections, callers are responsible for external coordination.
Contains(HexCoord)
Determines whether the specified coordinate is addressable and populated in this grid.
Declaration
public bool Contains(HexCoord coord)
Parameters
| Type | Name | Description |
|---|---|---|
| HexCoord | coord | The coordinate to test. |
Returns
| Type | Description |
|---|---|
| bool |
For dense grids, returns
For sparse grids, returns |
Remarks
This method is equivalent to checking whether TryGet(TCoord, out TCell) would return
true for the same coordinate. Use it when you only need the existence check
and do not need the value.
See Also
CreateBuilder()
Creates a new fluent ScyllaSparseHexGrid<TCell>.Builder for configuring and constructing a ScyllaSparseHexGrid<TCell> instance with complex parameters.
Declaration
public static ScyllaSparseHexGrid<TCell>.Builder CreateBuilder()
Returns
| Type | Description |
|---|---|
| ScyllaSparseHexGrid<TCell>.Builder | A new ScyllaSparseHexGrid<TCell>.Builder with default settings (unbounded, layout unset). |
DrawLine(HexCoord, HexCoord, Span<HexCoord>)
Traces a hex line from from to to and writes the set cells
along it into buffer. Mirrors DrawLine(SquareCoord, SquareCoord, Span<SquareCoord>) but keeps only
cells that currently exist in this sparse grid.
Declaration
public int DrawLine(HexCoord from, HexCoord to, Span<HexCoord> buffer)
Parameters
| Type | Name | Description |
|---|---|---|
| HexCoord | from | The starting coordinate (inclusive). |
| HexCoord | to | The ending coordinate (inclusive). |
| Span<HexCoord> | buffer | A span sized for the full line ( |
Returns
| Type | Description |
|---|---|
| int | The number of set cells written. |
GetEnumerator()
Returns a value-type ScyllaSparseHexGrid<TCell>.Enumerator that iterates through all populated cells without allocating on the heap when used with foreach on the concrete type.
Declaration
public ScyllaSparseHexGrid<TCell>.Enumerator GetEnumerator()
Returns
| Type | Description |
|---|---|
| ScyllaSparseHexGrid<TCell>.Enumerator | An ScyllaSparseHexGrid<TCell>.Enumerator for allocation-free iteration over (Coord, Value) pairs. |
GetNeighborsNonAlloc(HexCoord, Span<HexCoord>)
Writes the neighbors of the specified coordinate that are currently set in this grid into the provided buffer. Unlike the dense-grid version, neighbors that have not been explicitly written are not included even if they would be in-bounds.
Declaration
public int GetNeighborsNonAlloc(HexCoord coord, Span<HexCoord> buffer)
Parameters
| Type | Name | Description |
|---|---|---|
| HexCoord | coord | The coordinate whose set neighbors to retrieve. |
| Span<HexCoord> | buffer | A span to receive neighbor coordinates. Writing stops when the buffer is full. |
Returns
| Type | Description |
|---|---|
| int | The number of set neighbors written (up to 6). |
GetRange(HexCoord, int, Span<HexCoord>)
Writes the set cells within range steps of center into
buffer. Mirrors GetRange(HexCoord, int, Span<HexCoord>) but keeps only cells that
currently exist in this sparse grid.
Declaration
public int GetRange(HexCoord center, int range, Span<HexCoord> buffer)
Parameters
| Type | Name | Description |
|---|---|---|
| HexCoord | center | The center of the range query. |
| int | range | The maximum step distance. Must be at least 0. |
| Span<HexCoord> | buffer | A span sized for the full range ( |
Returns
| Type | Description |
|---|---|
| int | The number of set cells written. |
Exceptions
| Type | Condition |
|---|---|
| ArgumentOutOfRangeException | Thrown when |
GetRing(HexCoord, int, Span<HexCoord>)
Writes the set cells at exactly radius steps from center
into buffer. Mirrors GetRing(HexCoord, int, Span<HexCoord>) but keeps only cells that
currently exist in this sparse grid.
Declaration
public int GetRing(HexCoord center, int radius, Span<HexCoord> buffer)
Parameters
| Type | Name | Description |
|---|---|---|
| HexCoord | center | The center of the ring. |
| int | radius | The ring radius. Must be at least 0. |
| Span<HexCoord> | buffer | A span sized for the full ring ( |
Returns
| Type | Description |
|---|---|
| int | The number of set cells written. |
Exceptions
| Type | Condition |
|---|---|
| ArgumentOutOfRangeException | Thrown when |
GetSpiral(HexCoord, int, Span<HexCoord>)
Writes the set cells from center outward in spiral order up to
radius into buffer. Mirrors GetSpiral(HexCoord, int, Span<HexCoord>)
but keeps only cells that currently exist in this sparse grid.
Declaration
public int GetSpiral(HexCoord center, int radius, Span<HexCoord> buffer)
Parameters
| Type | Name | Description |
|---|---|---|
| HexCoord | center | The center where the spiral begins. |
| int | radius | The outermost ring radius. Must be at least 0. |
| Span<HexCoord> | buffer | A span sized for the full spiral ( |
Returns
| Type | Description |
|---|---|
| int | The number of set cells written. |
Exceptions
| Type | Condition |
|---|---|
| ArgumentOutOfRangeException | Thrown when |
GridToWorld(HexCoord)
Converts a hex coordinate to world-space position using the grid's layout.
Declaration
public Vector2 GridToWorld(HexCoord coord)
Parameters
| Type | Name | Description |
|---|---|---|
| HexCoord | coord | The hex coordinate. |
Returns
| Type | Description |
|---|---|
| Vector2 | The world-space center of the hex. |
IsInBounds(HexCoord)
Determines whether the specified coordinate is within the grid bounds. Always returns true for unbounded grids (HasBounds is false).
Declaration
public bool IsInBounds(HexCoord coord)
Parameters
| Type | Name | Description |
|---|---|---|
| HexCoord | coord | The hex coordinate to test. |
Returns
| Type | Description |
|---|---|
| bool | true if the grid is unbounded, or if |
TryGet(HexCoord, out TCell)
Attempts to retrieve the value stored at the specified coordinate without throwing on failure.
Declaration
public bool TryGet(HexCoord coord, out TCell value)
Parameters
| Type | Name | Description |
|---|---|---|
| HexCoord | coord | The grid coordinate to look up. |
| TCell | value | When this method returns |
Returns
| Type | Description |
|---|---|
| bool |
|
Remarks
Prefer this method over direct indexer access when the coordinate's validity is not guaranteed, as it avoids the cost of exception handling on out-of-bounds access. For dense grids, "within bounds" means the coordinate maps to a valid flat-array index. For sparse grids, "within bounds" additionally requires that the cell has been set.
See Also
TryRemove(HexCoord, out TCell)
Attempts to remove the cell at the specified coordinate from the grid.
Declaration
public bool TryRemove(HexCoord coord, out TCell value)
Parameters
| Type | Name | Description |
|---|---|---|
| HexCoord | coord | The coordinate to remove. |
| TCell | value | When this method returns, contains the removed value if found, or default otherwise. |
Returns
| Type | Description |
|---|---|
| bool | True if the cell was found and removed; false otherwise. |
TrySet(HexCoord, TCell)
Attempts to store a value at the specified coordinate without throwing on failure.
Declaration
public bool TrySet(HexCoord coord, TCell value)
Parameters
| Type | Name | Description |
|---|---|---|
| HexCoord | coord | The grid coordinate to write to. |
| TCell | value | The value to store at |
Returns
| Type | Description |
|---|---|
| bool |
|
Remarks
For dense grids, this writes to the pre-allocated cell at
coord and returns false if the coordinate falls outside
the grid's dimensions.
For sparse grids, this inserts or updates the entry at
coord and returns false only when the grid is bounded
and coord falls outside the defined bounds. On unbounded sparse
grids this method always returns true.
A successful call increments CellCount on sparse grids when
coord is newly written for the first time.
See Also
WorldToGrid(Vector2)
Converts a world-space position to a hex coordinate using the grid's layout.
Declaration
public HexCoord WorldToGrid(Vector2 worldPos)
Parameters
| Type | Name | Description |
|---|---|---|
| Vector2 | worldPos | The world-space position. |
Returns
| Type | Description |
|---|---|
| HexCoord | The nearest hex coordinate. |