simvx.core.properties

Typed Property subclasses for editor-visible values.

These subclasses extend :class:simvx.core.descriptors.Property with type-specific metadata so the editor can dispatch the correct widget without relying on name heuristics or tuple-shape guessing. Stored values remain primitive (str, int, tuple) so scene serialisation is unaffected.

The five subclasses are:

  • class:

    Colour – RGB/RGBA tuple with optional alpha channel. Also carries a palette of named colour constants (Colour.RED etc.) and factory helpers (Colour.hex, Colour.rgba, Colour.from_rgb255).

  • class:

    FilePath – File / resource path with filter and relative base.

  • class:

    Multiline – Multi-line string with optional syntax hint.

  • class:

    Bitmask – N-bit integer with optional per-bit names.

  • class:

    NodePath – Scene-relative node path with optional type filter.

All five accept the existing hint=, group=, on_change=, link=, propagate= kwargs exactly like :class:Property.

Module Contents

Classes

Colour

RGB or RGBA colour property (tuple of floats in [0, 1]).

FilePath

File / resource path property.

Multiline

Multi-line string property with optional syntax hint.

Bitmask

Bit flag integer property with optional per-bit names.

NodePath

Scene-relative node path property.

Functions

set_mask_bit

Return value with bit index (0-31) set or cleared per enabled.

get_mask_bit

Return whether bit index (0-31) is set in value.

Data

API

simvx.core.properties.set_mask_bit(value: int, index: int, enabled: bool, *, label: str = 'Layer') int[source]

Return value with bit index (0-31) set or cleared per enabled.

Shared by the engine’s render-layer / cull-mask toggles. label names the field in the range-check error message.

simvx.core.properties.get_mask_bit(value: int, index: int, *, label: str = 'Layer') bool[source]

Return whether bit index (0-31) is set in value.

class simvx.core.properties.Colour(default: tuple = (1.0, 1.0, 1.0, 1.0), *, has_alpha: bool = True, **kwargs)[source]

Bases: simvx.core.descriptors.Property

RGB or RGBA colour property (tuple of floats in [0, 1]).

Also exposes a palette of common colour constants and hex/rgba factory helpers for use anywhere an RGBA tuple is expected.

Example as a Property::

class Light(Node3D):
    tint = Colour((1.0, 0.5, 0.0, 1.0))
    ambient = Colour((0.1, 0.1, 0.15), has_alpha=False)

Example as a palette::

panel.bg_colour = Colour.RED
label.text_colour = Colour.hex("#FF6600")
button.bg_colour = Colour.rgba(0.2, 0.4, 0.8)

Assigning None to a :class:Colour Property reverts the value to the descriptor’s declared default (mirroring :class:ThemeColour’s “no override” semantics). Widget setters that accept Colour.coerce output (Panel.bg_colour etc.) treat None as “use the theme default”.

A stored value always has the arity the property declares, so downstream code can unpack it. An RGB value assigned to an RGBA property gains an opaque alpha, and an opaque RGBA value assigned to an RGB property drops it, which is why the palette constants (all RGBA) work on an alpha-less property. A translucent RGBA value assigned to an RGB property raises: that alpha is real data and silently discarding it would render the wrong thing.

Initialization

Create an editor-visible property descriptor.

