Namespace PopcorningGuineaPig.Engine.Scenes
Classes
ActionDefinition
AssetsDefinition
BindingDefinition
BindingSource
CameraDefinition
CommandDefinition
CompatibilityInfo
ConditionDefinition
ContainerElementFactory
Enhanced container factory that supports hierarchical elements
DictionaryJsonConverter
DynamicBinding
EngineSplashScreenScene
EntityDefinition
GradientStop
MappingDefinition
PgpscnJsonContext
PropertyBinder<T>
Fluent typed setter map for game-defined UI elements that want the Option B path (no reflection, strongly typed dispatch). Built on top of a Dictionary<TKey, TValue> of property-name → typed setter so each TrySet(object, string, object) call is a single hashtable lookup plus a delegate invocation.
Usage:
public sealed class MyWidget : InteractiveUIElement
{
public static readonly IPropertyBinder Binder =
new PropertyBinder<MyWidget>()
.Add("text", (w, v) => w.Text = (string)v)
.Add("score", (w, v) => w.Score = Convert.ToInt32(v));
public string Text { get; set; } = string.Empty;
public int Score { get; set; }
}
// At startup:
UIElementBinderRegistry.Register(typeof(MyWidget), MyWidget.Binder);
The PGPSCN JsonElement values that arrive at TrySet(object, string, object)
after System.Text.Json deserialization are converted to the expected
CLR type by UnwrapValue(object) (called by
the registry before dispatch), so setters receive already-unwrapped CLR
primitives (string, int, double, bool).
RangeDefinition
RelativePositionDefinition
RenderLayerDefinition
RollbackScene
Base class for scenes that support rollback netcode Extends the existing Scene architecture with rollback capabilities
RollbackSceneState
Serializable scene state for rollback
Scene
Scene3D
3D scene type that extends the base Scene with 3D-specific functionality. Contains world, camera, and 3D rendering capabilities.
SceneActionRegistry
Static lookup table that maps PGPSCN action_handler command keys to
game-supplied delegates. Exists to make PGPSCN action dispatch trim-safe:
the legacy scene_method / static_method dispatch in
SceneLoader.ExecuteCommand relied on Type.GetType and
MethodInfo.Invoke, both of which the .NET IL Trimmer cannot follow.
The registry replaces the indirection at the dispatch boundary: PGPSCN
files name a string key, game code registers a delegate for that key at
startup, and the loader does a pure dictionary lookup at runtime.
Contract: games using PGPSCN with action_handler commands must register
every key referenced by their scene files at startup (before game.RunGame()).
Unregistered keys log a diagnostic and the action becomes a no-op.
SceneData
SceneLoader
SceneMetadata
SceneTypeRegistry
Static lookup table that maps PGPSCN scene name strings to their concrete
Scene subclass Type. Exists to make
scene_transition action resolution trim-safe: the
DynamicallyAccessedMembersAttribute on the registration generic flows
through every call site, pinning the public parameterless constructor of every
registered scene class so the .NET IL Trimmer cannot strip it.
Replaces the legacy GetType(string) + assembly-walk lookup that previously lived in SceneLoader.
Contract: the engine self-registers its own built-in scenes from the
Game() base constructor (runs before the subclass ctor body, so a
subclass can QueueScene a transition immediately and still resolve).
Games using PGPSCN with scene_transition actions must register their own
Scene subclasses at startup.
SpawnPoint
TraditionalUIElementFactory
TransformDefinition
TriggerVolume
UIElementBinderRegistry
Static lookup table mapping UI element Type to an IPropertyBinder that knows how to write its bindable PGPSCN properties without runtime GetProperty(string) reflection at the dispatch site.
Replaces the legacy element.GetType().GetProperty(name).SetValue(...)
chain previously used in ApplyBinding(object, string, object, BindingDefinition) and
SceneLoader's binding setup. That chain was both:
- silently broken (most bindable fields were private — reflection returned
nulland the write skipped), and - not trim-safe (the trimmer could not prove which properties on which types remained reachable).
Two registration paths:
- Option A — RegisterReflective<T>() creates a
reflection-based binder whose
typeof(T).GetProperty(name)site is statically pinned byT's DynamicallyAccessedMembersAttribute annotation. Cheap; fine when the target type has public properties for its bindable surface. - Option B — Register(Type, IPropertyBinder) accepts a hand-authored PropertyBinder<T> with explicit setters. Zero reflection at runtime. Used for game-defined custom UI.
UIElementDefinition
UIElementFactory
WorldDefinition
Interfaces
IPropertyBinder
Trim-safe property-set adapter for a UI element type. Replaces the
runtime element.GetType().GetProperty(name).SetValue(...) chain in
the PGPSCN binding hot path with a strongly typed, allocation-free dispatch.
Two implementation paths exist:
- The engine's built-in UI elements (Button, Label, Panel, etc.) are
registered with UIElementBinderRegistry via the generic
Register<T>()overload, which produces a reflection-based binder whosetypeof(T)reflection site is[DynamicallyAccessedMembers]-pinned. - Game-defined custom UI elements implement this interface directly (typically via PropertyBinder<T>) and register with Register(Type, IPropertyBinder).
ISceneCommandHandler
Receives PGPSCN command-action side effects that are runtime-only
(scene transitions and sound playback). The runtime Game
passes its SceneManager.ChangeScene / SoundPlayer.PlaySound
here; the editor's SceneBridge passes no-op or logging stubs so the
viewport never accidentally transitions away from the scene being
previewed or pipes audio through the editor process.