Repository: League-of-Foundry-Developers/foundry-vtt-types
Pull request #3197 (2025-02-24 04:09:28)

Canvas edges and sources part 3
Types, tests, and nullability comments/link cleanup


Patch:
diff --git a/src/foundry/client-esm/canvas/edges/collision.d.mts b/src/foundry/client-esm/canvas/edges/collision.d.mts
index af96b12f6..2998516fe 100644
--- a/src/foundry/client-esm/canvas/edges/collision.d.mts
+++ b/src/foundry/client-esm/canvas/edges/collision.d.mts
@@ -7,7 +7,15 @@ import type PolygonVertex from "./vertex.d.mts";
  * This class is not designed or intended for use outside of that context.
  */
 declare class CollisionResult {
-  constructor(values?: CollisionResult.ConstructorValues);
+  constructor({
+    target,
+    collisions,
+    cwEdges,
+    ccwEdges,
+    isBehind,
+    isLimited,
+    wasLimited,
+  }?: CollisionResult.ConstructorValues);
 
   /**
    * The vertex that was the target of this result
diff --git a/src/foundry/client-esm/canvas/edges/edge.d.mts b/src/foundry/client-esm/canvas/edges/edge.d.mts
index cd9b05367..eded97719 100644
--- a/src/foundry/client-esm/canvas/edges/edge.d.mts
+++ b/src/foundry/client-esm/canvas/edges/edge.d.mts
@@ -14,6 +14,7 @@ declare class Edge {
    * @param b - The second endpoint of the edge
    * @param options - Additional options which describe the edge
    */
+  // options: not null (destructured)
   constructor(a: Canvas.Point, b: Canvas.Point, options?: Edge.ConstructorOptions);
 
   /**
@@ -103,7 +104,7 @@ declare class Edge {
    * A PolygonVertex instance.
    * Used as part of ClockwiseSweepPolygon computation.
    * @defaultValue `undefined`
-   * @remarks Only set in {@link ClockwiseSweepPolygon#_identifyVertices} (part of CSP initialization)
+   * @remarks Only set in {@link ClockwiseSweepPolygon._identifyVertices | `ClockwiseSweepPolygon#_identifyVertices`} (part of CSP initialization)
    */
   vertexA: PolygonVertex | undefined;
 
@@ -111,7 +112,7 @@ declare class Edge {
    * A PolygonVertex instance.
    * Used as part of ClockwiseSweepPolygon computation.
    * @defaultValue `undefined`
-   * @remarks Only set in {@link ClockwiseSweepPolygon#_identifyVertices} (part of CSP initialization)
+   * @remarks Only set in {@link ClockwiseSweepPolygon._identifyVertices | `ClockwiseSweepPolygon#_identifyVertices`} (part of CSP initialization)
    */
   vertexB: PolygonVertex | undefined;
 
@@ -140,7 +141,11 @@ declare class Edge {
    * @returns True if the edge has a threshold greater than 0 for the source type,
    *          and the source type is within that distance.
    */
-  applyThreshold(sourceType: Edge.AttenuationTypes, sourceOrigin: Canvas.Point, externalRadius?: number): boolean;
+  applyThreshold(
+    sourceType: Edge.AttenuationTypes,
+    sourceOrigin: Canvas.Point,
+    externalRadius?: number | null,
+  ): boolean;
 
   /**
    * Determine the orientation of this Edge with respect to a reference point.
diff --git a/src/foundry/client-esm/canvas/edges/vertex.d.mts b/src/foundry/client-esm/canvas/edges/vertex.d.mts
index 4869b91f0..dcc48e082 100644
--- a/src/foundry/client-esm/canvas/edges/vertex.d.mts
+++ b/src/foundry/client-esm/canvas/edges/vertex.d.mts
@@ -4,10 +4,9 @@ import type Edge from "./edge.d.mts";
 /**
  * A specialized point data structure used to represent vertices in the context of the ClockwiseSweepPolygon.
  * This class is not designed or intended for use outside of that context.
- * @internal
  */
 declare class PolygonVertex {
-  constructor(x: number, y: number, options?: PolygonVertex.ConstructorOptions);
+  constructor(x: number, y: number, { distance, index }?: PolygonVertex.ConstructorOptions);
 
   x: number;
 
@@ -18,7 +17,7 @@ declare class PolygonVertex {
 
   /**
    * @defaultValue `undefined`
-   * @remarks Accessed externally in {@link ClockwiseSweepPolygon#_testCollision}
+   * @remarks Accessed externally in {@link ClockwiseSweepPolygon._testCollision | `ClockwiseSweepPolygon#_testCollision`}
    */
   _distance: number | undefined | null;
 
@@ -108,10 +107,9 @@ declare class PolygonVertex {
   /**
    * Record whether this PolygonVertex has been visited in the sweep
    * @defaultValue `false`
-   * @remarks Set externally during `ClockwiseSweeepPolygon` initialization
-   * @privateRemarks Foundry marked `@internal`
+   * @remarks Foundry marked `@internal`, set externally during `ClockwiseSweepPolygon` initialization
    */
-  _visited: boolean;
+  protected _visited: boolean;
 
   /**
    * Is this vertex limited in type?
@@ -131,7 +129,10 @@ declare class PolygonVertex {
    */
   get isTerminal(): boolean;
 
-  /**declareme point?
+  /**
+   * Is this vertex the same point as some other vertex?
+   * @param other - Some other vertex
+   * @returns Are they the same point?
    */
   equals(other: PolygonVertex): boolean;
 
@@ -141,6 +142,7 @@ declare class PolygonVertex {
    * @param options - Additional options that apply to this vertex
    * @returns The constructed vertex
    */
+  // options: not null (destructured when passed to `new this()`)
   static fromPoint(point: Canvas.Point, options?: PolygonVertex.ConstructorOptions): PolygonVertex;
 }
 
diff --git a/src/foundry/client-esm/canvas/sources/base-effect-source.d.mts b/src/foundry/client-esm/canvas/sources/base-effect-source.d.mts
index 999eb7e63..5c3bf8de9 100644
--- a/src/foundry/client-esm/canvas/sources/base-effect-source.d.mts
+++ b/src/foundry/client-esm/canvas/sources/base-effect-source.d.mts
@@ -1,4 +1,4 @@
-import type { NullishProps, IntentionalPartial } from "fvtt-types/utils";
+import type { NullishProps, IntentionalPartial, AnyObject } from "fvtt-types/utils";
 
 /**
  * TODO - Re-document after ESM refactor.
@@ -23,28 +23,31 @@ declare abstract class BaseEffectSource<
    * @param options - Options which modify the base effect source instance
    * @remarks Passing a PlaceableObject is deprecated, and will be removed in v13
    */
-  constructor(options?: BaseEffectSource.SourceOptions | PlaceableObject);
+  // not null (property access)
+  constructor(options?: BaseEffectSource.ConstructorOptions | PlaceableObject);
 
   /**
    * The type of source represented by this data structure.
    * Each subclass must implement this attribute.
+   * @remarks Effectively abstract, must be defined by subclasses; `undefined` in `BaseEffectSource`
    */
-  static sourceType: string;
+  static sourceType: string | undefined;
 
   /**
    * The target collection into the effects canvas group.
+   * @remarks Foundry marked `@abstract`; Is `undefined` in `BaseEffectSource`
    */
-  static effectsCollection: string;
+  static effectsCollection: string | undefined;
 
   /**
    * Effect source default data.
    * @defaultValue
    * ```js
    * {
-   * x: 0,
-   * y: 0,
-   * elevation: 0,
-   * disabled: false
+   *   x: 0,
+   *   y: 0,
+   *   elevation: 0,
+   *   disabled: false
    * }
    * ```
    */
@@ -69,14 +72,15 @@ declare abstract class BaseEffectSource<
 
   /**
    * The geometric shape of the effect source which is generated later.
-   * @remarks This only isn't `undefined` in subclasses implementing `_createShapes()`, usually via {@link PointEffectSourceMixin}
+   * @remarks This only isn't `undefined` in subclasses implementing `_createShapes()`, usually via {@link foundry.canvas.sources.PointEffectSourceMixin | `PointEffectSourceMixin`}
    */
   shape: SourceShape | undefined;
 
   /**
    * A collection of boolean flags which control rendering and refresh behavior for the source.
+   * @defaultValue `{}`
    */
-  protected _flags: Record<string, boolean | number>;
+  protected _flags: BaseEffectSource.Flags;
 
   /**
    * The x-coordinate of the point source origin.
@@ -123,6 +127,7 @@ declare abstract class BaseEffectSource<
   /**
    * Records of suppression strings with a boolean value.
    * If any of this record is true, the source is suppressed.
+   * @defaultValue `{}`
    */
   suppression: Record<string, boolean>;
 
@@ -132,39 +137,34 @@ declare abstract class BaseEffectSource<
    * @param options - Additional options which modify source initialization
    * @returns The initialized source
    */
-  initialize(
-    data?: NullishProps<SourceData>,
-    /** @privateRemarks Foundry describes an `options.behaviors` key, but it is neither checked for nor used at runtime */
-    options?: NullishProps<{
-      /**
-       * Should source data be reset to default values before applying changes?
-       * @defaultValue `false`
-       */
-      reset: boolean;
-    }>,
-  ): this;
+  // options: not null (destructured)
+  initialize(data?: NullishProps<SourceData> | null, options?: BaseEffectSource.InitializeOptions): this;
 
   /**
    * Subclass specific data initialization steps.
    * @param data - Provided data for configuration
+   * @remarks Not actually `abstract`, but a is a no-op in `BaseEffectSource`
    */
-  _initialize(
-    /** @remarks IntentionalPartial because `this.initialize` has filtered invalid keys and replaced any nullish values before calling this */
+  protected _initialize(
+    /** @privateRemarks `IntentionalPartial` because `#initialize` has filtered invalid keys and replaced any nullish values before calling this */
     data: IntentionalPartial<SourceData>,
   ): void;
 
-  /**
-   * Create the polygon shape (or shapes) for this source using configured data.
-   */
-  protected _createShapes(): void;
+  /** Create the polygon shape (or shapes) for this source using configured data. */
+  protected abstract _createShapes(): void;
 
   /**
    * Subclass specific configuration steps. Occurs after data initialization and shape computation.
    * Only called if the source is attached and not disabled.
    * @param changes - Changes to the source data which were applied
-   * @remarks This is actually passed *flattened* partial data
+   * @remarks Not actually abstract, but is a no-op in `BaseEffectSource`
+   * @privateRemarks This is actually passed *flattened* partial data, and while we were very close to having
+   * that be a non-issue, `RenderedEffectSource`'s data's `animation` and `GlobalLightSource`'s `darkness`
+   * properties are objects, so this can't just be `IntentionalPartial<SourceData>` until we have a `Flatten<>`
+   * type.
    */
-  protected _configure(changes: IntentionalPartial<SourceData>): void;
+  // TODO: Flatten<IntentionalPartial<SourceData>>
+  protected _configure(changes: AnyObject): void;
 
   /**
    * Refresh the state and uniforms of the source.
@@ -207,7 +207,7 @@ declare abstract class BaseEffectSource<
    * @deprecated since v12, will be removed in v14
    * @remarks `"BaseEffectSource#_createShape is deprecated in favor of BaseEffectSource#_createShapes."`
    */
-  _createShape(): void;
+  protected _createShape(): void;
 
   /**
    * @deprecated since v12, will be removed in v14
@@ -217,22 +217,26 @@ declare abstract class BaseEffectSource<
 }
 
 declare namespace BaseEffectSource {
+  interface Any extends AnyBaseEffectSource {}
   type AnyConstructor = typeof AnyBaseEffectSource;
 
   /** @internal */
-  type _SourceOptions = NullishProps<{
+  type _ConstructorOptions = NullishProps<{
     /**
      * An optional PlaceableObject which is responsible for this source
+     * @remarks Only the global light source is passed the ECG
      */
-    object: PlaceableObject;
+    object: PlaceableObject.Any | EffectsCanvasGroup.Any;
   }>;
 
-  interface SourceOptions extends _SourceOptions {
+  interface ConstructorOptions extends _ConstructorOptions {
     /**
      * A unique ID for this source. This will be set automatically if an
      * object is provided, otherwise is required.
-     * @remarks The above is misleading; sourceId will *not* be inferred if you pass in `{object: PlaceableObject}`,
-     * only if you pass a `PlaceableObject` *instead* of an options object to the constructor.
+     * @remarks The above is misleading; sourceId will only be inferred if you pass a `PlaceableObject`
+     * _instead_ of an options object to the constructor (which is a deprecated path removed in v13),
+     * _not_ if you pass in `{ object: PlaceableObject }`, where you're expected to also pass `sourceId`
+     * yourself.
      */
     sourceId?: string;
   }
@@ -240,24 +244,50 @@ declare namespace BaseEffectSource {
   interface SourceData {
     /**
      * The x-coordinate of the source location
+     * @defaultValue `0`
      */
     x: number;
+
     /**
      * The y-coordinate of the source location
+     * @defaultValue `0`
      */
     y: number;
+
     /**
      * The elevation of the point source
+     * @defaultValue `0`
      */
     elevation: number;
+
     /**
      * Whether or not the source is disabled
+     * @defaultValue `false`
      */
     disabled: boolean;
   }
+
+  /** @internal */
+  type _InitializeOptions = NullishProps<{
+    /**
+     * Should source data be reset to default values before applying changes?
+     * @defaultValue `false`
+     */
+    reset: boolean;
+  }>;
+
+  /** @privateRemarks Foundry describes an `options.behaviors` key, but it is neither checked for nor used at runtime */
+  interface InitializeOptions extends _InitializeOptions {}
+
+  /** @privateRemarks The `| number` is from Foundry's typing, but core only uses boolean flags in v12.331 */
+  interface Flags extends Record<string, boolean | number> {
+    renderSoftEdges?: boolean;
+    initializedMeshes?: boolean;
+    hasColor?: boolean;
+  }
 }
 
-declare abstract class AnyBaseEffectSource extends BaseEffectSource<any, any> {
+declare abstract class AnyBaseEffectSource extends BaseEffectSource<BaseEffectSource.SourceData, PIXI.Polygon> {
   constructor(arg0: never, ...args: never[]);
 }
 
diff --git a/src/foundry/client-esm/canvas/sources/base-light-source.d.mts b/src/foundry/client-esm/canvas/sources/base-light-source.d.mts
index 25d24010d..f9ed243a2 100644
--- a/src/foundry/client-esm/canvas/sources/base-light-source.d.mts
+++ b/src/foundry/client-esm/canvas/sources/base-light-source.d.mts
@@ -1,4 +1,4 @@
-import type { InexactPartial, IntentionalPartial } from "fvtt-types/utils";
+import type { IntentionalPartial, NullishProps } from "fvtt-types/utils";
 import type RenderedEffectSource from "./rendered-effect-source.d.mts";
 
 /**
@@ -32,8 +32,8 @@ declare abstract class BaseLightSource<
 
   /**
    * The corresponding animation config.
-   * @remarks More broad than it should be to accomodate {@link foundry.canvas.sources.PointDarknessSource}
-   * TODO: Reevaluate after CONFIG has been gone over
+   * @privateRemarks Only uses `CONFIG.Canvas.lightAnimations` in `BaseLightSource`, but `PointDarknessSource`
+   * overrides to use `.darknessAnimations`, so the union type is necessary
    */
   protected static get ANIMATIONS(): typeof CONFIG.Canvas.lightAnimations | typeof CONFIG.Canvas.darknessAnimations;
 
@@ -41,18 +41,18 @@ declare abstract class BaseLightSource<
    * @defaultValue
    * ```js
    * {
-   * ...super.defaultData,
-   * priority: 0,
-   * alpha: 0.5,
-   * bright: 0,
-   * coloration: 1,
-   * contrast: 0,
-   * dim: 0,
-   * attenuation: 0.5,
-   * luminosity: 0.5,
-   * saturation: 0,
-   * shadows: 0,
-   * vision: false
+   *   ...super.defaultData,
+   *   priority: 0,
+   *   alpha: 0.5,
+   *   bright: 0,
+   *   coloration: 1,
+   *   contrast: 0,
+   *   dim: 0,
+   *   attenuation: 0.5,
+   *   luminosity: 0.5,
+   *   saturation: 0,
+   *   shadows: 0,
+   *   vision: false
    * }
    * ```
    */
@@ -63,27 +63,28 @@ declare abstract class BaseLightSource<
    */
   ratio: number;
 
-  override _initialize(data: IntentionalPartial<SourceData>): void;
+  protected override _initialize(data: IntentionalPartial<SourceData>): void;
 
-  override _updateColorationUniforms(): void;
+  protected override _updateColorationUniforms(): void;
 
-  override _updateIlluminationUniforms(): void;
+  protected override _updateIlluminationUniforms(): void;
 
-  override _updateBackgroundUniforms(): void;
+  protected override _updateBackgroundUniforms(): void;
 
-  override _updateCommonUniforms(shader: AbstractBaseShader): void;
+  protected override _updateCommonUniforms(shader: AbstractBaseShader): void;
 
-  /** @remarks This property is undocumented, and only defined during `_updateCommonUniforms` */
-  cachededAttentuation?: number;
+  /** @remarks Doesn't exist prior to initialization. Ultimately set in `_updateCommonUniforms` */
+  cachedAttenuation?: number;
 
-  /** @remarks This property is undocumented, and only defined during `_updateCommonUniforms` */
-  computedAttentuation?: number;
+  /** @remarks Doesn't exist prior to initialization. Ultimately set in `_updateCommonUniforms` */
+  computedAttenuation?: number;
 
   /**
    * An animation with flickering ratio and light intensity.
    * @param dt      - Delta time
    * @param options - Additional options which modify the torch animation
    */
+  // not null (destructured)
   animateTorch(dt: number, options?: RenderedEffectSource.AnimationFunctionOptions): void;
 
   /**
@@ -91,21 +92,13 @@ declare abstract class BaseLightSource<
    * @param dt      - Delta time
    * @param options - Additional options which modify the flame animation
    */
-  animateFlickering(
-    dt: number,
-    options?: RenderedEffectSource.AnimationFunctionOptions &
-      InexactPartial<{
-        /**
-         * Noise amplification (\>1) or dampening (\<1)
-         * @defaultValue `1`
-         */
-        amplification: number;
-      }>,
-  ): void;
+  // not null (destructured)
+  animateFlickering(dt: number, options?: BaseLightSource.AnimateFlickeringOptions): void;
 
   /**
-   * @remarks This property will be generated on any class that is `animateFlickering`'s `this` when it is called.
-   * Foundry does not document it.
+   * @remarks This property will be generated on any class that is `#animateFlickering`'s `this` when it is called.
+   * In Foundry practice this will always be a `BaseLightSource` subclass, so it's defined here. Foundry does not
+   * document it.
    */
   _noise?: SmoothNoise;
 
@@ -114,16 +107,20 @@ declare abstract class BaseLightSource<
    * @param dt      - Delta time
    * @param options - Additional options which modify the pulse animation
    */
+  // not null (destructured)
   animatePulse(dt: number, options?: RenderedEffectSource.AnimationFunctionOptions): void;
 
   /**
    * @deprecated since v12, until v14
    * @remarks "BaseLightSource#isDarkness is now obsolete. Use DarknessSource instead."
+   *
+   * Always returns `false`
    */
   get isDarkness(): boolean;
 }
 
 declare namespace BaseLightSource {
+  interface Any extends AnyBaseLightSource {}
   type AnyConstructor = typeof AnyBaseLightSource;
 
   type LightAnimationFunction = (
@@ -135,62 +132,89 @@ declare namespace BaseLightSource {
   interface SourceData extends RenderedEffectSource.SourceData {
     /**
      * An opacity for the emitted light, if any
+     * @defaultValue `0.5`
      */
     alpha: number;
 
     /**
      * The allowed radius of bright vision or illumination
+     * @defaultValue `0`
      */
     bright: number;
 
     /**
      * The coloration technique applied in the shader
+     * @defaultValue `1`
      */
     coloration: number;
 
     /**
      * The amount of contrast this light applies to the background texture
+     * @defaultValue `0`
      */
     contrast: number;
 
     /**
      * The allowed radius of dim vision or illumination
+     * @defaultValue `0`
      */
     dim: number;
 
     /**
      * Strength of the attenuation between bright, dim, and dark
+     * @defaultValue `0.5`
      */
     attenuation: number;
 
     /**
      * The luminosity applied in the shader
+     * @defaultValue `0.5`
      */
     luminosity: number;
 
     /**
      * The amount of color saturation this light applies to the background texture
+     * @defaultValue `0`
      */
     saturation: number;
 
     /**
      * The depth of shadows this light applies to the background texture
+     * @defaultValue `0`
      */
     shadows: number;
 
     /**
      * Whether or not this source provides a source of vision
+     * @defaultValue `false`
      */
     vision: boolean;
 
     /**
      * Strength of this source to beat or not negative/positive sources
+     * @defaultValue `0`
      */
     priority: number;
   }
+
+  /** @internal */
+  type _AnimateFlickeringOptions = NullishProps<{
+    /**
+     * Noise amplification (\>1) or dampening (\<1)
+     * @defaultValue `1`
+     * @remarks Parameter default only, `null` is only cast to `0`
+     */
+    amplification: number;
+  }>;
+
+  interface AnimateFlickeringOptions extends RenderedEffectSource.AnimationFunctionOptions, _AnimateFlickeringOptions {}
 }
 
-declare abstract class AnyBaseLightSource extends BaseLightSource {
+declare abstract class AnyBaseLightSource extends BaseLightSource<
+  BaseLightSource.SourceData,
+  PIXI.Polygon,
+  RenderedEffectSource.Layers
+> {
   constructor(arg0: never, ...args: never[]);
 }
 
diff --git a/src/foundry/client-esm/canvas/sources/global-light-source.d.mts b/src/foundry/client-esm/canvas/sources/global-light-source.d.mts
index f2e2c4a7e..c1cdc9211 100644
--- a/src/foundry/client-esm/canvas/sources/global-light-source.d.mts
+++ b/src/foundry/client-esm/canvas/sources/global-light-source.d.mts
@@ -1,9 +1,15 @@
+import type { FixedInstanceType } from "../../../../utils/index.d.mts";
 import type BaseLightSource from "./base-light-source.d.mts";
+import type RenderedEffectSource from "./rendered-effect-source.d.mts";
 
 /**
  * A specialized subclass of the BaseLightSource which is used to render global light source linked to the scene.
  */
-declare class GlobalLightSource extends BaseLightSource {
+declare class GlobalLightSource<
+  SourceData extends GlobalLightSource.SourceData = GlobalLightSource.SourceData,
+  SourceShape extends PIXI.Polygon = PIXI.Polygon,
+  RenderingLayers extends Record<string, RenderedEffectSource.SourceLayer> = RenderedEffectSource.Layers,
+> extends BaseLightSource<SourceData, SourceShape, RenderingLayers> {
   /** @defaultValue `"GlobalLight"` */
   static override sourceType: string;
 
@@ -14,23 +20,26 @@ declare class GlobalLightSource extends BaseLightSource {
    * @defaultValue
    * ```js
    * {
-   * ...super.defaultData,
-   * rotation: 0,
-   * angle: 360,
-   * attenuation: 0,
-   * priority: -Infinity,
-   * vision: false,
-   * walls: false,
-   * elevation: Infinity,
-   * darkness: {min: 0, max: 0}
+   *   ...super.defaultData,
+   *   rotation: 0,
+   *   angle: 360,
+   *   attenuation: 0,
+   *   priority: -Infinity,
+   *   vision: false,
+   *   walls: false,
+   *   elevation: Infinity,
+   *   darkness: {min: 0, max: 0}
    * }
    * ```
    */
-  static override defaultData: BaseLightSource.SourceData;
+  static override defaultData: GlobalLightSource.SourceData;
+
+  /** @privateRemarks This class implements `#_createShapes`, so it's shape property will 'never' be undefined (after initialization) */
+  shape: SourceShape;
 
   /**
    * Name of this global light source.
-   * @defaultValue `GlobalLightSource.sourceType`
+   * @defaultValue `this.constructor.sourceType` (`"GlobalLight"`)
    */
   name: string;
 
@@ -41,18 +50,68 @@ declare class GlobalLightSource extends BaseLightSource {
    */
   customPolygon: PIXI.Polygon | number[] | null;
 
-  override _createShapes(): void;
+  protected override _createShapes(): void;
 
-  override _initializeSoftEdges(): void;
+  protected override _initializeSoftEdges(): void;
 
-  override _updateGeometry(): void;
+  protected override _updateGeometry(): void;
 
-  override _updateCommonUniforms(shader: AbstractBaseShader): void;
+  protected override _updateCommonUniforms(shader: AbstractBaseShader): void;
 }
 
 declare namespace GlobalLightSource {
-  type Any = AnyGlobalLightSource;
+  interface Any extends AnyGlobalLightSource {}
   type AnyConstructor = typeof AnyGlobalLightSource;
+
+  /**
+   * @privateRemarks `attenuation`, `priority`, and `elevation` exist in the parent interface,
+   * but are here for defaultValue overrides
+   */
+  interface SourceData extends BaseLightSource.SourceData {
+    /** @privateRemarks Type override only, the global light is not going to use a `darknessShader` */
+    animation: RenderedEffectSource.StoredLightAnimationConfig;
+
+    /**
+     * @defaultValue `0`
+     * @remarks Seemingly unused here, since `GlobalLightSource` does not inherit from `PointEffectSourceMixin`
+     */
+    rotation: number;
+
+    /**
+     * @defaultValue `360`
+     * @remarks Seemingly unused here, since `GlobalLightSource` does not inherit from `PointEffectSourceMixin`
+     */
+    angle: number;
+
+    /** @defaultValue `0` */
+    attenuation: number;
+
+    /** @defaultValue `-Infinity` */
+    priority: number;
+
+    // `vision` override omitted as it doesn't change the default
+
+    /**
+     * @defaultValue `false`
+     * @remarks Seemingly unused here, since `GlobalLightSource` does not inherit from `PointEffectSourceMixin`
+     */
+    walls: boolean;
+
+    /** @defaultValue `Infinity` */
+    elevation: number;
+
+    /** @remarks Threshold values for what darkness level the global light should be enabled for */
+    darkness: {
+      /** @defaultValue `0` */
+      min: number;
+
+      /** @defaultValue `0` */
+      max: number;
+    };
+  }
+
+  type ConfiguredClass = CONFIG["Canvas"]["globalLightSourceClass"];
+  type ConfiguredInstance = FixedInstanceType<ConfiguredClass>;
 }
 
 declare abstract class AnyGlobalLightSource extends GlobalLightSource {
diff --git a/src/foundry/client-esm/canvas/sources/point-darkness-source.d.mts b/src/foundry/client-esm/canvas/sources/point-darkness-source.d.mts
index f46327367..f29e062af 100644
--- a/src/foundry/client-esm/canvas/sources/point-darkness-source.d.mts
+++ b/src/foundry/client-esm/canvas/sources/point-darkness-source.d.mts
@@ -1,4 +1,4 @@
-import type { IntentionalPartial } from "fvtt-types/utils";
+import type { AnyObject, FixedInstanceType, IntentionalPartial, RequiredProps } from "fvtt-types/utils";
 import type BaseLightSource from "./base-light-source.d.mts";
 import type PointEffectSourceMixin from "./point-effect-source.d.mts";
 import type RenderedEffectSource from "./rendered-effect-source.d.mts";
@@ -9,20 +9,21 @@ import type RenderedEffectSource from "./rendered-effect-source.d.mts";
 declare class PointDarknessSource<
   SourceData extends PointDarknessSource.SourceData = PointDarknessSource.SourceData,
   SourceShape extends PointSourcePolygon = PointSourcePolygon,
-> extends PointEffectSourceMixin(BaseLightSource)<SourceData, SourceShape, PointDarknessSource.Layers> {
+  RenderingLayers extends Record<string, RenderedEffectSource.SourceLayer> = PointDarknessSource.Layers,
+> extends PointEffectSourceMixin(BaseLightSource)<SourceData, SourceShape, RenderingLayers> {
   /** @defaultValue `"darknessSources"` */
   static override effectsCollection: string;
 
   /** @defaultValue `foundry.CONST.LIGHTING_LEVELS.HALFDARK` */
-  static override _dimLightingLevel: foundry.CONST.LIGHTING_LEVELS;
+  protected static override _dimLightingLevel: foundry.CONST.LIGHTING_LEVELS;
 
   /** @defaultValue `foundry.CONST.LIGHTING_LEVELS.DARKNESS` */
-  static override _brightLightingLevel: foundry.CONST.LIGHTING_LEVELS;
+  protected static override _brightLightingLevel: foundry.CONST.LIGHTING_LEVELS;
 
   /** @defaultValue `CONFIG.Canvas.darknessAnimations` */
-  static get ANIMATIONS(): typeof CONFIG.Canvas.darknessAnimations;
+  protected static get ANIMATIONS(): typeof CONFIG.Canvas.darknessAnimations;
 
-  static override get _layers(): Record<string, foundry.canvas.sources.RenderedEffectSource.LayerConfig>;
+  protected static override get _layers(): Record<string, RenderedEffectSource.LayerConfig>;
 
   /** @privateRemarks This is not in Foundry's code, but accounts for the mixin class's static property's inability to be generic */
   static override defaultData: PointDarknessSource.SourceData;
@@ -54,47 +55,63 @@ declare class PointDarknessSource<
   /**
    * A convenience accessor to the darkness layer mesh.
    */
-  get darkness(): this["layers"]["darkness"]["mesh"];
+  get darkness(): PointSourceMesh;
 
-  override _initialize(data: IntentionalPartial<SourceData>): void;
+  protected override _initialize(data: IntentionalPartial<SourceData>): void;
 
-  override _createShapes(): void;
+  protected override _createShapes(): void;
 
-  override _configure(changes: IntentionalPartial<SourceData>): void;
+  // TODO: Flatten<IntentionalPartial<SourceData>>
+  protected override _configure(changes: AnyObject): void;
 
-  override _getPolygonConfiguration(): PointSourcePolygon.Config;
+  protected override _getPolygonConfiguration(): PointDarknessSource.PolygonConfig;
 
-  override _drawMesh(layerId: string): PIXI.Mesh | null;
+  protected override _drawMesh(layerId: string): PointSourceMesh | null;
 
-  override _updateGeometry(): void;
+  protected override _updateGeometry(): void;
 
   /**
    * Update the uniforms of the shader on the darkness layer.
    */
-  _updateDarknessUniforms(): void;
+  protected _updateDarknessUniforms(): void;
 
-  override _destroy(): void;
+  protected override _destroy(): void;
 
   /**
    * @deprecated since v12, until v14
    * @remarks `"BaseLightSource#isDarkness is now obsolete. Use DarknessSource instead."`
+   *
+   * Always returns `true`
    */
-  get isDarkness(): boolean;
+  get isDarkness(): true;
 }
 
 declare namespace PointDarknessSource {
+  interface Any extends AnyPointDarknessSource {}
   type AnyConstructor = typeof AnyPointDarknessSource;
 
-  type SourceData = BaseLightSource.SourceData & PointEffectSourceMixin.SourceData;
+  interface SourceData extends BaseLightSource.SourceData, PointEffectSourceMixin.SourceData {
+    animation: RenderedEffectSource.StoredDarknessAnimationConfig;
+  }
+
+  interface PolygonConfig
+    extends RequiredProps<PointEffectSourceMixin.PolygonConfig, "useThreshold" | "includeDarkness" | "radius"> {}
 
   // Interface would require `RenderingLayers extends ... = InterfaceToObject<Layers>` in every subclass signature
   // eslint-disable-next-line @typescript-eslint/consistent-type-definitions
   type Layers = {
     darkness: RenderedEffectSource.SourceLayer;
   };
+
+  type ConfiguredClass = CONFIG["Canvas"]["darknessSourceClass"];
+  type ConfiguredInstance = FixedInstanceType<ConfiguredClass>;
 }
 
-declare abstract class AnyPointDarknessSource extends PointDarknessSource {
+declare abstract class AnyPointDarknessSource extends PointDarknessSource<
+  PointDarknessSource.SourceData,
+  PointSourcePolygon,
+  PointDarknessSource.Layers
+> {
   constructor(arg0: never, ...args: never[]);
 }
 
diff --git a/src/foundry/client-esm/canvas/sources/point-effect-source.d.mts b/src/foundry/client-esm/canvas/sources/point-effect-source.d.mts
index 5eaf888d9..26fec0ff3 100644
--- a/src/foundry/client-esm/canvas/sources/point-effect-source.d.mts
+++ b/src/foundry/client-esm/canvas/sources/point-effect-source.d.mts
@@ -1,28 +1,33 @@
-import type { Mixin, IntentionalPartial, FixedInstanceType } from "fvtt-types/utils";
+import type { Mixin, IntentionalPartial, FixedInstanceType, RequiredProps } from "fvtt-types/utils";
 import type BaseEffectSource from "./base-effect-source.d.mts";
 
 declare class PointEffectSource {
-  /** @privateRemarks All mixin classses should accept anything for its constructor. */
+  /** @privateRemarks All mixin classes should accept anything for its constructor. */
   constructor(...args: any[]);
 
   /**
    * @defaultValue
    * ```js
    * {
-   * ...super.defaultData,
-   * radius: 0,
-   * externalRadius: 0,
-   * rotation: 0,
-   * angle: 360,
-   * walls: true
+   *   ...super.defaultData,
+   *   radius: 0,
+   *   externalRadius: 0,
+   *   rotation: 0,
+   *   angle: 360,
+   *   walls: true
    * }
    * ```
-   * @privateRemarks This will only be accurate for classes extending `PointEffectSourceMixin(BaseEffectSource)`.
-   * Other subclasses must override this.
+   * @remarks This type is only accurate for classes extending `PointEffectSourceMixin(BaseEffectSource)`.
+   * Other subclasses must override.
    */
   static defaultData: PointEffectSourceMixin.MixedSourceData;
 
-  /** @privateRemarks This is not in Foundry's code, but the mixin class loses access to the type parameter that would otherwise be here */
+  /**
+   * @defaultValue `CONFIG.Canvas.polygonBackends[this.constructor.sourceType].create(origin, config)`
+   * @privateRemarks This is not in Foundry's code, but the mixin class loses access to the type parameter that would
+   * otherwise be here, and per the default above this is always a {@link PointSourcePolygon | `PointSourcePolygon`} subclass, always
+   * {@link ClockwiseSweepPolygon | `ClockwiseSweepPolygon`} in core
+   */
   shape: PointSourcePolygon;
 
   /**
@@ -30,20 +35,20 @@ declare class PointEffectSource {
    */
   get radius(): number;
 
-  _initialize(data: IntentionalPartial<PointEffectSourceMixin.MixedSourceData>): void;
+  protected _initialize(data: IntentionalPartial<PointEffectSourceMixin.MixedSourceData>): void;
 
-  _initializeSoftEdges(): void;
+  protected _initializeSoftEdges(): void;
 
   /**
    * Configure the parameters of the polygon that is generated for this source.
    */
-  protected _getPolygonConfiguration(): PointSourcePolygon.Config;
+  protected _getPolygonConfiguration(): PointEffectSourceMixin.PolygonConfig;
 
-  _createShapes(): void;
+  protected _createShapes(): void;
 
-  _drawMesh(layerId: string): PIXI.Mesh | null;
+  protected _drawMesh(layerId: string): PointSourceMesh | null;
 
-  _updateGeometry(): void;
+  protected _updateGeometry(): void;
 
   /**
    * @deprecated since v11, until v13
@@ -55,9 +60,9 @@ declare class PointEffectSource {
   /**
    * @deprecated since v11, until v13
    * @remarks `"PointEffectSource#los is deprecated in favor of PointEffectSource#shape."`
-   * @privateRemarks Actual definition is get/set
+   * @privateRemarks Actually implemented as getter/setter for deprecation warning purposes, but this causes inheritance problems with  {@link foundry.canvas.sources.PointVisionSource#los | `PointVisionSource`}
    */
-  los: PointSourcePolygon;
+  los: this["shape"];
 }
 
 /**
@@ -76,25 +81,38 @@ declare namespace PointEffectSourceMixin {
 
   type MixedSourceData = SourceData & BaseEffectSource.SourceData;
 
+  /** @remarks This mixin guarantees certain keys in the return type beyond the base required `type` */
+  interface PolygonConfig
+    extends RequiredProps<PointSourcePolygon.Config, "radius" | "externalRadius" | "angle" | "rotation" | "source"> {}
+
   interface SourceData {
     /**
      * The radius of the source
+     * @defaultValue `0`
      */
     radius: number;
+
     /**
      * A secondary radius used for limited angles
+     * @defaultValue `0`
      */
     externalRadius: number;
+
     /**
      * The angle of rotation for this point source
+     * @defaultValue `0`
      */
     rotation: number;
+
     /**
      * The angle of emission for this point source
+     * @defaultValue `360`
      */
     angle: number;
+
     /**
      * Whether or not the source is constrained by walls
+     * @defaultValue `true`
      */
     walls: boolean;
   }
diff --git a/src/foundry/client-esm/canvas/sources/point-light-source.d.mts b/src/foundry/client-esm/canvas/sources/point-light-source.d.mts
index 3334772cc..2a88313a1 100644
--- a/src/foundry/client-esm/canvas/sources/point-light-source.d.mts
+++ b/src/foundry/client-esm/canvas/sources/point-light-source.d.mts
@@ -1,6 +1,7 @@
-import type { IntentionalPartial } from "fvtt-types/utils";
+import type { AnyObject, FixedInstanceType, IntentionalPartial, RequiredProps } from "fvtt-types/utils";
 import type BaseLightSource from "./base-light-source.d.mts";
 import type PointEffectSourceMixin from "./point-effect-source.d.mts";
+import type RenderedEffectSource from "./rendered-effect-source.d.mts";
 
 /**
  * A specialized subclass of the BaseLightSource which renders a source of light as a point-based effect.
@@ -8,30 +9,36 @@ import type PointEffectSourceMixin from "./point-effect-source.d.mts";
 declare class PointLightSource<
   SourceData extends PointLightSource.SourceData = PointLightSource.SourceData,
   SourceShape extends PointSourcePolygon = PointSourcePolygon,
-> extends PointEffectSourceMixin(BaseLightSource)<SourceData, SourceShape> {
+  RenderingLayers extends Record<string, RenderedEffectSource.SourceLayer> = RenderedEffectSource.Layers,
+> extends PointEffectSourceMixin(BaseLightSource)<SourceData, SourceShape, RenderingLayers> {
   /** @defaultValue `"lightSources"` */
   static override effectsCollection: string;
 
+  /** @privateRemarks Not in Foundry code, necessary type override */
+  static override defaultData: PointLightSource.SourceData;
+
   /**
    * @privateRemarks This is not in foundry's code, but since this class (and its parent) implements `_createShapes`,
    * and we are counting what happens in `initialize` as 'the constructor', this gets to be declared never undefined.
    */
   override shape: SourceShape;
 
-  override _initialize(data: IntentionalPartial<SourceData>): void;
+  protected override _initialize(data: IntentionalPartial<SourceData>): void;
 
-  override _createShapes(): void;
+  protected override _createShapes(): void;
 
-  override _configure(changes: IntentionalPartial<SourceData>): void;
+  // TODO: Flatten<IntentionalPartial<SourceData>>
+  protected override _configure(changes: AnyObject): void;
 
-  override _getPolygonConfiguration(): PointSourcePolygon.Config;
+  protected override _getPolygonConfiguration(): PointLightSource.PolygonConfig;
 
   /**
    * Test whether this LightSource provides visibility to see a certain target object.
    * @param config - The visibility test configuration
    * @returns Is the target object visible to this source?
+   * @remarks Despite being an `={}` parameter, this will error if `config.tests` is not at least an empty array of `CanvasVisibility.Test`s
    */
-  testVisibility(config?: CanvasVisibility.TestConfig): boolean;
+  testVisibility(config: CanvasVisibility.TestConfig): boolean;
 
   /**
    * Can this LightSource theoretically detect a certain object based on its properties?
@@ -39,17 +46,38 @@ declare class PointLightSource<
    * @param target - The target object being tested
    * @returns Can the target object theoretically be detected by this vision source?
    */
-  _canDetectObject(target?: PlaceableObject | null): boolean;
+  protected _canDetectObject(target?: PlaceableObject.Any | null): boolean;
+
+  /**
+   * @deprecated since v12, until v14
+   * @remarks `"BaseLightSource#isDarkness is now obsolete. Use DarknessSource instead."`
+   *
+   * Always returns `false`
+   * @privateRemarks This isn't actually overridden here, `BaseLightSource#isDarkness` always returns false, but it's type as `boolean` there to allow `PointDarknessSource#isDarkness` to return true.
+   */
+  get isDarkness(): false;
 }
 
 declare namespace PointLightSource {
   interface Any extends AnyPointLightSource {}
   type AnyConstructor = typeof AnyPointLightSource;
 
-  type SourceData = PointEffectSourceMixin.SourceData & BaseLightSource.SourceData;
+  interface SourceData extends PointEffectSourceMixin.SourceData, BaseLightSource.SourceData {
+    animation: RenderedEffectSource.StoredLightAnimationConfig;
+  }
+
+  interface PolygonConfig
+    extends RequiredProps<PointEffectSourceMixin.PolygonConfig, "useThreshold" | "includeDarkness"> {}
+
+  type ConfiguredClass = CONFIG["Canvas"]["lightSourceClass"];
+  type ConfiguredInstance = FixedInstanceType<ConfiguredClass>;
 }
 
-declare abstract class AnyPointLightSource extends PointLightSource<PointLightSource.SourceData, PointSourcePolygon> {
+declare abstract class AnyPointLightSource extends PointLightSource<
+  PointLightSource.SourceData,
+  PointSourcePolygon,
+  RenderedEffectSource.Layers
+> {
   constructor(arg0: never, ...args: never[]);
 }
 
diff --git a/src/foundry/client-esm/canvas/sources/point-movement-source.d.mts b/src/foundry/client-esm/canvas/sources/point-movement-source.d.mts
index 0bd9111b2..3d1c749d4 100644
--- a/src/foundry/client-esm/canvas/sources/point-movement-source.d.mts
+++ b/src/foundry/client-esm/canvas/sources/point-movement-source.d.mts
@@ -11,6 +11,9 @@ declare class PointMovementSource<
   /** @defaultValue `"move"` */
   static override sourceType: string;
 
+  /** @privateRemarks Not in Foundry code, necessary type override */
+  static override defaultData: PointMovementSource.SourceData;
+
   /**
    * @privateRemarks This is not in foundry's code, but since this class (and its parent) implements `_createShapes`,
    * and we are counting what happens in `initialize` as 'the constructor', this gets to be declared never undefined.
@@ -19,12 +22,19 @@ declare class PointMovementSource<
 }
 
 declare namespace PointMovementSource {
+  interface Any extends AnyPointMovementSource {}
   type AnyConstructor = typeof AnyPointMovementSource;
 
-  type SourceData = PointEffectSourceMixin.MixedSourceData;
+  interface SourceData extends PointEffectSourceMixin.MixedSourceData {}
+
+  // This is the only core Point*Source class that isn't configurable, `Token##getMovementSource`
+  // references this class directly, not a `CONFIG` property
 }
 
-declare abstract class AnyPointMovementSource extends PointMovementSource {
+declare abstract class AnyPointMovementSource extends PointMovementSource<
+  PointMovementSource.SourceData,
+  PointSourcePolygon
+> {
   constructor(arg0: never, ...args: never[]);
 }
 
diff --git a/src/foundry/client-esm/canvas/sources/point-sound-source.d.mts b/src/foundry/client-esm/canvas/sources/point-sound-source.d.mts
index dfdb84dfc..152c45f70 100644
--- a/src/foundry/client-esm/canvas/sources/point-sound-source.d.mts
+++ b/src/foundry/client-esm/canvas/sources/point-sound-source.d.mts
@@ -1,4 +1,4 @@
-import type { FixedInstanceType, NullishProps } from "fvtt-types/utils";
+import type { FixedInstanceType, NullishProps, RequiredProps } from "fvtt-types/utils";
 import type BaseEffectSource from "./base-effect-source.d.mts";
 import type PointEffectSourceMixin from "./point-effect-source.d.mts";
 
@@ -12,15 +12,18 @@ declare class PointSoundSource<
   /** @defaultValue `"sound"` */
   static override sourceType: string;
 
+  /** @privateRemarks Not in Foundry code, necessary type override */
+  static override defaultData: PointSoundSource.SourceData;
+
   /**
    * @privateRemarks This is not in foundry's code, but since this class (and its parent) implements `_createShapes`,
    * and we are counting what happens in `initialize` as 'the constructor', this gets to be declared never undefined.
    */
   override shape: SourceShape;
 
-  override get effectsCollection(): Collection<this>;
+  override get effectsCollection(): foundry.utils.Collection<this>;
 
-  override _getPolygonConfiguration(): PointSourcePolygon.Config;
+  override _getPolygonConfiguration(): PointSoundSource.PolygonConfig;
 
   /**
    * Get the effective volume at which an AmbientSound source should be played for a certain listener.
@@ -44,13 +47,15 @@ declare namespace PointSoundSource {
 
   interface GetVolumeMultiplierOptions extends _GetVolumeMultiplierOptions {}
 
-  type SourceData = PointEffectSourceMixin.MixedSourceData;
+  interface SourceData extends PointEffectSourceMixin.MixedSourceData {}
+
+  interface PolygonConfig extends RequiredProps<PointEffectSourceMixin.PolygonConfig, "useThreshold"> {}
 
   type ConfiguredClass = CONFIG["Canvas"]["soundSourceClass"];
   type ConfiguredInstance = FixedInstanceType<ConfiguredClass>;
 }
 
-declare abstract class AnyPointSoundSource extends PointSoundSource {
+declare abstract class AnyPointSoundSource extends PointSoundSource<PointSoundSource.SourceData, PointSourcePolygon> {
   constructor(arg0: never, ...args: never[]);
 }
 
diff --git a/src/foundry/client-esm/canvas/sources/point-vision-source.d.mts b/src/foundry/client-esm/canvas/sources/point-vision-source.d.mts
index db278c2a3..637c5e314 100644
--- a/src/foundry/client-esm/canvas/sources/point-vision-source.d.mts
+++ b/src/foundry/client-esm/canvas/sources/point-vision-source.d.mts
@@ -1,6 +1,6 @@
 import type RenderedEffectSource from "./rendered-effect-source.d.mts";
 import type PointEffectSourceMixin from "./point-effect-source.d.mts";
-import type { IntentionalPartial } from "fvtt-types/utils";
+import type { AnyObject, FixedInstanceType, IntentionalPartial, RequiredProps } from "fvtt-types/utils";
 
 /**
  * A specialized subclass of RenderedEffectSource which represents a source of point-based vision.
@@ -14,10 +14,10 @@ declare class PointVisionSource<
   static override sourceType: string;
 
   /** @defaultValue `["visionMode", "blinded"]` */
-  static override _initializeShaderKeys: string[];
+  protected static override _initializeShaderKeys: string[];
 
   /** @defaultValue `["radius", "color", "attenuation", "brightness", "contrast", "saturation", "visionMode"]` */
-  static override _refreshUniformsKeys: string[];
+  protected static override _refreshUniformsKeys: string[];
 
   /**
    * The corresponding lighting levels for dim light.
@@ -40,46 +40,53 @@ declare class PointVisionSource<
    * @defaultValue
    * ```js
    * {
-   * ...super.defaultData,
-   * contrast: 0,
-   * attenuation: 0.5,
-   * saturation: 0,
-   * brightness: 0,
-   * visionMode: "basic",
-   * lightRadius: null
+   *   ...super.defaultData,
+   *   contrast: 0,
+   *   attenuation: 0.5,
+   *   saturation: 0,
+   *   brightness: 0,
+   *   visionMode: "basic",
+   *   lightRadius: null
    * }
    * ```
    */
   static override defaultData: PointVisionSource.SourceData;
 
   /** @remarks Overrides `Adaptive*Shader` references with `*VisionShader` ones */
-  static get _layers(): Record<string, RenderedEffectSource.LayerConfig>;
+  protected static get _layers(): Record<string, RenderedEffectSource.LayerConfig>;
 
   /**
    * The vision mode linked to this VisionSource
+   * @remarks Foundry types this as `| null`, and initializes to `= null` in the class body,
+   * but then sets it to `CONFIG.Canvas.visionModes[this.data.visionMode]` during actual
+   * initialization, so it'll either be a defined `VisionMode` or `undefined`
    */
-  visionMode: VisionMode | null;
+  visionMode: VisionMode | undefined;
 
   /**
    * The vision mode activation flag for handlers
-   * @internal
+   * @remarks Foundry marked `@internal`.
+   *
+   * Read and set externally in {@link VisionMode.activate | `VisionMode#activate`} and {@link VisionMode.deactivate | `VisionMode#deactivate`}
    */
-  _visionModeActivated: boolean;
+  protected _visionModeActivated: boolean;
 
   /**
    * The unconstrained LOS polygon.
+   * @remarks Initialization includes `this.los = this.shape` in `#_createShapes()`
    */
-  los: PointSourcePolygon;
+  los: SourceShape;
 
   /**
    * The polygon of light perception.
+   * @remarks Initialization includes `this.light = this._createLightPolygon()` in `#_createShapes()`
    */
-  light: PointSourcePolygon;
+  light: SourceShape;
 
   /**
    * An alias for the shape of the vision source.
    */
-  get fov(): PIXI.Polygon | PointSourcePolygon;
+  get fov(): SourceShape;
 
   /**
    * If this vision source background is rendered into the lighting container.
@@ -107,27 +114,29 @@ declare class PointVisionSource<
    * Records of blinding strings with a boolean value.
    * By default, if any of this record is true, the source is blinded.
    */
-  blinded: Record<string, boolean>;
+  blinded: PointVisionSource.BlindedReasons;
 
   /**
    * Data overrides that could happen with blindness vision mode.
+   * @remarks Initialized in the class to `{}`, but filled in during actual initialization (`#_updateVisionMode` via `#_createShapes`)
    */
-  visionModeOverrides: object;
+  visionModeOverrides: PointVisionSource.VisionModeOverrides;
 
-  override _initialize(data: IntentionalPartial<SourceData>): void;
+  protected override _initialize(data: IntentionalPartial<SourceData>): void;
 
-  override _createShapes(): void;
+  protected override _createShapes(): void;
 
   /**
    * Responsible for assigning the Vision Mode and calling the activation and deactivation handlers.
    */
   protected _updateVisionMode(): void;
 
-  override _configure(changes: IntentionalPartial<SourceData>): void;
+  // TODO: Flatten<IntentionalPartial<SourceData>>
+  protected override _configure(changes: AnyObject): void;
 
-  override _configureLayer(layer: RenderedEffectSource.SourceLayer, layerId: string): void;
+  protected override _configureLayer(layer: RenderedEffectSource.SourceLayer, layerId: string): void;
 
-  override _getPolygonConfiguration(): PointSourcePolygon.Config;
+  protected override _getPolygonConfiguration(): PointVisionSource.PolygonConfig;
 
   /**
    * Creates the polygon that represents light perception.
@@ -135,7 +144,7 @@ declare class PointVisionSource<
    * instead the LOS polygon of this vision source is returned.
    * @returns The new polygon or `this.los`.
    */
-  protected _createLightPolygon(): PointSourcePolygon;
+  protected _createLightPolygon(): SourceShape;
 
   /**
    * Create a restricted FOV polygon by limiting the radius of the unrestricted LOS polygon.
@@ -143,59 +152,71 @@ declare class PointVisionSource<
    * instead the LOS polygon of this vision source is returned.
    * @returns The new polygon or `this.los`.
    */
-  protected _createRestrictedPolygon(): PointSourcePolygon;
+  protected _createRestrictedPolygon(): SourceShape;
 
-  override _configureShaders(): Record<keyof RenderingLayers, typeof AdaptiveVisionShader>;
+  protected override _configureShaders(): Record<keyof RenderingLayers, AdaptiveVisionShader.AnyConstructor>;
 
-  override _updateColorationUniforms(): void;
+  protected override _updateColorationUniforms(): void;
 
-  override _updateIlluminationUniforms(): void;
+  protected override _updateIlluminationUniforms(): void;
 
-  override _updateBackgroundUniforms(): void;
+  protected override _updateBackgroundUniforms(): void;
 
-  override _updateCommonUniforms(shader: AbstractBaseShader): void;
+  protected override _updateCommonUniforms(shader: AbstractBaseShader): void;
 
   /**
    * Update layer uniforms according to vision mode uniforms, if any.
    * @param shader     - The shader being updated.
    * @param vmUniforms - The targeted layer.
    */
-  protected _updateVisionModeUniforms(shader: AdaptiveVisionShader, vmUniforms: AbstractBaseShader.Uniforms): void;
+  protected _updateVisionModeUniforms(
+    shader: AdaptiveVisionShader,
+    vmUniforms: Array<[string, AbstractBaseShader.UniformValue]>,
+  ): void;
 }
 
 declare namespace PointVisionSource {
-  type Any = PointVisionSource<SourceData>;
-
+  interface Any extends AnyPointVisionSource {}
   type AnyConstructor = typeof AnyPointVisionSource;
 
   interface SourceData extends RenderedEffectSource.SourceData, PointEffectSourceMixin.SourceData {
     /**
      * The amount of contrast
+     * @defaultValue `0`
      */
     contrast: number;
 
     /**
      * Strength of the attenuation between bright, dim, and dark
+     * @defaultValue `0.5`
      */
     attenuation: number;
 
     /**
      * The amount of color saturation
+     * @defaultValue `0`
      */
     saturation: number;
 
     /**
-     * The vision brightness.
+     * The vision brightness
+     * @defaultValue `0`.
      */
     brightness: number;
 
     /**
      * The vision mode.
+     * @defaultValue `"basic"`
      */
-    visionMode: string;
+    visionMode: VisionMode.ConfiguredModes;
 
     /**
      * The range of light perception.
+     * @defaultValue `null`
+     * @remarks `null` is treated as `0` for `get LightRadius()` purposes, and while this
+     * will be `null` in `.defaultData`, `PointVisionSource#_initialize` will replace it
+     * with `Math.max(canvas.dimensions.maxR, this.data.externalRadius)` if it's not
+     * otherwise specified
      */
     lightRadius: number | null;
 
@@ -204,9 +225,33 @@ declare namespace PointVisionSource {
      */
     blinded: boolean;
   }
+
+  /** @privateRemarks Foundry types the property this is for as just `object` */
+  interface VisionModeOverrides {
+    colorRGB: Color.RGBColorVector | null;
+    brightness: number;
+    contrast: number;
+    saturation: number;
+    attenuation: number;
+  }
+
+  /** @privateRemarks Foundry types this as just the Record, but only ever checks the one key */
+  interface BlindedReasons extends Record<string, boolean> {
+    darkness?: boolean;
+  }
+
+  interface PolygonConfig
+    extends RequiredProps<PointEffectSourceMixin.PolygonConfig, "radius" | "useThreshold" | "includeDarkness"> {}
+
+  type ConfiguredClass = CONFIG["Canvas"]["visionSourceClass"];
+  type ConfiguredInstance = FixedInstanceType<ConfiguredClass>;
 }
 
-declare abstract class AnyPointVisionSource extends PointVisionSource {
+declare abstract class AnyPointVisionSource extends PointVisionSource<
+  PointVisionSource.SourceData,
+  PointSourcePolygon,
+  RenderedEffectSource.Layers
+> {
   constructor(arg0: never, ...args: never[]);
 }
 
diff --git a/src/foundry/client-esm/canvas/sources/rendered-effect-source.d.mts b/src/foundry/client-esm/canvas/sources/rendered-effect-source.d.mts
index 9b57d143a..94f44cfd3 100644
--- a/src/foundry/client-esm/canvas/sources/rendered-effect-source.d.mts
+++ b/src/foundry/client-esm/canvas/sources/rendered-effect-source.d.mts
@@ -1,17 +1,20 @@
-import type { InexactPartial, IntentionalPartial } from "fvtt-types/utils";
+import type { AnyObject, InexactPartial, IntentionalPartial, NullishProps } from "fvtt-types/utils";
 import type BaseEffectSource from "./base-effect-source.d.mts";
+import type BaseLightSource from "./base-light-source.d.mts";
 
 /**
  * An abstract class which extends the base PointSource to provide common functionality for rendering.
  * This class is extended by both the LightSource and VisionSource subclasses.
  */
-declare class RenderedEffectSource<
+declare abstract class RenderedEffectSource<
   SourceData extends RenderedEffectSource.SourceData = RenderedEffectSource.SourceData,
   SourceShape extends PIXI.Polygon = PIXI.Polygon,
   RenderingLayers extends Record<string, RenderedEffectSource.SourceLayer> = RenderedEffectSource.Layers,
 > extends BaseEffectSource<SourceData, SourceShape> {
   /**
    * Keys of the data object which require shaders to be re-initialized.
+   * @privateRemarks Presumably, allowing this to contain `"animation.type"` in `BaseLightSource` is why
+   * `#_configure` is passed flattened data
    */
   protected static _initializeShaderKeys: string[];
 
@@ -36,11 +39,11 @@ declare class RenderedEffectSource<
    * @defaultValue
    * ```js
    * {
-   * ...super.defaultData,
-   * animation: {},
-   * seed: null,
-   * preview: false,
-   * color: null
+   *   ...super.defaultData,
+   *   animation: {},
+   *   seed: null,
+   *   preview: false,
+   *   color: null
    * }
    * ```
    */
@@ -50,7 +53,7 @@ declare class RenderedEffectSource<
    * The animation configuration applied to this source
    * @defaultValue `{}`
    */
-  animation: RenderedEffectSource.AnimationConfig;
+  animation: RenderedEffectSource.StoredAnimationConfig;
 
   /**
    * Track the status of rendering layers
@@ -60,7 +63,7 @@ declare class RenderedEffectSource<
   /**
    * The color of the source as an RGB vector.
    */
-  colorRGB: [number, number, number] | null;
+  colorRGB: Color.RGBColorVector | null;
 
   /**
    * PIXI Geometry generated to draw meshes.
@@ -97,23 +100,25 @@ declare class RenderedEffectSource<
    */
   get illumination(): PointSourceMesh;
 
-  override _initialize(data: IntentionalPartial<SourceData>): void;
+  protected override _initialize(data: IntentionalPartial<SourceData>): void;
 
   /**
    * Decide whether to render soft edges with a blur.
    */
   protected _initializeSoftEdges(): void;
 
-  override _configure(changes: IntentionalPartial<SourceData>): void;
+  // TODO: Flatten<IntentionalPartial<SourceData>>
+  protected override _configure(changes: AnyObject): void;
 
   /**
    * Configure which shaders are used for each rendered layer.
    * @privateRemarks Foundry marks this as private then overrides it in `PointVisionSource`
    */
-  protected _configureShaders(): Record<keyof RenderingLayers, typeof AdaptiveLightingShader>;
+  protected _configureShaders(): Record<keyof RenderingLayers, AdaptiveLightingShader.AnyConstructor>;
 
   /**
    * Specific configuration for a layer.
+   * @remarks Is a no-op in `RenderedEffectSource`
    */
   protected _configureLayer(layer: RenderedEffectSource.SourceLayer, layerId: string): void;
 
@@ -126,15 +131,16 @@ declare class RenderedEffectSource<
 
   /**
    * Render the containers used to represent this light source within the LightingLayer
+   * @remarks Will error if called prior to initialization
    */
-  drawMeshes(): Record<keyof RenderingLayers, PIXI.Mesh | null>;
+  drawMeshes(): Record<keyof RenderingLayers, PointSourceMesh | null>;
 
   /**
    * Create a Mesh for a certain rendered layer of this source.
    * @param layerId - The layer key in layers to draw
    * @returns The drawn mesh for this layer, or null if no mesh is required
    */
-  protected _drawMesh(layerId: string): PIXI.Mesh | null;
+  protected _drawMesh(layerId: string): PointSourceMesh | null;
 
   /**
    * Update shader uniforms used by every rendered layer.
@@ -161,8 +167,8 @@ declare class RenderedEffectSource<
   /**
    * Animate the PointSource, if an animation is enabled and if it currently has rendered containers.
    * @param dt - Delta time.
-   * @privateRemarks In core this will return `void`, as the `this.animation.animation` function will  be a {@link BaseLightSource.LightAnimationFunction}
-   * and in fact most of the time will be `RenderedEffectSource#animateTime`, but it could technically be set to any function
+   * @privateRemarks In core this will return `void`, as the `this.animation.animation` function will  be a {@link foundry.canvas.sources.BaseLightSource.LightAnimationFunction | `LightAnimationFunction`}
+   * and in fact most of the time will be {@link foundry.canvas.sources.RenderedEffectSource.animateTime | `RenderedEffectSource#animateTime`}, but it could technically be set to any function
    */
   animate(dt: number): this["animation"]["animation"] extends (...args: infer _1) => infer Return ? Return : void;
 
@@ -177,7 +183,7 @@ declare class RenderedEffectSource<
    * Get corrected level according to level and active vision mode data.
    * @returns The corrected level.
    */
-  static getCorrectedLevel(level: foundry.CONST.LIGHTING_LEVELS): number;
+  static getCorrectedLevel(level: foundry.CONST.LIGHTING_LEVELS): foundry.CONST.LIGHTING_LEVELS;
 
   /**
    * Get corrected color according to level, dim color, bright color and background color.
@@ -186,7 +192,7 @@ declare class RenderedEffectSource<
     level: foundry.CONST.LIGHTING_LEVELS,
     colorDim: Color,
     colorBright: Color,
-    colorBackground?: Color,
+    colorBackground?: Color | null,
   ): Color;
 
   /**
@@ -203,28 +209,37 @@ declare class RenderedEffectSource<
 }
 
 declare namespace RenderedEffectSource {
-  type Any = RenderedEffectSource<any, any, any>;
-
+  interface Any extends AnyRenderedEffectSource {}
   type AnyConstructor = typeof AnyRenderedEffectSource;
 
   interface SourceData extends BaseEffectSource.SourceData {
     /**
      * An animation configuration for the source
+     * @defaultValue `{}`
      */
-    animation: object;
+    animation: StoredAnimationConfig;
 
     /**
      * A color applied to the rendered effect
+     * @defaultValue `null`
+     * @remarks Foundry types as `number`, but it gets passed to `Color.from()`
+     *
+     * If `null`, Foundry will use the associated shader's `.defaultUniforms.color`
      */
-    color: number | null;
+    color: Color.Source | null;
 
     /**
      * An integer seed to synchronize (or de-synchronize) animations
+     * @defaultValue `null`
+     * @remarks This will remain null in `#data` if not specified, which will lead to `Math.floor(Math.random() * 100000)`
+     *
+     * If specified, takes precedence over `RenderedEffectSource#animation.seed`
      */
     seed: number | null;
 
     /**
      * Is this source a temporary preview?
+     * @defaultValue `false`
      */
     preview: boolean;
   }
@@ -241,14 +256,14 @@ declare namespace RenderedEffectSource {
     /**
      * The animation speed, from 0 to 10
      * @defaultValue `5`
-     * @remarks Can't be null due to only having default via signature
+     * @remarks Can't be `null` as it only has a parameter default
      */
     speed: number;
 
     /**
      * The animation intensity, from 1 to 10
      * @defaultValue `5`
-     * @remarks Can't be null due to only having default via signature
+     * @remarks Can't be `null` as it only has a parameter default
      */
     intensity: number;
 
@@ -259,52 +274,107 @@ declare namespace RenderedEffectSource {
     reverse: boolean | null;
   }>;
 
-  /** Shared options for the {@link AnimationFunction}s provided by `_Source` classes */
+  /** Shared options for the {@link RenderedEffectSource.AnimationFunction | `AnimationFunction`}s provided by {@link foundry.canvas.sources.RenderedEffectSource | `RenderedEffectSource`} and subclasses */
   interface AnimationFunctionOptions extends _AnimationFunctionOptions {}
 
-  type AnimationConfig = InexactPartial<{
+  /**
+   * Properties *every* core-provided config has
+   * @internal
+   */
+  interface _AnimationConfigBase {
     /**
      * The human-readable (localized) label for the animation
+     * @remarks Despite the above, all of the core-provided configs provide a localization
+     * key here, not localized text.
      */
     label: string;
 
     /**
      * The animation function that runs every frame
-     * @privateRemarks TODO: Figure out if there's a better way to define the function
+     * @privateRemarks Eventually called with `animation?.call()`, but at no point is a default provided,
+     * and not having one is nonsensical.
+     */
+    animation: AnimationFunction | BaseLightSource.LightAnimationFunction;
+  }
+
+  /** @internal */
+  type _Seed = NullishProps<{
+    /**
+     * The animation seed
+     * @defaultValue `Math.floor(Math.random() * 100000)`
+     * @remarks No Foundry-provided config specifies this, but it would be respected if set
      */
-    animation: RenderedEffectSource.AnimationFunction;
+    seed: number;
+  }>;
 
+  /**
+   * Each Foundry-provided entry in `CONFIG.Canvas.lightAnimations` provides at least a `colorationShader`,
+   * but any properties not provided will be backfilled by `|| this.layers[layer].defaultShader`
+   * @internal
+   */
+  type _AnimationConfigLightingShaders = NullishProps<{
     /**
      * A custom illumination shader used by this animation
+     * @defaultValue `AdaptiveIlluminationShader`
      */
-    illuminationShader: typeof AdaptiveIlluminationShader;
+    illuminationShader: AdaptiveIlluminationShader.AnyConstructor;
 
     /**
      * A custom coloration shader used by this animation
+     * @defaultValue `AdaptiveColorationShader`
      */
-    colorationShader: typeof AdaptiveColorationShader;
+    colorationShader: AdaptiveColorationShader.AnyConstructor;
 
     /**
      * A custom background shader used by this animation
+     * @defaultValue `AdaptiveBackgroundShader`
      */
-    backgroundShader: typeof AdaptiveBackgroundShader;
+    backgroundShader: AdaptiveBackgroundShader.AnyConstructor;
+  }> & { darknessShader?: never };
 
+  /**
+   * Foundry's typedef lists `darknessShader` as required, and every core-provided config
+   * has one specified, but it has a default just like the lighting shaders
+   * @internal
+   */
+  interface _AnimationConfigDarknessShaders {
     /**
      * A custom darkness shader used by this animation
+     * @defaultValue `AdaptiveDarknessShader`
      */
-    darknessShader: typeof AdaptiveDarknessShader;
+    darknessShader: AdaptiveDarknessShader.AnyConstructor;
 
-    /**
-     * The animation seed
-     */
-    seed: number;
+    illuminationShader?: never;
+    colorationShader?: never;
+    backgroundShader?: never;
+  }
 
+  /**
+   * `this.animation.time` always gets set by `RenderedEffectSource#animateTime`,
+   * which all animation functions end up calling
+   * @internal
+   */
+  type _AnimationConfigComputed = InexactPartial<{
     /**
      * The animation time
+     * @remarks Always computed, never specified in `CONFIG`
      */
     time: number;
   }>;
 
+  interface LightAnimationConfig extends _AnimationConfigBase, _Seed, _AnimationConfigLightingShaders {}
+
+  interface StoredLightAnimationConfig extends IntentionalPartial<LightAnimationConfig>, _AnimationConfigComputed {}
+
+  interface DarknessAnimationConfig extends _AnimationConfigBase, _Seed, _AnimationConfigDarknessShaders {}
+
+  interface StoredDarknessAnimationConfig
+    extends IntentionalPartial<DarknessAnimationConfig>,
+      _AnimationConfigComputed {}
+
+  type AnimationConfig = LightAnimationConfig | DarknessAnimationConfig;
+
+  type StoredAnimationConfig = StoredLightAnimationConfig | StoredDarknessAnimationConfig;
   /**
    * @remarks The properties `mesh` and `shader` from `LayerConfig` are not documented as being part of the typedef. They are given values
    * during initialization *if* the Source has a valid `Placeable` as its `object`. `vmUniforms` is only provided a value for `PointVisionSource` layers.
@@ -335,7 +405,7 @@ declare namespace RenderedEffectSource {
      */
     shader: AdaptiveLightingShader | undefined;
 
-    /** @remarks Foundry does not include this in the typedef but is in the initalization of `RenderedEffectSource#layers` */
+    /** @remarks Foundry does not include this in the typedef but is in the initialization of `RenderedEffectSource#layers` */
     vmUniforms: AbstractBaseShader.Uniforms | undefined;
   }
 
@@ -343,7 +413,7 @@ declare namespace RenderedEffectSource {
     /**
      * The default shader used by this layer
      */
-    defaultShader: typeof AdaptiveLightingShader;
+    defaultShader: AdaptiveLightingShader.AnyConstructor;
 
     /**
      * The blend mode used by this layer
@@ -360,7 +430,11 @@ declare namespace RenderedEffectSource {
   };
 }
 
-declare abstract class AnyRenderedEffectSource extends RenderedEffectSource<any, any, any> {
+declare abstract class AnyRenderedEffectSource extends RenderedEffectSource<
+  RenderedEffectSource.SourceData,
+  PIXI.Polygon,
+  RenderedEffectSource.Layers
+> {
   constructor(arg0: never, ...args: never[]);
 }
 
diff --git a/src/foundry/client/config.d.mts b/src/foundry/client/config.d.mts
index 45e78ad2a..0205326bf 100644
--- a/src/foundry/client/config.d.mts
+++ b/src/foundry/client/config.d.mts
@@ -2,6 +2,7 @@ import type * as CONST from "../common/constants.d.mts";
 import type { DataModel, Document } from "../common/abstract/module.d.mts";
 import type { GetKey, AnyObject, HandleEmptyObject, MaybePromise } from "fvtt-types/utils";
 import type BaseLightSource from "../client-esm/canvas/sources/base-light-source.d.mts";
+import type RenderedEffectSource from "../client-esm/canvas/sources/rendered-effect-source.d.mts";
 
 declare global {
   namespace CONFIG {
@@ -961,15 +962,35 @@ declare global {
       /** @defaultValue `10000` */
       daylightToDarknessAnimationMS: number;
 
-      darknessSourceClass: foundry.canvas.sources.PointDarknessSource.AnyConstructor;
+      /**
+       * @defaultValue `foundry.canvas.sources.PointDarknessSource`
+       * @remarks Can't be `AnyConstructor` as it's instantiated expecting a compatible constructor
+       */
+      darknessSourceClass: typeof foundry.canvas.sources.PointDarknessSource;
 
-      lightSourceClass: foundry.canvas.sources.PointLightSource.AnyConstructor;
+      /**
+       * @defaultValue `foundry.canvas.sources.PointLightSource`
+       * @remarks Can't be `AnyConstructor` as it's instantiated expecting a compatible constructor
+       */
+      lightSourceClass: typeof foundry.canvas.sources.PointLightSource;
 
-      globalLightSourceClass: foundry.canvas.sources.GlobalLightSource.AnyConstructor;
+      /**
+       * @defaultValue `foundry.canvas.sources.GlobalLightSource`
+       * @remarks Can't be `AnyConstructor` as it's instantiated expecting a compatible constructor
+       */
+      globalLightSourceClass: typeof foundry.canvas.sources.GlobalLightSource;
 
-      visionSourceClass: foundry.canvas.sources.PointVisionSource.AnyConstructor;
+      /**
+       * @defaultValue `foundry.canvas.sources.PointVisionSource`
+       * @remarks Can't be `AnyConstructor` as it's instantiated expecting a compatible constructor
+       */
+      visionSourceClass: typeof foundry.canvas.sources.PointVisionSource;
 
-      soundSourceClass: foundry.canvas.sources.PointSoundSource.AnyConstructor;
+      /**
+       * @defaultValue `foundry.canvas.sources.PointSoundSource`
+       * @remarks Can't be `AnyConstructor` as it's instantiated via `new`
+       */
+      soundSourceClass: typeof foundry.canvas.sources.PointSoundSource;
 
       groups: CONFIG.Canvas.Groups;
 
@@ -1116,7 +1137,9 @@ declare global {
         roundPoints: GridLayer.GridStyle;
       };
 
-      lightAnimations: CONFIG.Canvas.LightSourceAnimationConfig & {
+      lightAnimations: {
+        [key: string]: RenderedEffectSource.LightAnimationConfig;
+
         flame: {
           /** @defaultValue `"LIGHT.AnimationFame"` */
           label: string;
@@ -1189,7 +1212,7 @@ declare global {
           label: string;
 
           /** @defaultValue `foundry.canvas.sources.LightSource.prototype.animateTime` */
-          animation: BaseLightSource.LightAnimationFunction;
+          animation: RenderedEffectSource.AnimationFunction;
 
           /** @defaultValue `ChromaColorationShader` */
           colorationShader: AdaptiveColorationShader.AnyConstructor;
@@ -1200,7 +1223,7 @@ declare global {
           label: string;
 
           /** @defaultValue `foundry.canvas.sources.LightSource.prototype.animateTime` */
-          animation: BaseLightSource.LightAnimationFunction;
+          animation: RenderedEffectSource.AnimationFunction;
 
           /** @defaultValue `WaveIlluminationShader` */
           illuminationShader: AdaptiveIlluminationShader.AnyConstructor;
@@ -1214,7 +1237,7 @@ declare global {
           label: string;
 
           /** @defaultValue `foundry.canvas.sources.LightSource.prototype.animateTime` */
-          animation: BaseLightSource.LightAnimationFunction;
+          animation: RenderedEffectSource.AnimationFunction;
 
           /** @defaultValue `FogColorationShader` */
           colorationShader: AdaptiveColorationShader.AnyConstructor;
@@ -1225,7 +1248,7 @@ declare global {
           label: string;
 
           /** @defaultValue `foundry.canvas.sources.LightSource.prototype.animateTime` */
-          animation: BaseLightSource.LightAnimationFunction;
+          animation: RenderedEffectSource.AnimationFunction;
 
           /** @defaultValue `SunburstIlluminationShader` */
           illuminationShader: AdaptiveIlluminationShader.AnyConstructor;
@@ -1239,7 +1262,7 @@ declare global {
           label: string;
 
           /** @defaultValue `foundry.canvas.sources.LightSource.prototype.animateTime` */
-          animation: BaseLightSource.LightAnimationFunction;
+          animation: RenderedEffectSource.AnimationFunction;
 
           /** @defaultValue `LightDomeColorationShader` */
           colorationShader: AdaptiveColorationShader.AnyConstructor;
@@ -1250,7 +1273,7 @@ declare global {
           label: string;
 
           /** @defaultValue `foundry.canvas.sources.LightSource.prototype.animateTime` */
-          animation: BaseLightSource.LightAnimationFunction;
+          animation: RenderedEffectSource.AnimationFunction;
 
           /** @defaultValue `EmanationColorationShader` */
           colorationShader: AdaptiveColorationShader.AnyConstructor;
@@ -1261,7 +1284,7 @@ declare global {
           label: string;
 
           /** @defaultValue `foundry.canvas.sources.LightSource.prototype.animateTime` */
-          animation: BaseLightSource.LightAnimationFunction;
+          animation: RenderedEffectSource.AnimationFunction;
 
           /** @defaultValue `HexaDomeColorationShader` */
           colorationShader: AdaptiveColorationShader.AnyConstructor;
@@ -1272,7 +1295,7 @@ declare global {
           label: string;
 
           /** @defaultValue `foundry.canvas.sources.LightSource.prototype.animateTime` */
-          animation: BaseLightSource.LightAnimationFunction;
+          animation: RenderedEffectSource.AnimationFunction;
 
           /** @defaultValue `GhostLightIlluminationShader` */
           illuminationShader: AdaptiveIlluminationShader.AnyConstructor;
@@ -1286,7 +1309,7 @@ declare global {
           label: string;
 
           /** @defaultValue `foundry.canvas.sources.LightSource.prototype.animateTime` */
-          animation: BaseLightSource.LightAnimationFunction;
+          animation: RenderedEffectSource.AnimationFunction;
 
           /** @defaultValue `EnergyFieldColorationShader` */
           colorationShader: AdaptiveColorationShader.AnyConstructor;
@@ -1297,7 +1320,7 @@ declare global {
           label: string;
 
           /** @defaultValue `foundry.canvas.sources.LightSource.prototype.animateTime` */
-          animation: BaseLightSource.LightAnimationFunction;
+          animation: RenderedEffectSource.AnimationFunction;
 
           /** @defaultValue `VortexIlluminationShader` */
           illuminationShader: AdaptiveIlluminationShader.AnyConstructor;
@@ -1311,7 +1334,7 @@ declare global {
           label: string;
 
           /** @defaultValue `foundry.canvas.sources.LightSource.prototype.animateTime` */
-          animation: BaseLightSource.LightAnimationFunction;
+          animation: RenderedEffectSource.AnimationFunction;
 
           /** @defaultValue `BewitchingWaveIlluminationShader` */
           illuminationShader: AdaptiveIlluminationShader.AnyConstructor;
@@ -1325,7 +1348,7 @@ declare global {
           label: string;
 
           /** @defaultValue `foundry.canvas.sources.LightSource.prototype.animateTime` */
-          animation: BaseLightSource.LightAnimationFunction;
+          animation: RenderedEffectSource.AnimationFunction;
 
           /** @defaultValue `SwirlingRainbowColorationShader` */
           colorationShader: AdaptiveColorationShader.AnyConstructor;
@@ -1336,7 +1359,7 @@ declare global {
           label: string;
 
           /** @defaultValue `foundry.canvas.sources.LightSource.prototype.animateTime` */
-          animation: BaseLightSource.LightAnimationFunction;
+          animation: RenderedEffectSource.AnimationFunction;
 
           /** @defaultValue `RadialRainbowColorationShader` */
           colorationShader: AdaptiveColorationShader.AnyConstructor;
@@ -1347,7 +1370,7 @@ declare global {
           label: string;
 
           /** @defaultValue `foundry.canvas.sources.LightSource.prototype.animateTime` */
-          animation: BaseLightSource.LightAnimationFunction;
+          animation: RenderedEffectSource.AnimationFunction;
 
           /** @defaultValue `FairyLightIlluminationShader` */
           illuminationShader: AdaptiveIlluminationShader.AnyConstructor;
@@ -1357,12 +1380,48 @@ declare global {
         };
       };
 
-      darknessAnimations: CONFIG.Canvas.DarknessSourceAnimationConfig;
+      darknessAnimations: {
+        [key: string]: RenderedEffectSource.DarknessAnimationConfig;
+
+        magicalGloom: {
+          /** @defaultValue `"LIGHT.AnimationMagicalGloom"` */
+          label: string;
+
+          /** @defaultValue `foundry.canvas.sources.PointDarknessSource.prototype.animateTime` */
+          animation: RenderedEffectSource.AnimationFunction;
+
+          /** @defaultValue `MagicalGloomDarknessShader` */
+          darknessShader: AdaptiveDarknessShader.AnyConstructor;
+        };
+
+        roiling: {
+          /** @defaultValue `"LIGHT.AnimationRoilingMass"` */
+          label: string;
+
+          /** @defaultValue `foundry.canvas.sources.PointDarknessSource.prototype.animateTime` */
+          animation: RenderedEffectSource.AnimationFunction;
+
+          /** @defaultValue `RoilingDarknessShader` */
+          darknessShader: AdaptiveDarknessShader.AnyConstructor;
+        };
+
+        hole: {
+          /** @defaultValue `"LIGHT.AnimationBlackHole"` */
+          label: string;
+
+          /** @defaultValue `foundry.canvas.sources.PointDarknessSource.prototype.animateTime` */
+          animation: RenderedEffectSource.AnimationFunction;
+
+          /** @defaultValue `BlackHoleDarknessShader` */
+          darknessShader: AdaptiveDarknessShader.AnyConstructor;
+        };
+      };
 
       /**
        * A registry of Scenes which are managed by a specific SceneManager class.
+       * @remarks Keys are Scene IDs
+       * @privateRemarks Can't be `AnyConstructor` because it's instantiated expecting a compatible constructor
        */
-      // `typeof foundry.canvas.SceneManager` is used because
       managedScenes: Record<string, typeof foundry.canvas.SceneManager>;
 
       pings: {
@@ -3096,32 +3155,6 @@ declare global {
         };
       }
 
-      /**
-       * A light source animation configuration object.
-       */
-      type LightSourceAnimationConfig = Record<
-        string,
-        {
-          label: string;
-          animation: BaseLightSource.LightAnimationFunction;
-          backgroundShader?: AdaptiveBackgroundShader.AnyConstructor;
-          illuminationShader?: AdaptiveIlluminationShader.AnyConstructor;
-          colorationShader?: AdaptiveColorationShader.AnyConstructor;
-        }
-      >;
-
-      /**
-       * A darkness source animation configuration object.
-       */
-      type DarknessSourceAnimationConfig = Record<
-        string,
-        {
-          label: string;
-          animation: BaseLightSource.LightAnimationFunction;
-          darknessShader: AdaptiveDarknessShader.AnyConstructor;
-        }
-      >;
-
       namespace Pings {
         interface Style {
           class: unknown;
diff --git a/src/foundry/client/pixi/core/shapes/source-polygon.d.mts b/src/foundry/client/pixi/core/shapes/source-polygon.d.mts
index d5a6916db..aafb10ffe 100644
--- a/src/foundry/client/pixi/core/shapes/source-polygon.d.mts
+++ b/src/foundry/client/pixi/core/shapes/source-polygon.d.mts
@@ -7,7 +7,7 @@ declare global {
    */
   abstract class PointSourcePolygon extends PIXI.Polygon {
     /**
-     * @remarks This is protected because `new PointSourcePolygon` does not sufficiently initalize the class; Use the static `create` method instead.
+     * @remarks This is protected because `new PointSourcePolygon` does not sufficiently initialize the class; Use the static `create` method instead.
      */
     protected constructor(...args: ConstructorParameters<typeof PIXI.Polygon>);
 
@@ -24,13 +24,13 @@ declare global {
 
     /**
      * The origin point of the source polygon.
-     * @remarks Not initalized to any value, but immediately set by `PointSourcePolygon#initalize`
+     * @remarks Not initialized to any value, but immediately set by `PointSourcePolygon#initialize`
      */
     origin: Canvas.Point;
 
     /**
      * The configuration of this polygon.
-     * @remarks Initialized as `{}` but immediately filled by `PointSourcePolygon#initalize`
+     * @remarks Initialized as `{}` but immediately filled by `PointSourcePolygon#initialize`
      */
     config: PointSourcePolygon.StoredConfig;
 
@@ -221,7 +221,7 @@ declare global {
     interface _OptionalOnlyConfig {
       /**
        * The object (if any) that spawned this polygon.
-       * @remarks Not guaranteed by `PointSourcePolygon#initalize` but will exist in all configs created by `PointEffectSourceMixin` subclasses. No default provided
+       * @remarks Not guaranteed by `PointSourcePolygon#initialize` but will exist in all configs created by `PointEffectSourceMixin` subclasses. No default provided
        * @privateRemarks Foundry types this as `PointSource` which is neither a typedef nor a class, not even a mixin class name. The type here matches usage and tracks with what they probably meant.
        */
       source?: PointEffectSourceMixin.AnyMixed;
@@ -230,7 +230,7 @@ declare global {
        * The external radius of the source
        * @remarks Can't be `undefined` or `null` or its use in math would produce `NaN`s.
        *
-       * Not guaranteed by `PointSourcePolygon#initalize` but will exist in all configs created by `PointEffectSourceMixin` subclasses.
+       * Not guaranteed by `PointSourcePolygon#initialize` but will exist in all configs created by `PointEffectSourceMixin` subclasses.
        */
       externalRadius?: number;
     }
@@ -298,7 +298,7 @@ declare global {
 
       /**
        * Display debugging visualization and logging for the polygon
-       * @remarks Overriden `true` if `CONFIG.debug.polygons` is truthy
+       * @remarks Overridden `true` if `CONFIG.debug.polygons` is truthy
        */
       debug?: boolean;
 
diff --git a/src/foundry/client/pixi/groups/environment.d.mts b/src/foundry/client/pixi/groups/environment.d.mts
index f2350ccc2..a4b544876 100644
--- a/src/foundry/client/pixi/groups/environment.d.mts
+++ b/src/foundry/client/pixi/groups/environment.d.mts
@@ -1,4 +1,4 @@
-import type { FixedInstanceType, HandleEmptyObject, InexactPartial, NullishProps } from "fvtt-types/utils";
+import type { HandleEmptyObject, InexactPartial, NullishProps } from "fvtt-types/utils";
 import type { SceneEnvironmentData } from "../../../common/documents/_types.d.mts";
 
 declare global {
@@ -13,7 +13,7 @@ declare global {
      * The global light source attached to the environment
      * @remarks This is `defineProperty`'d as non-writable and non-configurable at construction
      */
-    readonly globalLightSource: FixedInstanceType<typeof CONFIG.Canvas.globalLightSourceClass>;
+    readonly globalLightSource: foundry.canvas.sources.GlobalLightSource.ConfiguredInstance;
 
     /**
      * Should this group tear down its non-layer children?
diff --git a/src/foundry/client/pixi/layers/effects/visibility.d.mts b/src/foundry/client/pixi/layers/effects/visibility.d.mts
index bae494263..187273dce 100644
--- a/src/foundry/client/pixi/layers/effects/visibility.d.mts
+++ b/src/foundry/client/pixi/layers/effects/visibility.d.mts
@@ -1,4 +1,4 @@
-import type { HandleEmptyObject, InexactPartial, IntentionalPartial } from "fvtt-types/utils";
+import type { HandleEmptyObject, InexactPartial, IntentionalPartial, NullishProps } from "fvtt-types/utils";
 
 declare global {
   /**
@@ -81,7 +81,7 @@ declare global {
      * Optional overrides for exploration sprite dimensions.
      *
      * @privateRemarks Foundry types this parameter as `FogTextureConfiguration` in v12.331 which is plainly wrong even if it didn't not exist
-     * v13.335 types as `PIXI.Rectable | undefined`, but only x/y/width/height are ever accessed, and only then if this has been set to something
+     * v13.335 types as `PIXI.Rectangle | undefined`, but only x/y/width/height are ever accessed, and only then if this has been set to something
      * other than `undefined`, and in fact nothing in core ever does.
      */
     set explorationRect(rect: Canvas.Rectangle | undefined);
@@ -201,14 +201,14 @@ declare global {
     interface CreateTestConfigOptions extends _CreateTestConfigOptions {}
 
     /** @internal */
-    interface _TestConfigOptional {
+    type _TestConfigOptional = NullishProps<{
       /**
        * The target object
        * @defaultValue `null`
        * @remarks Only checked in `#_canDetect` for `instanceof Token`
        */
       object: TestObject;
-    }
+    }>;
 
     /** @internal */
     interface _TestConfigRequired {
@@ -226,7 +226,7 @@ declare global {
 
     /**
      * @privateRemarks This is a fixed subset of `PIXI.IBaseTextureOptions` that `CanvasVisibility##createTextureConfiguration` produces.
-     * Since it's generated by a private method and stored in a private property, it's not meaninfully extensible (`canvas.visibility.textureConfiguration.foo = "bar"` doesn't count)
+     * Since it's generated by a private method and stored in a private property, it's not meaningfully extensible (`canvas.visibility.textureConfiguration.foo = "bar"` doesn't count)
      */
     interface TextureConfiguration {
       resolution: number;
diff --git a/src/foundry/client/pixi/perception/vision-mode.d.mts b/src/foundry/client/pixi/perception/vision-mode.d.mts
index fd0b2b23c..470c52eff 100644
--- a/src/foundry/client/pixi/perception/vision-mode.d.mts
+++ b/src/foundry/client/pixi/perception/vision-mode.d.mts
@@ -1,4 +1,4 @@
-import type { Brand, InterfaceToObject, SimpleMerge } from "fvtt-types/utils";
+import type { Brand, InterfaceToObject, RemoveIndexSignatures, SimpleMerge } from "fvtt-types/utils";
 import type { fields } from "../../../common/data/module.d.mts";
 import DataField = foundry.data.fields.DataField;
 import type DataModel from "../../../common/abstract/data.d.mts";
@@ -134,6 +134,11 @@ declare global {
   }
 
   namespace VisionMode {
+    interface Any extends AnyVisionMode {}
+    type AnyConstructor = typeof AnyVisionMode;
+
+    type ConfiguredModes = keyof RemoveIndexSignatures<CONFIG["Canvas"]["visionModes"]>;
+
     type LIGHTING_VISIBILITY = Brand<number, "VisionMode.LIGHTING_VISIBILITY">;
 
     interface ExtraConstructorOptions {
@@ -234,3 +239,7 @@ declare global {
     }
   }
 }
+
+declare class AnyVisionMode extends VisionMode {
+  constructor(arg0: never, ...args: never[]);
+}


Test patch:
diff --git a/tests/foundry/client-esm/canvas/edges/vertex.test-d.ts b/tests/foundry/client-esm/canvas/edges/vertex.test-d.ts
index e3bc85b48..7867bacbf 100644
--- a/tests/foundry/client-esm/canvas/edges/vertex.test-d.ts
+++ b/tests/foundry/client-esm/canvas/edges/vertex.test-d.ts
@@ -16,7 +16,7 @@ expectTypeOf(vertex.isBlockingCCW).toEqualTypeOf<boolean | undefined>();
 expectTypeOf(vertex.isBlockingCW).toEqualTypeOf<boolean | undefined>();
 expectTypeOf(vertex.isInternal).toEqualTypeOf<boolean>();
 expectTypeOf(vertex.restriction).toEqualTypeOf<foundry.CONST.WALL_SENSE_TYPES>();
-expectTypeOf(vertex._visited).toEqualTypeOf<boolean>();
+expectTypeOf(vertex["_visited"]).toEqualTypeOf<boolean>();
 expectTypeOf(vertex.isLimited).toEqualTypeOf<boolean>();
 
 declare const edge: foundry.canvas.edges.Edge;
diff --git a/tests/foundry/client-esm/canvas/sources/base-effect-source.mjs.test-d.ts b/tests/foundry/client-esm/canvas/sources/base-effect-source.mjs.test-d.ts
deleted file mode 100644
index c3b7c1554..000000000
--- a/tests/foundry/client-esm/canvas/sources/base-effect-source.mjs.test-d.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-import { expectTypeOf } from "vitest";
-import type BaseEffectSource from "../../../../../src/foundry/client-esm/canvas/sources/base-effect-source.d.mts";
-
-declare const mySource: BaseEffectSource<BaseEffectSource.SourceData, PIXI.Polygon>;
-
-expectTypeOf(mySource.active).toEqualTypeOf<boolean>();
diff --git a/tests/foundry/client-esm/canvas/sources/base-effect-source.test-d.ts b/tests/foundry/client-esm/canvas/sources/base-effect-source.test-d.ts
new file mode 100644
index 000000000..e1d799df0
--- /dev/null
+++ b/tests/foundry/client-esm/canvas/sources/base-effect-source.test-d.ts
@@ -0,0 +1,125 @@
+import { expectTypeOf } from "vitest";
+import type BaseEffectSource from "../../../../../src/foundry/client-esm/canvas/sources/base-effect-source.d.mts";
+import type { IntentionalPartial } from "fvtt-types/utils";
+
+class MyEffectSource<SourceData extends BaseEffectSource.SourceData = BaseEffectSource.SourceData> extends foundry
+  .canvas.sources.BaseEffectSource<SourceData, PIXI.Polygon> {
+  static override sourceType = "sight";
+
+  static override effectsCollection = "someCollection";
+
+  protected override _initialize(data: IntentionalPartial<SourceData>): void {
+    data.disabled = false;
+  }
+
+  protected override _createShapes(): void {
+    this.shape = new PIXI.Polygon();
+  }
+
+  protected override _configure(changes: IntentionalPartial<SourceData>): void {
+    if (typeof changes.x === "number" && changes.x > 500) {
+      console.warn("too far");
+    }
+  }
+}
+
+expectTypeOf(MyEffectSource.sourceType).toBeString();
+expectTypeOf(MyEffectSource.effectsCollection).toBeString();
+expectTypeOf(MyEffectSource.defaultData).toEqualTypeOf<BaseEffectSource.SourceData>();
+
+const mySource = new MyEffectSource();
+
+expectTypeOf(mySource.object).toEqualTypeOf<PlaceableObject.Any | CanvasGroupMixin.AnyMixed | null>();
+expectTypeOf(mySource.sourceId).toEqualTypeOf<string | undefined>();
+expectTypeOf(mySource.data).toEqualTypeOf<BaseEffectSource.SourceData>();
+expectTypeOf(mySource.shape).toEqualTypeOf<PIXI.Polygon | undefined>();
+
+expectTypeOf(mySource["_flags"]).toEqualTypeOf<BaseEffectSource.Flags>();
+expectTypeOf((mySource["_flags"].foo = true)).toBeBoolean();
+expectTypeOf((mySource["_flags"].bar = 7)).toBeNumber();
+
+expectTypeOf(mySource.x).toBeNumber();
+expectTypeOf(mySource.y).toBeNumber();
+expectTypeOf(mySource.elevation).toBeNumber();
+expectTypeOf(mySource.effectsCollection).toEqualTypeOf<foundry.utils.Collection<MyEffectSource>>();
+expectTypeOf(mySource.updateId).toBeNumber();
+expectTypeOf(mySource.active).toBeBoolean();
+expectTypeOf(mySource.attached).toBeBoolean();
+expectTypeOf(mySource.suppression).toEqualTypeOf<Record<string, boolean>>();
+
+expectTypeOf(mySource.initialize()).toEqualTypeOf<MyEffectSource>();
+expectTypeOf(mySource.initialize(null, { reset: null })).toEqualTypeOf<MyEffectSource>();
+expectTypeOf(mySource.initialize({}, { reset: false })).toEqualTypeOf<MyEffectSource>();
+expectTypeOf(
+  mySource.initialize(
+    {
+      x: null,
+      y: null,
+      disabled: null,
+      elevation: null,
+    },
+    { reset: undefined },
+  ),
+).toEqualTypeOf<MyEffectSource>();
+expectTypeOf(
+  mySource.initialize(
+    {
+      x: 50,
+      y: 50,
+      elevation: 50,
+      disabled: false,
+    },
+    undefined,
+  ),
+).toEqualTypeOf<MyEffectSource>();
+
+//@ts-expect-error `#_initialize` takes and mutates data, not passing it anything doesn't make sense
+expectTypeOf(mySource["_initialize"]()).toBeVoid();
+expectTypeOf(
+  //@ts-expect-error `#initialize` will have already applied the defaults from `.defaultData` before calling `#_initialize`
+  mySource["_initialize"]({
+    y: undefined,
+  }),
+).toBeVoid();
+expectTypeOf(mySource["_initialize"]({})).toBeVoid();
+expectTypeOf(
+  mySource["_initialize"]({
+    x: 50,
+    y: 50,
+    elevation: 50,
+  }),
+).toBeVoid();
+
+// `#_configure` gets passed flattened data, but none of the core Source types have any
+// nested objects in their data, so this is currently irrelevant
+expectTypeOf(mySource["_configure"]({}));
+expectTypeOf(
+  mySource["_configure"]({
+    x: 50,
+    y: 50,
+    elevation: 20,
+    disabled: false,
+  }),
+);
+expectTypeOf(
+  //@ts-expect-error data passed to `#_configure` will have had excess keys stripped and default values applied
+  mySource["_configure"]({
+    y: undefined,
+  }),
+);
+
+expectTypeOf(mySource.refresh()).toBeVoid();
+expectTypeOf(mySource["_refresh"]()).toBeVoid();
+
+expectTypeOf(mySource.destroy()).toBeVoid();
+expectTypeOf(mySource["_destroy"]()).toBeVoid();
+
+expectTypeOf(mySource.add()).toBeVoid();
+expectTypeOf(mySource.remove()).toBeVoid();
+
+//deprecated since v11, until v13
+expectTypeOf(mySource.sourceType).toBeString();
+
+//deprecated since v12, until v14
+expectTypeOf(mySource["_createShape"]()).toBeVoid();
+expectTypeOf(mySource.disabled).toBeBoolean();
diff --git a/tests/foundry/client-esm/canvas/sources/base-light-source.mjs.test-d.ts b/tests/foundry/client-esm/canvas/sources/base-light-source.mjs.test-d.ts
deleted file mode 100644
index 8f7060de0..000000000
--- a/tests/foundry/client-esm/canvas/sources/base-light-source.mjs.test-d.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import { expectTypeOf } from "vitest";
-import type BaseLightSource from "../../../../../src/foundry/client-esm/canvas/sources/base-light-source.d.mts";
-
-declare const mySource: BaseLightSource;
-
-expectTypeOf(mySource.active).toEqualTypeOf<boolean>();
-expectTypeOf(mySource.drawMeshes().background?.visible).toEqualTypeOf<boolean | undefined>();
-expectTypeOf(mySource.animateTorch(5)).toEqualTypeOf<void>();
diff --git a/tests/foundry/client-esm/canvas/sources/base-light-source.test-d.ts b/tests/foundry/client-esm/canvas/sources/base-light-source.test-d.ts
new file mode 100644
index 000000000..b81497fcc
--- /dev/null
+++ b/tests/foundry/client-esm/canvas/sources/base-light-source.test-d.ts
@@ -0,0 +1,53 @@
+import { expectTypeOf } from "vitest";
+import type BaseLightSource from "../../../../../src/foundry/client-esm/canvas/sources/base-light-source.d.mts";
+import type RenderedEffectSource from "../../../../../src/foundry/client-esm/canvas/sources/rendered-effect-source.d.mts";
+
+declare class MyLightSource extends foundry.canvas.sources.BaseLightSource {
+  protected override _createShapes(): void;
+}
+
+expectTypeOf(MyLightSource.sourceType).toBeString();
+expectTypeOf(MyLightSource["_initializeShaderKeys"]).toEqualTypeOf<string[]>();
+expectTypeOf(MyLightSource["_refreshUniformsKeys"]).toEqualTypeOf<string[]>();
+expectTypeOf(MyLightSource["_dimLightingLevel"]).toEqualTypeOf<foundry.CONST.LIGHTING_LEVELS>();
+expectTypeOf(MyLightSource["_brightLightingLevel"]).toEqualTypeOf<foundry.CONST.LIGHTING_LEVELS>();
+expectTypeOf(MyLightSource["ANIMATIONS"]).toMatchTypeOf<Record<string, RenderedEffectSource.AnimationConfig>>();
+expectTypeOf(MyLightSource.defaultData).toEqualTypeOf<BaseLightSource.SourceData>();
+
+declare const someToken: Token.ConfiguredInstance;
+const mySource = new MyLightSource({ object: someToken, sourceId: "asfsdfs" });
+
+expectTypeOf(mySource.ratio).toBeNumber();
+
+// only new SourceData keys tested here, thorough tests are on the final Point*Source classes
+expectTypeOf(
+  mySource["_initialize"]({
+    priority: 7,
+    alpha: 0.2,
+    bright: 50,
+    dim: 100,
+    attenuation: 0.9,
+    luminosity: 0.87,
+    saturation: 0.2,
+    shadows: 1,
+    vision: true,
+  }),
+).toBeVoid();
+
+expectTypeOf(mySource["_updateColorationUniforms"]()).toBeVoid();
+expectTypeOf(mySource["_updateIlluminationUniforms"]()).toBeVoid();
+expectTypeOf(mySource["_updateBackgroundUniforms"]()).toBeVoid();
+declare const someBackgroundShader: AdaptiveBackgroundShader;
+expectTypeOf(mySource["_updateCommonUniforms"](someBackgroundShader)).toBeVoid();
+
+expectTypeOf(mySource.cachedAttenuation).toEqualTypeOf<number | undefined>();
+expectTypeOf(mySource.computedAttenuation).toEqualTypeOf<number | undefined>();
+expectTypeOf(mySource._noise).toEqualTypeOf<SmoothNoise | undefined>();
+
+expectTypeOf(mySource.animatePulse(7)).toBeVoid();
+expectTypeOf(mySource.animateTorch(23, { intensity: undefined, reverse: null, speed: undefined })).toBeVoid();
+// animateFlickering is the only animation function with an extra option (`amplification`)
+expectTypeOf(mySource.animateFlickering(12, { amplification: -3, intensity: 2, reverse: true, speed: 10 })).toBeVoid();
+
+// deprecated since v12, until v14
+expectTypeOf(mySource.isDarkness).toBeBoolean();
diff --git a/tests/foundry/client-esm/canvas/sources/global-light-source.mjs.test-d.ts b/tests/foundry/client-esm/canvas/sources/global-light-source.mjs.test-d.ts
deleted file mode 100644
index 0a0e4f3b7..000000000
--- a/tests/foundry/client-esm/canvas/sources/global-light-source.mjs.test-d.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import { expectTypeOf } from "vitest";
-
-const mySource = new foundry.canvas.sources.GlobalLightSource();
-
-expectTypeOf(mySource.active).toEqualTypeOf<boolean>();
-expectTypeOf(mySource.drawMeshes().background.visible).toEqualTypeOf<boolean>();
-expectTypeOf(mySource.animateTorch(5)).toEqualTypeOf<void>();
-
-// Pulled from EnvironmentCanvasGroup##configureGlobalLight
-const globalLightData = {
-  z: -Infinity,
-  elevation: Infinity,
-  dim: 0,
-  bright: 0,
-  disabled: false,
-};
-
-expectTypeOf(mySource.initialize(globalLightData)).toEqualTypeOf<foundry.canvas.sources.GlobalLightSource>();
diff --git a/tests/foundry/client-esm/canvas/sources/global-light-source.test-d.ts b/tests/foundry/client-esm/canvas/sources/global-light-source.test-d.ts
new file mode 100644
index 000000000..fcbbf55a6
--- /dev/null
+++ b/tests/foundry/client-esm/canvas/sources/global-light-source.test-d.ts
@@ -0,0 +1,58 @@
+import { expectTypeOf } from "vitest";
+import type GlobalLightSource from "../../../../../src/foundry/client-esm/canvas/sources/global-light-source.d.mts";
+
+const { GlobalLightSource: GLSC } = foundry.canvas.sources;
+
+expectTypeOf(GLSC.sourceType).toBeString();
+expectTypeOf(GLSC.effectsCollection).toBeString();
+expectTypeOf(GLSC.defaultData).toEqualTypeOf<GlobalLightSource.SourceData>();
+
+declare const ecg: EffectsCanvasGroup;
+const mySource = new GLSC({ object: ecg, sourceId: "globalLight" });
+
+expectTypeOf(mySource.data).toEqualTypeOf<GlobalLightSource.SourceData>();
+expectTypeOf(mySource.shape).toEqualTypeOf<PIXI.Polygon>();
+
+// Every property of SourceData represented for testing, not all necessarily actually used by this type
+expectTypeOf(
+  mySource.initialize({
+    alpha: 0.9,
+    angle: 360,
+    animation: {
+      animation: GLSC.prototype.animatePulse,
+      colorationShader: PulseColorationShader,
+      illuminationShader: PulseIlluminationShader,
+      backgroundShader: AdaptiveBackgroundShader,
+      seed: 235252,
+    },
+    attenuation: -0.1,
+    bright: canvas!.dimensions!.maxR * 1.2,
+    dim: canvas!.dimensions!.maxR * 1.2,
+    color: [0.5, 0.7, 0.9],
+    coloration: -0.4,
+    contrast: 0.6,
+    darkness: { min: 0, max: 0.78 },
+    disabled: false,
+    elevation: Infinity,
+    luminosity: 0.1,
+    preview: false,
+    priority: 5,
+    rotation: 0,
+    saturation: 0,
+    seed: 11111111,
+    shadows: 0.3,
+    vision: true,
+    walls: false,
+    x: canvas!.dimensions!.sceneWidth / 2,
+    y: canvas!.dimensions!.sceneHeight / 2,
+  }),
+).toEqualTypeOf<typeof mySource>();
+
+expectTypeOf(mySource.name).toBeString();
+expectTypeOf(mySource.customPolygon).toEqualTypeOf<PIXI.Polygon | number[] | null>();
+
+expectTypeOf(mySource["_updateColorationUniforms"]()).toBeVoid();
+expectTypeOf(mySource["_updateIlluminationUniforms"]()).toBeVoid();
+expectTypeOf(mySource["_updateBackgroundUniforms"]()).toBeVoid();
+declare const someBackgroundShader: AdaptiveBackgroundShader;
+expectTypeOf(mySource["_updateCommonUniforms"](someBackgroundShader)).toBeVoid();
diff --git a/tests/foundry/client-esm/canvas/sources/point-darkness-sources.mjs.test-d.ts b/tests/foundry/client-esm/canvas/sources/point-darkness-sources.mjs.test-d.ts
deleted file mode 100644
index df2386ba3..000000000
--- a/tests/foundry/client-esm/canvas/sources/point-darkness-sources.mjs.test-d.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import { expectTypeOf } from "vitest";
-
-const mySource = new foundry.canvas.sources.PointDarknessSource();
-
-expectTypeOf(mySource.data).toEqualTypeOf<foundry.canvas.sources.PointDarknessSource.SourceData>();
-expectTypeOf(mySource.active).toEqualTypeOf<boolean>();
-expectTypeOf(mySource.drawMeshes().darkness).toEqualTypeOf<PIXI.Mesh | null>();
-expectTypeOf(mySource.drawMeshes().darkness?.visible).toEqualTypeOf<boolean | undefined>();
-expectTypeOf(mySource.animateTorch(5)).toEqualTypeOf<void>();
-expectTypeOf(mySource.add()).toEqualTypeOf<void>();
-expectTypeOf(mySource.shape).toEqualTypeOf<PointSourcePolygon>();
-expectTypeOf(mySource.layers.darkness.suppressed).toEqualTypeOf<boolean>();
diff --git a/tests/foundry/client-esm/canvas/sources/point-darkness-sources.test-d.ts b/tests/foundry/client-esm/canvas/sources/point-darkness-sources.test-d.ts
new file mode 100644
index 000000000..1450561d4
--- /dev/null
+++ b/tests/foundry/client-esm/canvas/sources/point-darkness-sources.test-d.ts
@@ -0,0 +1,67 @@
+import { expectTypeOf } from "vitest";
+import type RenderedEffectSource from "../../../../../src/foundry/client-esm/canvas/sources/rendered-effect-source.d.mts";
+import type PointDarknessSource from "../../../../../src/foundry/client-esm/canvas/sources/point-darkness-source.d.mts";
+
+const { PointDarknessSource: PDS } = foundry.canvas.sources;
+
+expectTypeOf(PDS.effectsCollection).toBeString();
+expectTypeOf(PDS["_dimLightingLevel"]).toMatchTypeOf<foundry.CONST.LIGHTING_LEVELS>();
+expectTypeOf(PDS["_brightLightingLevel"]).toMatchTypeOf<foundry.CONST.LIGHTING_LEVELS>();
+expectTypeOf(PDS["ANIMATIONS"]).toEqualTypeOf<typeof CONFIG.Canvas.darknessAnimations>();
+expectTypeOf(PDS["_layers"]).toMatchTypeOf<Record<string, RenderedEffectSource.LayerConfig>>();
+expectTypeOf(PDS.defaultData).toEqualTypeOf<PointDarknessSource.SourceData>();
+
+const mySource = new foundry.canvas.sources.PointDarknessSource();
+
+expectTypeOf(mySource["_visualShape"]).toEqualTypeOf<PointSourcePolygon | null>();
+expectTypeOf(mySource.shape).toEqualTypeOf<PointSourcePolygon>();
+expectTypeOf(mySource["_padding"]).toBeNumber();
+expectTypeOf(mySource.edges).toEqualTypeOf<foundry.canvas.edges.Edge[]>();
+expectTypeOf(mySource.darkness).toEqualTypeOf<PointSourceMesh>();
+
+const sourceData = {
+  x: 50,
+  y: 50,
+  alpha: 0.1,
+  angle: 215,
+  animation: {
+    animation: PDS.prototype.animateTime,
+    darknessShader: BlackHoleDarknessShader,
+  },
+  attenuation: 0,
+  bright: 10,
+  color: 0xffffff,
+  coloration: 1,
+  contrast: 0.7,
+  dim: 20,
+  disabled: false,
+  elevation: 0,
+  externalRadius: 0,
+  luminosity: 1,
+  preview: false,
+  priority: 17,
+  radius: 50,
+  rotation: 0,
+  saturation: 1,
+  seed: 42,
+  shadows: 1,
+  vision: true,
+  walls: false,
+} satisfies PointDarknessSource.SourceData;
+
+expectTypeOf(mySource["_initialize"]({})).toBeVoid();
+expectTypeOf(mySource["_initialize"](sourceData)).toBeVoid();
+
+expectTypeOf(mySource["_createShapes"]()).toBeVoid();
+expectTypeOf(mySource["_configure"]({})).toBeVoid();
+expectTypeOf(mySource["_configure"](sourceData)).toBeVoid();
+
+expectTypeOf(mySource["_getPolygonConfiguration"]()).toEqualTypeOf<PointDarknessSource.PolygonConfig>();
+expectTypeOf(mySource["_drawMesh"]("darkness")).toEqualTypeOf<PointSourceMesh | null>();
+
+expectTypeOf(mySource["_updateGeometry"]()).toBeVoid();
+expectTypeOf(mySource["_updateDarknessUniforms"]()).toBeVoid();
+expectTypeOf(mySource["_destroy"]()).toBeVoid();
+
+// deprecated since v12, until v14
+expectTypeOf(mySource.isDarkness).toEqualTypeOf<true>();
diff --git a/tests/foundry/client-esm/canvas/sources/point-effect-source.test-d.ts b/tests/foundry/client-esm/canvas/sources/point-effect-source.test-d.ts
new file mode 100644
index 000000000..916e7ad71
--- /dev/null
+++ b/tests/foundry/client-esm/canvas/sources/point-effect-source.test-d.ts
@@ -0,0 +1,40 @@
+import { expectTypeOf } from "vitest";
+import type PointEffectSourceMixin from "../../../../../src/foundry/client-esm/canvas/sources/point-effect-source.d.mts";
+
+declare class MyPointEffectSource<
+  SourceData extends PointEffectSourceMixin.MixedSourceData = PointEffectSourceMixin.MixedSourceData,
+  SourceShape extends PointSourcePolygon = ClockwiseSweepPolygon,
+> extends PointEffectSourceMixin(foundry.canvas.sources.BaseEffectSource)<SourceData, SourceShape> {
+  static defaultData: PointEffectSourceMixin.MixedSourceData;
+  shape: SourceShape;
+}
+
+expectTypeOf(MyPointEffectSource.defaultData).toEqualTypeOf<PointEffectSourceMixin.MixedSourceData>();
+
+const mySource = new MyPointEffectSource();
+
+expectTypeOf(mySource.data).toEqualTypeOf<PointEffectSourceMixin.MixedSourceData>();
+expectTypeOf(mySource.shape).toEqualTypeOf<ClockwiseSweepPolygon>();
+expectTypeOf(mySource.radius).toBeNumber();
+
+expectTypeOf(mySource["_initialize"]({})).toBeVoid();
+// only new SourceData keys tested here, thorough tests are on the final Point*Source classes
+expectTypeOf(
+  mySource["_initialize"]({
+    radius: 200,
+    externalRadius: 400,
+    rotation: 60,
+    angle: 270,
+    walls: false,
+  }),
+).toBeVoid();
+
+expectTypeOf(mySource["_initializeSoftEdges"]()).toBeVoid();
+expectTypeOf(mySource["_getPolygonConfiguration"]()).toEqualTypeOf<PointEffectSourceMixin.PolygonConfig>();
+expectTypeOf(mySource["_createShapes"]()).toBeVoid();
+expectTypeOf(mySource["_drawMesh"]("background")).toEqualTypeOf<PointSourceMesh | null>();
+expectTypeOf(mySource["_updateGeometry"]()).toBeVoid();
+
+// deprecated since v11, until v13
+expectTypeOf((mySource.radius = 5)).toBeNumber();
+expectTypeOf(mySource.los).toEqualTypeOf<ClockwiseSweepPolygon>();
diff --git a/tests/foundry/client-esm/canvas/sources/point-light-source.mjs.test-d.ts b/tests/foundry/client-esm/canvas/sources/point-light-source.mjs.test-d.ts
deleted file mode 100644
index 20b959643..000000000
--- a/tests/foundry/client-esm/canvas/sources/point-light-source.mjs.test-d.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import { expectTypeOf } from "vitest";
-
-const mySource = new foundry.canvas.sources.PointLightSource();
-
-expectTypeOf(mySource.active).toEqualTypeOf<boolean>();
-expectTypeOf(mySource.drawMeshes().background?.visible).toEqualTypeOf<boolean | undefined>();
-expectTypeOf(mySource.animateTorch(5)).toEqualTypeOf<void>();
-expectTypeOf(mySource.add()).toEqualTypeOf<void>();
-expectTypeOf(mySource.shape).toEqualTypeOf<PointSourcePolygon>();
diff --git a/tests/foundry/client-esm/canvas/sources/point-light-source.test-d.ts b/tests/foundry/client-esm/canvas/sources/point-light-source.test-d.ts
new file mode 100644
index 000000000..e4f6a6260
--- /dev/null
+++ b/tests/foundry/client-esm/canvas/sources/point-light-source.test-d.ts
@@ -0,0 +1,74 @@
+import { expectTypeOf } from "vitest";
+import type PointLightSource from "../../../../../src/foundry/client-esm/canvas/sources/point-light-source.d.mts";
+
+const PLS = foundry.canvas.sources.PointLightSource;
+
+expectTypeOf(PLS.effectsCollection).toBeString();
+expectTypeOf(PLS.defaultData).toEqualTypeOf<PointLightSource.SourceData>();
+
+const mySource = new PLS();
+
+expectTypeOf(mySource.data).toEqualTypeOf<PointLightSource.SourceData>();
+expectTypeOf(mySource.shape).toEqualTypeOf<PointSourcePolygon>();
+
+const sourceData = {
+  x: 50,
+  y: 50,
+  alpha: 0.1,
+  angle: 215,
+  animation: {
+    animation: PLS.prototype.animateTime,
+    illuminationShader: FairyLightIlluminationShader,
+    colorationShader: FairyLightColorationShader,
+    backgroundShader: AdaptiveBackgroundShader,
+    seed: 987654321,
+  },
+  attenuation: 0,
+  bright: 10,
+  color: 0xffffff,
+  coloration: 1,
+  contrast: 0.7,
+  dim: 20,
+  disabled: false,
+  elevation: 0,
+  externalRadius: 0,
+  luminosity: 1,
+  preview: false,
+  priority: 17,
+  radius: 50,
+  rotation: 0,
+  saturation: 1,
+  seed: 42,
+  shadows: 1,
+  vision: true,
+  walls: false,
+} satisfies PointLightSource.SourceData;
+
+expectTypeOf(mySource["_initialize"]({})).toBeVoid();
+expectTypeOf(mySource["_initialize"](sourceData)).toBeVoid();
+
+expectTypeOf(mySource["_createShapes"]()).toBeVoid();
+expectTypeOf(mySource["_configure"]({})).toBeVoid();
+expectTypeOf(mySource["_configure"](sourceData)).toBeVoid();
+
+expectTypeOf(mySource["_getPolygonConfiguration"]()).toEqualTypeOf<PointLightSource.PolygonConfig>();
+
+declare const someVisionSource: foundry.canvas.sources.PointVisionSource;
+declare const someToken: Token.ConfiguredInstance;
+const tests = [
+  {
+    elevation: 0,
+    los: new Map([[someVisionSource, true]]),
+    point: { x: 50, y: 50 },
+  },
+];
+expectTypeOf(mySource.testVisibility({ object: someToken, tests }));
+expectTypeOf(mySource.testVisibility({ object: null, tests }));
+expectTypeOf(mySource.testVisibility({ tests }));
+
+expectTypeOf(mySource["_canDetectObject"]()).toBeBoolean();
+expectTypeOf(mySource["_canDetectObject"](null)).toBeBoolean();
+expectTypeOf(mySource["_canDetectObject"](someToken)).toBeBoolean();
+
+// deprecated since v12, until v14
+expectTypeOf(mySource.isDarkness).toEqualTypeOf<false>();
diff --git a/tests/foundry/client-esm/canvas/sources/point-movement-source.mjs.test-d.ts b/tests/foundry/client-esm/canvas/sources/point-movement-source.mjs.test-d.ts
deleted file mode 100644
index 1eec56be1..000000000
--- a/tests/foundry/client-esm/canvas/sources/point-movement-source.mjs.test-d.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import { expectTypeOf } from "vitest";
-import type PointMovementSource from "../../../../../src/foundry/client-esm/canvas/sources/point-movement-source.d.mts";
-
-const mySource = new foundry.canvas.sources.PointMovementSource();
-
-expectTypeOf(mySource.active).toEqualTypeOf<boolean>();
-expectTypeOf(mySource.initialize({ x: 3, y: 5, elevation: 7 })).toEqualTypeOf<PointMovementSource>();
-expectTypeOf(mySource.shape).toEqualTypeOf<PointSourcePolygon>();
-expectTypeOf(mySource.data).toEqualTypeOf<PointMovementSource.SourceData>();
diff --git a/tests/foundry/client-esm/canvas/sources/point-movement-source.test-d.ts b/tests/foundry/client-esm/canvas/sources/point-movement-source.test-d.ts
new file mode 100644
index 000000000..836ff8be5
--- /dev/null
+++ b/tests/foundry/client-esm/canvas/sources/point-movement-source.test-d.ts
@@ -0,0 +1,27 @@
+import { expectTypeOf } from "vitest";
+import type PointMovementSource from "../../../../../src/foundry/client-esm/canvas/sources/point-movement-source.d.mts";
+
+const PMS = foundry.canvas.sources.PointMovementSource;
+
+expectTypeOf(PMS.sourceType).toBeString();
+expectTypeOf(PMS.defaultData).toEqualTypeOf<PointMovementSource.SourceData>();
+
+const mySource = new PMS();
+
+expectTypeOf(mySource.data).toEqualTypeOf<PointMovementSource.SourceData>();
+expectTypeOf(mySource.shape).toEqualTypeOf<PointSourcePolygon>();
+
+// Every property of SourceData represented for testing, not all necessarily actually used by this type
+expectTypeOf(
+  mySource.initialize({
+    angle: 90,
+    disabled: false,
+    elevation: 20,
+    externalRadius: 2000,
+    radius: 300,
+    rotation: 270,
+    walls: true,
+    x: 50,
+    y: 50,
+  }),
+).toEqualTypeOf<typeof mySource>();
diff --git a/tests/foundry/client-esm/canvas/sources/point-sound-source.mjs.test-d.ts b/tests/foundry/client-esm/canvas/sources/point-sound-source.mjs.test-d.ts
deleted file mode 100644
index d4374b953..000000000
--- a/tests/foundry/client-esm/canvas/sources/point-sound-source.mjs.test-d.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import { expectTypeOf } from "vitest";
-import type PointSoundSource from "../../../../../src/foundry/client-esm/canvas/sources/point-sound-source.d.mts";
-
-const mySource = new foundry.canvas.sources.PointSoundSource();
-
-expectTypeOf(mySource.active).toEqualTypeOf<boolean>();
-expectTypeOf(mySource.initialize({ radius: 5, walls: true, disabled: false })).toEqualTypeOf<PointSoundSource>();
-expectTypeOf(mySource.shape).toEqualTypeOf<PointSourcePolygon>();
-expectTypeOf(mySource.data).toEqualTypeOf<PointSoundSource.SourceData>();
diff --git a/tests/foundry/client-esm/canvas/sources/point-sound-source.test-d.ts b/tests/foundry/client-esm/canvas/sources/point-sound-source.test-d.ts
new file mode 100644
index 000000000..e100ccb32
--- /dev/null
+++ b/tests/foundry/client-esm/canvas/sources/point-sound-source.test-d.ts
@@ -0,0 +1,32 @@
+import { expectTypeOf } from "vitest";
+import type PointSoundSource from "../../../../../src/foundry/client-esm/canvas/sources/point-sound-source.d.mts";
+
+const PSS = foundry.canvas.sources.PointSoundSource;
+
+expectTypeOf(PSS.sourceType).toBeString();
+expectTypeOf(PSS.defaultData).toEqualTypeOf<PointSoundSource.SourceData>();
+
+const mySource = new PSS();
+
+expectTypeOf(mySource.data).toEqualTypeOf<PointSoundSource.SourceData>();
+expectTypeOf(mySource.shape).toEqualTypeOf<PointSourcePolygon>();
+expectTypeOf(mySource.effectsCollection).toEqualTypeOf<foundry.utils.Collection<typeof mySource>>();
+
+// Every property of SourceData represented for testing, not all necessarily actually used by this type
+expectTypeOf(
+  mySource.initialize({
+    angle: 90,
+    disabled: false,
+    elevation: 20,
+    externalRadius: 2000,
+    radius: 300,
+    rotation: 270,
+    walls: true,
+    x: 50,
+    y: 50,
+  }),
+).toEqualTypeOf<typeof mySource>();
+
+expectTypeOf(mySource.getVolumeMultiplier({ x: 50, y: 40 })).toBeNumber();
+expectTypeOf(mySource.getVolumeMultiplier({ x: 50, y: 40 }, { easing: true })).toBeNumber();
+expectTypeOf(mySource.getVolumeMultiplier({ x: 50, y: 40 }, { easing: null })).toBeNumber();
diff --git a/tests/foundry/client-esm/canvas/sources/point-vision-source.mjs.test-d.ts b/tests/foundry/client-esm/canvas/sources/point-vision-source.mjs.test-d.ts
deleted file mode 100644
index 510338d67..000000000
--- a/tests/foundry/client-esm/canvas/sources/point-vision-source.mjs.test-d.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { expectTypeOf } from "vitest";
-import type PointVisionSource from "../../../../../src/foundry/client-esm/canvas/sources/point-vision-source.d.mts";
-
-const mySource = new foundry.canvas.sources.PointVisionSource();
-
-expectTypeOf(mySource.active).toEqualTypeOf<boolean>();
-expectTypeOf(mySource.drawMeshes().background?.visible).toEqualTypeOf<boolean | undefined>();
-expectTypeOf(mySource.data).toEqualTypeOf<PointVisionSource.SourceData>();
-expectTypeOf(mySource.shape).toEqualTypeOf<PointSourcePolygon>();
-expectTypeOf(mySource._configureShaders().background).toEqualTypeOf<typeof AdaptiveVisionShader>();
diff --git a/tests/foundry/client-esm/canvas/sources/point-vision-source.test-d.ts b/tests/foundry/client-esm/canvas/sources/point-vision-source.test-d.ts
new file mode 100644
index 000000000..e53477c3a
--- /dev/null
+++ b/tests/foundry/client-esm/canvas/sources/point-vision-source.test-d.ts
@@ -0,0 +1,104 @@
+import { expectTypeOf } from "vitest";
+import type PointVisionSource from "../../../../../src/foundry/client-esm/canvas/sources/point-vision-source.d.mts";
+import type RenderedEffectSource from "../../../../../src/foundry/client-esm/canvas/sources/rendered-effect-source.d.mts";
+
+const PVS = foundry.canvas.sources.PointVisionSource;
+
+expectTypeOf(PVS.sourceType).toBeString();
+expectTypeOf(PVS["_initializeShaderKeys"]).toEqualTypeOf<string[]>();
+expectTypeOf(PVS["_refreshUniformsKeys"]).toEqualTypeOf<string[]>();
+expectTypeOf(PVS["_dimLightingLevel"]).toEqualTypeOf<foundry.CONST.LIGHTING_LEVELS>();
+expectTypeOf(PVS["_brightLightingLevel"]).toEqualTypeOf<foundry.CONST.LIGHTING_LEVELS>();
+expectTypeOf(PVS.EDGE_OFFSET).toBeNumber();
+expectTypeOf(PVS.effectsCollection).toBeString();
+expectTypeOf(PVS.defaultData).toEqualTypeOf<PointVisionSource.SourceData>();
+expectTypeOf(PVS["_layers"]).toEqualTypeOf<Record<string, RenderedEffectSource.LayerConfig>>();
+
+const mySource = new PVS();
+
+expectTypeOf(mySource.data).toEqualTypeOf<PointVisionSource.SourceData>();
+expectTypeOf(mySource.shape).toEqualTypeOf<PointSourcePolygon>();
+expectTypeOf(mySource.visionMode).toEqualTypeOf<VisionMode | undefined>();
+expectTypeOf(mySource["_visionModeActivated"]).toBeBoolean();
+expectTypeOf(mySource.los).toEqualTypeOf<PointSourcePolygon>();
+expectTypeOf(mySource.light).toEqualTypeOf<PointSourcePolygon>();
+expectTypeOf(mySource.fov).toEqualTypeOf<PointSourcePolygon>();
+expectTypeOf(mySource.preferred).toEqualTypeOf<boolean | undefined>();
+expectTypeOf(mySource.isAnimated).toBeBoolean();
+expectTypeOf(mySource.lightRadius).toBeNumber();
+expectTypeOf(mySource.radius).toBeNumber();
+expectTypeOf(mySource.isBlinded).toBeBoolean();
+expectTypeOf(mySource.blinded).toEqualTypeOf<PointVisionSource.BlindedReasons>();
+expectTypeOf(mySource.visionModeOverrides).toEqualTypeOf<PointVisionSource.VisionModeOverrides>();
+
+// Every property of SourceData represented for testing, not all necessarily actually used by this type
+expectTypeOf(
+  mySource["_initialize"]({
+    angle: 100,
+    animation: {
+      animation: PVS.prototype.animateTime,
+      // not actually sure if vision animation takes shaders here or not, so omitted
+    },
+    attenuation: -1,
+    blinded: false,
+    brightness: 0.6,
+    color: 0xfeafef,
+    contrast: -0.2,
+    disabled: false,
+    elevation: 10,
+    externalRadius: 20000,
+    lightRadius: 3123,
+    preview: false,
+    radius: 222,
+    rotation: 179,
+    saturation: 0.3,
+    seed: 2442,
+    visionMode: "darkvision",
+    walls: false,
+    x: 10,
+    y: 20,
+  }),
+).toBeVoid();
+expectTypeOf(mySource["_createShapes"]()).toBeVoid();
+
+const someBackgroundShader = BackgroundVisionShader.create();
+expectTypeOf(
+  mySource["_configureLayer"](
+    {
+      active: true,
+      blendMode: "SATURATION",
+      defaultShader: BackgroundVisionShader,
+      mesh: undefined,
+      reset: false,
+      suppressed: false,
+      shader: someBackgroundShader,
+      vmUniforms: {
+        foo: 7,
+        bar: new PIXI.Matrix(),
+      },
+    },
+    "background",
+  ),
+).toBeVoid();
+
+expectTypeOf(mySource["_configure"]({})).toBeVoid();
+expectTypeOf(mySource["_getPolygonConfiguration"]()).toEqualTypeOf<PointVisionSource.PolygonConfig>();
+
+expectTypeOf(mySource["_createLightPolygon"]()).toEqualTypeOf<PointSourcePolygon>();
+expectTypeOf(mySource["_createRestrictedPolygon"]()).toEqualTypeOf<PointSourcePolygon>();
+
+expectTypeOf(mySource["_configureShaders"]()).toEqualTypeOf<
+  Record<keyof RenderedEffectSource.Layers, AdaptiveVisionShader.AnyConstructor>
+>();
+
+expectTypeOf(mySource["_updateColorationUniforms"]()).toBeVoid();
+expectTypeOf(mySource["_updateIlluminationUniforms"]()).toBeVoid();
+expectTypeOf(mySource["_updateBackgroundUniforms"]()).toBeVoid();
+expectTypeOf(mySource["_updateCommonUniforms"](someBackgroundShader)).toBeVoid();
+
+expectTypeOf(
+  mySource["_updateVisionModeUniforms"](someBackgroundShader, [
+    ["foo", 7],
+    ["baz", [1, 1, 0, 1]],
+  ]),
+).toBeVoid();
diff --git a/tests/foundry/client-esm/canvas/sources/rendered-effect-source.mjs.test-d.ts b/tests/foundry/client-esm/canvas/sources/rendered-effect-source.mjs.test-d.ts
deleted file mode 100644
index db8d2a527..000000000
--- a/tests/foundry/client-esm/canvas/sources/rendered-effect-source.mjs.test-d.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-import { expectTypeOf } from "vitest";
-
-const mySource = new foundry.canvas.sources.RenderedEffectSource();
-const meshes = mySource.drawMeshes();
-expectTypeOf(mySource.active).toEqualTypeOf<boolean>();
-expectTypeOf(meshes.background?.visible).toEqualTypeOf<boolean | undefined>();
diff --git a/tests/foundry/client-esm/canvas/sources/rendered-effect-source.test-d.ts b/tests/foundry/client-esm/canvas/sources/rendered-effect-source.test-d.ts
new file mode 100644
index 000000000..d5e6d10c2
--- /dev/null
+++ b/tests/foundry/client-esm/canvas/sources/rendered-effect-source.test-d.ts
@@ -0,0 +1,157 @@
+import { expectTypeOf } from "vitest";
+import type RenderedEffectSource from "../../../../../src/foundry/client-esm/canvas/sources/rendered-effect-source.d.mts";
+
+declare class MyRenderedSource extends foundry.canvas.sources.RenderedEffectSource {
+  protected override _createShapes(): void;
+}
+
+expectTypeOf(MyRenderedSource["_initializeShaderKeys"]).toEqualTypeOf<string[]>();
+expectTypeOf(MyRenderedSource["_refreshUniformsKeys"]).toEqualTypeOf<string[]>();
+expectTypeOf(MyRenderedSource["_layers"]).toEqualTypeOf<Record<string, RenderedEffectSource.LayerConfig>>();
+expectTypeOf(MyRenderedSource.EDGE_OFFSET).toBeNumber();
+expectTypeOf(MyRenderedSource.defaultData).toEqualTypeOf<RenderedEffectSource.SourceData>();
+
+expectTypeOf(
+  MyRenderedSource.getCorrectedLevel(CONST.LIGHTING_LEVELS.BRIGHT),
+).toMatchTypeOf<foundry.CONST.LIGHTING_LEVELS>();
+expectTypeOf(
+  MyRenderedSource.getCorrectedColor(
+    CONST.LIGHTING_LEVELS.HALFDARK,
+    Color.from("9C9C9C"),
+    Color.from([0.2, 0.7, 0.65]),
+  ),
+).toEqualTypeOf<Color>();
+expectTypeOf(
+  MyRenderedSource.getCorrectedColor(
+    CONST.LIGHTING_LEVELS.HALFDARK,
+    Color.from("9C9C9C"),
+    Color.from([0.2, 0.7, 0.65]),
+    Color.from(0x0),
+  ),
+).toEqualTypeOf<Color>();
+expectTypeOf(
+  MyRenderedSource.getCorrectedColor(
+    CONST.LIGHTING_LEVELS.HALFDARK,
+    Color.from("9C9C9C"),
+    Color.from([0.2, 0.7, 0.65]),
+    null,
+  ),
+).toEqualTypeOf<Color>();
+
+const mySource = new MyRenderedSource();
+
+expectTypeOf(mySource.animation).toEqualTypeOf<RenderedEffectSource.StoredAnimationConfig>();
+
+// if there's a `darknessShader`, it's a `DarknessAnimationConfig`
+if (mySource.animation.darknessShader) {
+  expectTypeOf(mySource.animation.darknessShader).toEqualTypeOf<AdaptiveDarknessShader.AnyConstructor>();
+} else {
+  expectTypeOf(mySource.animation.illuminationShader).toEqualTypeOf<
+    AdaptiveIlluminationShader.AnyConstructor | undefined | null
+  >();
+  expectTypeOf(mySource.animation.colorationShader).toEqualTypeOf<
+    AdaptiveColorationShader.AnyConstructor | undefined | null
+  >();
+  expectTypeOf(mySource.animation.backgroundShader).toEqualTypeOf<
+    AdaptiveBackgroundShader.AnyConstructor | undefined | null
+  >();
+}
+
+expectTypeOf(mySource.layers).toEqualTypeOf<RenderedEffectSource.Layers>();
+expectTypeOf(mySource.layers.background.mesh).toEqualTypeOf<PointSourceMesh | undefined>();
+
+expectTypeOf(mySource.colorRGB).toEqualTypeOf<Color.RGBColorVector | null>();
+expectTypeOf(mySource["_geometry"]).toEqualTypeOf<PIXI.Geometry | null>();
+expectTypeOf(mySource.isAnimated).toBeBoolean();
+expectTypeOf(mySource.hasActiveLayer).toBeBoolean();
+expectTypeOf(mySource.isPreview).toBeBoolean();
+
+expectTypeOf(mySource.background).toEqualTypeOf<PointSourceMesh>();
+expectTypeOf(mySource.coloration).toEqualTypeOf<PointSourceMesh>();
+expectTypeOf(mySource.illumination).toEqualTypeOf<PointSourceMesh>();
+
+// only new SourceData keys tested here, thorough tests are on the final Point*Source classes
+expectTypeOf(
+  mySource["_initialize"]({
+    color: 0xfedcba,
+    preview: true,
+    seed: 420,
+    animation: {
+      label: "MYSOURCE.SomeAnimation.Label",
+      animation: foundry.canvas.sources.RenderedEffectSource.prototype.animateTime,
+      darknessShader: BlackHoleDarknessShader,
+    },
+  }),
+).toBeVoid();
+expectTypeOf(
+  mySource["_initialize"]({
+    color: null,
+    preview: false,
+    seed: null,
+    animation: {
+      label: "MYSOURCE.SomeOtherAnimation.Label",
+      animation: foundry.canvas.sources.RenderedEffectSource.prototype.animateTime,
+      illuminationShader: FlameIlluminationShader,
+      colorationShader: FlameColorationShader,
+      seed: 42,
+    },
+  }),
+).toBeVoid();
+
+expectTypeOf(mySource["_initializeSoftEdges"]()).toBeVoid();
+expectTypeOf(mySource["_configure"]({})).toBeVoid();
+expectTypeOf(mySource["_configureShaders"]()).toEqualTypeOf<
+  Record<keyof RenderedEffectSource.Layers, AdaptiveLightingShader.AnyConstructor>
+>();
+
+const someBackgroundShader = AdaptiveBackgroundShader.create();
+expectTypeOf(
+  mySource["_configureLayer"](
+    {
+      active: true,
+      blendMode: "COLOR_BURN",
+      defaultShader: AdaptiveBackgroundShader,
+      mesh: undefined,
+      reset: false,
+      suppressed: false,
+      shader: someBackgroundShader,
+      vmUniforms: undefined,
+    },
+    "background",
+  ),
+).toBeVoid();
+
+expectTypeOf(mySource["_updateGeometry"]()).toBeVoid();
+expectTypeOf(mySource.drawMeshes().coloration).toEqualTypeOf<PointSourceMesh | null>();
+expectTypeOf(mySource["_drawMesh"]("illumination")).toEqualTypeOf<PointSourceMesh | null>();
+
+expectTypeOf(mySource["_updateCommonUniforms"](someBackgroundShader)).toBeVoid();
+expectTypeOf(mySource["_updateBackgroundUniforms"]()).toBeVoid();
+expectTypeOf(mySource["_updateColorationUniforms"]()).toBeVoid();
+expectTypeOf(mySource["_updateIlluminationUniforms"]()).toBeVoid();
+expectTypeOf(mySource["_destroy"]()).toBeVoid();
+
+expectTypeOf(mySource.animate(0.8)).toBeVoid();
+expectTypeOf(mySource.animateTime(1)).toBeVoid();
+expectTypeOf(
+  mySource.animateTime(1, {
+    intensity: undefined,
+    reverse: null,
+    speed: undefined,
+  }),
+).toBeVoid();
+expectTypeOf(
+  mySource.animateTime(1, {
+    intensity: 7,
+    reverse: true,
+    speed: 3,
+  }),
+).toBeVoid();
+
+const meshes = mySource.drawMeshes();
+expectTypeOf(mySource.active).toEqualTypeOf<boolean>();
+expectTypeOf(meshes.background?.visible).toEqualTypeOf<boolean | undefined>();
+
+//deprecated since v11, until v13
+expectTypeOf(mySource.preview).toBeBoolean();
+expectTypeOf((mySource.preview = false)).toBeBoolean();
diff --git a/tests/foundry/client/pixi/groups/effects.test-d.ts b/tests/foundry/client/pixi/groups/effects.test-d.ts
index 1b6a98f0b..a427a9060 100644
--- a/tests/foundry/client/pixi/groups/effects.test-d.ts
+++ b/tests/foundry/client/pixi/groups/effects.test-d.ts
@@ -19,4 +19,6 @@ expectTypeOf(myEffectGroup.animateDarkness(3, { duration: 40000 })).toEqualTypeO
 
 //deprecated since v12 until v14
 expectTypeOf(myEffectGroup.visibility).toMatchTypeOf<CanvasVisibility.Any>();
-expectTypeOf(myEffectGroup.globalLightSource).toMatchTypeOf<foundry.canvas.sources.GlobalLightSource.Any>();
+expectTypeOf(
+  myEffectGroup.globalLightSource,
+).toEqualTypeOf<foundry.canvas.sources.GlobalLightSource.ConfiguredInstance>();
diff --git a/tests/foundry/client/pixi/groups/environment.test-d.ts b/tests/foundry/client/pixi/groups/environment.test-d.ts
index 23c91512d..6ae4cde09 100644
--- a/tests/foundry/client/pixi/groups/environment.test-d.ts
+++ b/tests/foundry/client/pixi/groups/environment.test-d.ts
@@ -18,7 +18,9 @@ expectTypeOf(
   }),
 ).toEqualTypeOf<void>();
 expectTypeOf(myEnvironmentGroup.layers).toEqualTypeOf<CanvasGroupMixin.LayersFor<"environment">>();
-expectTypeOf(myEnvironmentGroup.globalLightSource).toMatchTypeOf<foundry.canvas.sources.GlobalLightSource.Any>();
+expectTypeOf(
+  myEnvironmentGroup.globalLightSource,
+).toEqualTypeOf<foundry.canvas.sources.GlobalLightSource.ConfiguredInstance>();
 expectTypeOf(myEnvironmentGroup.darknessLevel).toEqualTypeOf<number>();
 expectTypeOf(myEnvironmentGroup.colors.ambientBrightest).toEqualTypeOf<Color | undefined>();
 expectTypeOf(myEnvironmentGroup.weights.bright).toEqualTypeOf<number | undefined>();