Args: default: Default value for the property. Mutually exclusive with default_factory. Mutable containers (list, dict, set, bytearray) are rejected here because a single shared instance would alias across every owning object: pass default_factory instead. default_factory: Zero-arg callable invoked the first time each instance reads the property. The result is cached on the instance, matching functools.cached_property and dataclasses.field(default_factory=...) semantics. range: Optional (min, max) tuple for numeric values. By default (clamp=True) assignments are hard-clamped into [min, max], which doubles as input validation (audio safety, save-load sanitisation, [0,1] enforcement rely on this). With clamp=False the range is a soft hint: it sets the editor inspector field’s default bounds (which stretch to cover a value outside them), and assigned values pass through unclamped. Use clamp=False for physical magnitudes whose range is a suggestion, not a limit (e.g. particle speed in pixels/sec). enum: Optional list of allowed values. coerce: Optional single-argument callable that converts an incoming value into the form the property stores. It runs FIRST, before every other check: coerce, then scalar rejection, then range clamping, then enum membership, then the change-detection and on_change machinery. Everything downstream therefore sees the converted value. The declared default is converted once at class-definition time so reads of an unwritten property return the canonical form too (default_factory results are used verbatim). Passing an Enum type is the common case: coerce=BodyMode lets callers write mode="static" while the node stores BodyMode.STATIC, so identity comparisons downstream hold. A value the callable rejects raises ValueError naming the owning class, the property and the accepted values. A property whose default is an Enum member coerces to that member’s type without being asked, so every enum-valued property stores members rather than the bare strings or ints they wrap. Pass coerce explicitly to override that. hint: Description shown in the editor inspector. link: When True, child values are offset from the parent’s value. propagate: When True, bool/enum Settings inherit disabling values from parents. group: Inspector section name for grouping. Empty string = default “Properties” section. on_change: Name of a bound method to invoke on the owning instance after a successful value change (i.e. when the new value differs from the old). Hooks fired during __init__ are deferred until __init__ returns, then dispatched once each (deduplicated by (property, hook) pair) so the hook always sees a fully constructed object. After construction, hooks fire synchronously inside __set__ (unless coalesce=True: see below). coalesce: When True and on_change is set, post-init hook calls fire at most once per scene-tree frame. Multiple writes within one tick collapse to a single deferred call drained at the end of :meth:SceneTree.tick: useful for expensive handlers like HUD rasterisation that don’t care about intermediate values (Tower Defence: coins -= 1 repeated five times in one frame rasterised the HUD text five times). The owning object must be attached to a SceneTree (obj._tree set); for tree-less owners the flag is ignored and hooks fire synchronously. persist: When True, the value is included in SaveManager snapshots. save_version: Optional integer schema version recorded alongside the persisted value. clamp: When True (default) a numeric range hard-clamps every assignment into bounds (validation). When False the range is an editor-field hint only and out-of-range values are accepted verbatim, both on assignment and in the inspector. Has no effect when range is None. It does not relax the type: a ranged property converts its value to a builtin number and refuses NaN under either setting, because NaN is not a magnitude that a looser bound could accommodate. scalar: When True, reject array-like values (numpy ndarray with ndim >= 1, Vec2/Vec3, list, tuple, dict, set) at assignment with a clear TypeError. Plain Python numbers, numpy scalar types (np.float32, np.int64 etc.), and 0-d numpy arrays are accepted. Use for properties that semantically represent a single number (e.g. Camera2D.zoom) so a stray Vec2 doesn’t leak into downstream math and produce visual glitches.

WHITE

(1.0, 1.0, 1.0, 1.0)

BLACK

(0.0, 0.0, 0.0, 1.0)

RED

(1.0, 0.0, 0.0, 1.0)

GREEN

(0.0, 1.0, 0.0, 1.0)

BLUE

(0.0, 0.0, 1.0, 1.0)

YELLOW

(1.0, 1.0, 0.0, 1.0)

CYAN

(0.0, 1.0, 1.0, 1.0)

MAGENTA

(1.0, 0.0, 1.0, 1.0)

TRANSPARENT

(0.0, 0.0, 0.0, 0.0)

GRAY

(0.5, 0.5, 0.5, 1.0)

DARK_GRAY

(0.2, 0.2, 0.2, 1.0)

LIGHT_GRAY

(0.75, 0.75, 0.75, 1.0)

ORANGE

(1.0, 0.6, 0.0, 1.0)

PURPLE

(0.6, 0.2, 0.8, 1.0)

PINK

(1.0, 0.4, 0.7, 1.0)

__slots__

(‘has_alpha’,)

__set__(obj, value)[source]
static coerce(value, *, name: str = 'colour', has_alpha: bool = True) tuple[float, ...] | None[source]

Coerce a colour-ish value to a float tuple of the requested arity, or None.

Accepts:

  • None – sentinel meaning “no override, use the theme default”. Returned as None so callers can fall back to a theme-resolved colour. Raw draw callsites that cannot tolerate None must check the result and either resolve it or raise loudly.

  • tuple / list of 3 or 4 numeric components

  • a :class:Colour Property instance (uses its default tuple)

has_alpha selects the arity of the result: RGBA by default, RGB when False. An RGB input is widened with an opaque alpha, and an opaque RGBA input is narrowed by dropping it. A translucent RGBA input cannot be narrowed and raises instead.

Raises TypeError / ValueError for anything else.

static hex(h: str) tuple[float, float, float, float][source]

Parse hex colour string '#RRGGBB' / '#RRGGBBAA' into RGBA tuple.

static rgba(r: float, g: float, b: float, a: float = 1.0) tuple[float, float, float, float][source]

Create colour from float components (0.0-1.0).

static from_rgb255(r: int, g: int, b: int, a: int = 255) tuple[float, float, float, float][source]

Create colour from 0-255 integer components (alpha defaults to 255 = opaque).

Returns a canonical 0-1 RGBA float tuple. This is the designer-ergonomic entry point for callers who think in 0-255: the rest of the engine speaks float 0-1 (HDR-ready, shader-native).

storage_backed: bool

True

__new__(*args, coerce: collections.abc.Callable[[Any], Any] | None = None, **kwargs)
__set_name__(owner, name)
__get__(obj, objtype=None)
get_raw(obj)
set_raw(obj, value) None
try_decrement(obj, amount: float | int) bool
__repr__()
class simvx.core.properties.FilePath(default: str = '', *, filter: str = '*.*', relative_to: str | None = None, **kwargs)[source]

Bases: simvx.core.descriptors.Property

File / resource path property.

Example::

icon = FilePath("", filter="*.png;*.jpg")

Initialization

Create an editor-visible property descriptor.

Args: default: Default value for the property. Mutually exclusive with default_factory. Mutable containers (list, dict, set, bytearray) are rejected here because a single shared instance would alias across every owning object: pass default_factory instead. default_factory: Zero-arg callable invoked the first time each instance reads the property. The result is cached on the instance, matching functools.cached_property and dataclasses.field(default_factory=...) semantics. range: Optional (min, max) tuple for numeric values. By default (clamp=True) assignments are hard-clamped into [min, max], which doubles as input validation (audio safety, save-load sanitisation, [0,1] enforcement rely on this). With clamp=False the range is a soft hint: it sets the editor inspector field’s default bounds (which stretch to cover a value outside them), and assigned values pass through unclamped. Use clamp=False for physical magnitudes whose range is a suggestion, not a limit (e.g. particle speed in pixels/sec). enum: Optional list of allowed values. coerce: Optional single-argument callable that converts an incoming value into the form the property stores. It runs FIRST, before every other check: coerce, then scalar rejection, then range clamping, then enum membership, then the change-detection and on_change machinery. Everything downstream therefore sees the converted value. The declared default is converted once at class-definition time so reads of an unwritten property return the canonical form too (default_factory results are used verbatim). Passing an Enum type is the common case: coerce=BodyMode lets callers write mode="static" while the node stores BodyMode.STATIC, so identity comparisons downstream hold. A value the callable rejects raises ValueError naming the owning class, the property and the accepted values. A property whose default is an Enum member coerces to that member’s type without being asked, so every enum-valued property stores members rather than the bare strings or ints they wrap. Pass coerce explicitly to override that. hint: Description shown in the editor inspector. link: When True, child values are offset from the parent’s value. propagate: When True, bool/enum Settings inherit disabling values from parents. group: Inspector section name for grouping. Empty string = default “Properties” section. on_change: Name of a bound method to invoke on the owning instance after a successful value change (i.e. when the new value differs from the old). Hooks fired during __init__ are deferred until __init__ returns, then dispatched once each (deduplicated by (property, hook) pair) so the hook always sees a fully constructed object. After construction, hooks fire synchronously inside __set__ (unless coalesce=True: see below). coalesce: When True and on_change is set, post-init hook calls fire at most once per scene-tree frame. Multiple writes within one tick collapse to a single deferred call drained at the end of :meth:SceneTree.tick: useful for expensive handlers like HUD rasterisation that don’t care about intermediate values (Tower Defence: coins -= 1 repeated five times in one frame rasterised the HUD text five times). The owning object must be attached to a SceneTree (obj._tree set); for tree-less owners the flag is ignored and hooks fire synchronously. persist: When True, the value is included in SaveManager snapshots. save_version: Optional integer schema version recorded alongside the persisted value. clamp: When True (default) a numeric range hard-clamps every assignment into bounds (validation). When False the range is an editor-field hint only and out-of-range values are accepted verbatim, both on assignment and in the inspector. Has no effect when range is None. It does not relax the type: a ranged property converts its value to a builtin number and refuses NaN under either setting, because NaN is not a magnitude that a looser bound could accommodate. scalar: When True, reject array-like values (numpy ndarray with ndim >= 1, Vec2/Vec3, list, tuple, dict, set) at assignment with a clear TypeError. Plain Python numbers, numpy scalar types (np.float32, np.int64 etc.), and 0-d numpy arrays are accepted. Use for properties that semantically represent a single number (e.g. Camera2D.zoom) so a stray Vec2 doesn’t leak into downstream math and produce visual glitches.

__slots__

(‘filter’, ‘relative_to’)

__set__(obj, value)[source]
coerce: collections.abc.Callable[[Any], Any]

None

storage_backed: bool

True

__new__(*args, coerce: collections.abc.Callable[[Any], Any] | None = None, **kwargs)
__set_name__(owner, name)
__get__(obj, objtype=None)
get_raw(obj)
set_raw(obj, value) None
try_decrement(obj, amount: float | int) bool
__repr__()
class simvx.core.properties.Multiline(default: str = '', *, min_lines: int = 3, syntax: str | None = None, **kwargs)[source]

Bases: simvx.core.descriptors.Property

Multi-line string property with optional syntax hint.

When syntax='python' the editor uses its code editor widget; otherwise it uses the plain multi-line text editor.

Example::

description = Multiline("", min_lines=4)
script_body = Multiline("", syntax="python")

Initialization

Create an editor-visible property descriptor.

Args: default: Default value for the property. Mutually exclusive with default_factory. Mutable containers (list, dict, set, bytearray) are rejected here because a single shared instance would alias across every owning object: pass default_factory instead. default_factory: Zero-arg callable invoked the first time each instance reads the property. The result is cached on the instance, matching functools.cached_property and dataclasses.field(default_factory=...) semantics. range: Optional (min, max) tuple for numeric values. By default (clamp=True) assignments are hard-clamped into [min, max], which doubles as input validation (audio safety, save-load sanitisation, [0,1] enforcement rely on this). With clamp=False the range is a soft hint: it sets the editor inspector field’s default bounds (which stretch to cover a value outside them), and assigned values pass through unclamped. Use clamp=False for physical magnitudes whose range is a suggestion, not a limit (e.g. particle speed in pixels/sec). enum: Optional list of allowed values. coerce: Optional single-argument callable that converts an incoming value into the form the property stores. It runs FIRST, before every other check: coerce, then scalar rejection, then range clamping, then enum membership, then the change-detection and on_change machinery. Everything downstream therefore sees the converted value. The declared default is converted once at class-definition time so reads of an unwritten property return the canonical form too (default_factory results are used verbatim). Passing an Enum type is the common case: coerce=BodyMode lets callers write mode="static" while the node stores BodyMode.STATIC, so identity comparisons downstream hold. A value the callable rejects raises ValueError naming the owning class, the property and the accepted values. A property whose default is an Enum member coerces to that member’s type without being asked, so every enum-valued property stores members rather than the bare strings or ints they wrap. Pass coerce explicitly to override that. hint: Description shown in the editor inspector. link: When True, child values are offset from the parent’s value. propagate: When True, bool/enum Settings inherit disabling values from parents. group: Inspector section name for grouping. Empty string = default “Properties” section. on_change: Name of a bound method to invoke on the owning instance after a successful value change (i.e. when the new value differs from the old). Hooks fired during __init__ are deferred until __init__ returns, then dispatched once each (deduplicated by (property, hook) pair) so the hook always sees a fully constructed object. After construction, hooks fire synchronously inside __set__ (unless coalesce=True: see below). coalesce: When True and on_change is set, post-init hook calls fire at most once per scene-tree frame. Multiple writes within one tick collapse to a single deferred call drained at the end of :meth:SceneTree.tick: useful for expensive handlers like HUD rasterisation that don’t care about intermediate values (Tower Defence: coins -= 1 repeated five times in one frame rasterised the HUD text five times). The owning object must be attached to a SceneTree (obj._tree set); for tree-less owners the flag is ignored and hooks fire synchronously. persist: When True, the value is included in SaveManager snapshots. save_version: Optional integer schema version recorded alongside the persisted value. clamp: When True (default) a numeric range hard-clamps every assignment into bounds (validation). When False the range is an editor-field hint only and out-of-range values are accepted verbatim, both on assignment and in the inspector. Has no effect when range is None. It does not relax the type: a ranged property converts its value to a builtin number and refuses NaN under either setting, because NaN is not a magnitude that a looser bound could accommodate. scalar: When True, reject array-like values (numpy ndarray with ndim >= 1, Vec2/Vec3, list, tuple, dict, set) at assignment with a clear TypeError. Plain Python numbers, numpy scalar types (np.float32, np.int64 etc.), and 0-d numpy arrays are accepted. Use for properties that semantically represent a single number (e.g. Camera2D.zoom) so a stray Vec2 doesn’t leak into downstream math and produce visual glitches.

__slots__

(‘min_lines’, ‘syntax’)

__set__(obj, value)[source]
coerce: collections.abc.Callable[[Any], Any]

None

storage_backed: bool

True

__new__(*args, coerce: collections.abc.Callable[[Any], Any] | None = None, **kwargs)
__set_name__(owner, name)
__get__(obj, objtype=None)
get_raw(obj)
set_raw(obj, value) None
try_decrement(obj, amount: float | int) bool
__repr__()
class simvx.core.properties.Bitmask(default: int = 0, *, bits: int = 32, names: list[str] | None = None, **kwargs)[source]

Bases: simvx.core.descriptors.Property

Bit flag integer property with optional per-bit names.

Stores an ordinary int. The editor renders a grid of bits toggles arranged as bits // 8 rows of 8.

Example::

collision_layer = Bitmask(1, bits=32, group="Collision")

Initialization

Create an editor-visible property descriptor.

Args: default: Default value for the property. Mutually exclusive with default_factory. Mutable containers (list, dict, set, bytearray) are rejected here because a single shared instance would alias across every owning object: pass default_factory instead. default_factory: Zero-arg callable invoked the first time each instance reads the property. The result is cached on the instance, matching functools.cached_property and dataclasses.field(default_factory=...) semantics. range: Optional (min, max) tuple for numeric values. By default (clamp=True) assignments are hard-clamped into [min, max], which doubles as input validation (audio safety, save-load sanitisation, [0,1] enforcement rely on this). With clamp=False the range is a soft hint: it sets the editor inspector field’s default bounds (which stretch to cover a value outside them), and assigned values pass through unclamped. Use clamp=False for physical magnitudes whose range is a suggestion, not a limit (e.g. particle speed in pixels/sec). enum: Optional list of allowed values. coerce: Optional single-argument callable that converts an incoming value into the form the property stores. It runs FIRST, before every other check: coerce, then scalar rejection, then range clamping, then enum membership, then the change-detection and on_change machinery. Everything downstream therefore sees the converted value. The declared default is converted once at class-definition time so reads of an unwritten property return the canonical form too (default_factory results are used verbatim). Passing an Enum type is the common case: coerce=BodyMode lets callers write mode="static" while the node stores BodyMode.STATIC, so identity comparisons downstream hold. A value the callable rejects raises ValueError naming the owning class, the property and the accepted values. A property whose default is an Enum member coerces to that member’s type without being asked, so every enum-valued property stores members rather than the bare strings or ints they wrap. Pass coerce explicitly to override that. hint: Description shown in the editor inspector. link: When True, child values are offset from the parent’s value. propagate: When True, bool/enum Settings inherit disabling values from parents. group: Inspector section name for grouping. Empty string = default “Properties” section. on_change: Name of a bound method to invoke on the owning instance after a successful value change (i.e. when the new value differs from the old). Hooks fired during __init__ are deferred until __init__ returns, then dispatched once each (deduplicated by (property, hook) pair) so the hook always sees a fully constructed object. After construction, hooks fire synchronously inside __set__ (unless coalesce=True: see below). coalesce: When True and on_change is set, post-init hook calls fire at most once per scene-tree frame. Multiple writes within one tick collapse to a single deferred call drained at the end of :meth:SceneTree.tick: useful for expensive handlers like HUD rasterisation that don’t care about intermediate values (Tower Defence: coins -= 1 repeated five times in one frame rasterised the HUD text five times). The owning object must be attached to a SceneTree (obj._tree set); for tree-less owners the flag is ignored and hooks fire synchronously. persist: When True, the value is included in SaveManager snapshots. save_version: Optional integer schema version recorded alongside the persisted value. clamp: When True (default) a numeric range hard-clamps every assignment into bounds (validation). When False the range is an editor-field hint only and out-of-range values are accepted verbatim, both on assignment and in the inspector. Has no effect when range is None. It does not relax the type: a ranged property converts its value to a builtin number and refuses NaN under either setting, because NaN is not a magnitude that a looser bound could accommodate. scalar: When True, reject array-like values (numpy ndarray with ndim >= 1, Vec2/Vec3, list, tuple, dict, set) at assignment with a clear TypeError. Plain Python numbers, numpy scalar types (np.float32, np.int64 etc.), and 0-d numpy arrays are accepted. Use for properties that semantically represent a single number (e.g. Camera2D.zoom) so a stray Vec2 doesn’t leak into downstream math and produce visual glitches.

__slots__

(‘bits’, ‘names’)

__set__(obj, value)[source]
coerce: collections.abc.Callable[[Any], Any]

None

storage_backed: bool

True

__new__(*args, coerce: collections.abc.Callable[[Any], Any] | None = None, **kwargs)
__set_name__(owner, name)
__get__(obj, objtype=None)
get_raw(obj)
set_raw(obj, value) None
try_decrement(obj, amount: float | int) bool
__repr__()
class simvx.core.properties.NodePath(default: str = '', *, type_filter: type | None = None, **kwargs)[source]

Bases: simvx.core.descriptors.Property

Scene-relative node path property.

Stores a path string (e.g. "../Camera2D"). type_filter is an optional Node subclass used by the editor picker to grey out nodes that would be invalid targets.

Example::

remote_path = NodePath("", type_filter=Node2D)

Initialization

Create an editor-visible property descriptor.

Args: default: Default value for the property. Mutually exclusive with default_factory. Mutable containers (list, dict, set, bytearray) are rejected here because a single shared instance would alias across every owning object: pass default_factory instead. default_factory: Zero-arg callable invoked the first time each instance reads the property. The result is cached on the instance, matching functools.cached_property and dataclasses.field(default_factory=...) semantics. range: Optional (min, max) tuple for numeric values. By default (clamp=True) assignments are hard-clamped into [min, max], which doubles as input validation (audio safety, save-load sanitisation, [0,1] enforcement rely on this). With clamp=False the range is a soft hint: it sets the editor inspector field’s default bounds (which stretch to cover a value outside them), and assigned values pass through unclamped. Use clamp=False for physical magnitudes whose range is a suggestion, not a limit (e.g. particle speed in pixels/sec). enum: Optional list of allowed values. coerce: Optional single-argument callable that converts an incoming value into the form the property stores. It runs FIRST, before every other check: coerce, then scalar rejection, then range clamping, then enum membership, then the change-detection and on_change machinery. Everything downstream therefore sees the converted value. The declared default is converted once at class-definition time so reads of an unwritten property return the canonical form too (default_factory results are used verbatim). Passing an Enum type is the common case: coerce=BodyMode lets callers write mode="static" while the node stores BodyMode.STATIC, so identity comparisons downstream hold. A value the callable rejects raises ValueError naming the owning class, the property and the accepted values. A property whose default is an Enum member coerces to that member’s type without being asked, so every enum-valued property stores members rather than the bare strings or ints they wrap. Pass coerce explicitly to override that. hint: Description shown in the editor inspector. link: When True, child values are offset from the parent’s value. propagate: When True, bool/enum Settings inherit disabling values from parents. group: Inspector section name for grouping. Empty string = default “Properties” section. on_change: Name of a bound method to invoke on the owning instance after a successful value change (i.e. when the new value differs from the old). Hooks fired during __init__ are deferred until __init__ returns, then dispatched once each (deduplicated by (property, hook) pair) so the hook always sees a fully constructed object. After construction, hooks fire synchronously inside __set__ (unless coalesce=True: see below). coalesce: When True and on_change is set, post-init hook calls fire at most once per scene-tree frame. Multiple writes within one tick collapse to a single deferred call drained at the end of :meth:SceneTree.tick: useful for expensive handlers like HUD rasterisation that don’t care about intermediate values (Tower Defence: coins -= 1 repeated five times in one frame rasterised the HUD text five times). The owning object must be attached to a SceneTree (obj._tree set); for tree-less owners the flag is ignored and hooks fire synchronously. persist: When True, the value is included in SaveManager snapshots. save_version: Optional integer schema version recorded alongside the persisted value. clamp: When True (default) a numeric range hard-clamps every assignment into bounds (validation). When False the range is an editor-field hint only and out-of-range values are accepted verbatim, both on assignment and in the inspector. Has no effect when range is None. It does not relax the type: a ranged property converts its value to a builtin number and refuses NaN under either setting, because NaN is not a magnitude that a looser bound could accommodate. scalar: When True, reject array-like values (numpy ndarray with ndim >= 1, Vec2/Vec3, list, tuple, dict, set) at assignment with a clear TypeError. Plain Python numbers, numpy scalar types (np.float32, np.int64 etc.), and 0-d numpy arrays are accepted. Use for properties that semantically represent a single number (e.g. Camera2D.zoom) so a stray Vec2 doesn’t leak into downstream math and produce visual glitches.

__slots__

(‘type_filter’,)

__set__(obj, value)[source]
coerce: collections.abc.Callable[[Any], Any]

None

storage_backed: bool

True

__new__(*args, coerce: collections.abc.Callable[[Any], Any] | None = None, **kwargs)
__set_name__(owner, name)
__get__(obj, objtype=None)
get_raw(obj)
set_raw(obj, value) None
try_decrement(obj, amount: float | int) bool
__repr__()
simvx.core.properties.__all__

[‘Bitmask’, ‘Colour’, ‘FilePath’, ‘Multiline’, ‘NodePath’, ‘get_mask_bit’, ‘set_mask_bit’]