Skip to content

Latest commit

 

History

History
351 lines (264 loc) · 10.8 KB

File metadata and controls

351 lines (264 loc) · 10.8 KB

rewrite.md — keeping the 3D fork in sync with upstream Phaser

What this file is for. When a new upstream Phaser version is released, the maintainer wants to drag the official src/ over our fork without overwriting our 3D work. This document is the canonical list of:

  1. New folders we added that upstream does not know about (just copy them across — they never collide).
  2. Existing 2D files we modified (these are the only files that need a manual rebase / patch on each upstream sync).
  3. Files outside src/ that need touching (webpack flags + cache plumbing).

Keep this document in sync with reality. Every time you edit a file in src/ that did not originally belong to the 3D fork, add it to §2 with a short description of the patch.


1. New folders / files (drop-in, never collide)

These directories were created by the 3D fork. Upstream Phaser does not contain them, so there is nothing to merge — they live alongside the 2D code and can be copied as-is when transplanted to another Phaser checkout.

Path What it owns
src/renderer/webgl3d/ The 3D renderer itself (WebGL3DRenderer, MaterialManager, Material, shaders/).
src/cameras/3d/ Camera3D, PerspectiveCamera, OrthographicCamera, Frustum, Ray3D, CameraManager3D.
src/gameobjects3d/ Object3D, Mesh3D, SkinnedMesh3D, InstancedMesh3D, Billboard3D, BlobShadow3D, primitives, GameObjectFactory3D.
src/lights3d/ Light3D and subclasses (Ambient, Directional, Point, Spot) + LightManager3D.
src/loader3d/ GLTFFile, GLTFParser, GLTFAsset (glTF 2.0 loader).
src/animation3d/ AnimationMixer3D (skeletal animation runtime).

Procedure on upstream sync: leave these folders alone. They never need patching against upstream because upstream does not touch them.


2. Existing Phaser 2D files we modified

These are the only files outside §1 that the 3D fork has touched. They are the points that conflict when arrastras the new upstream src/ on top of ours. Each one has a short description, the exact spot of the change, and the rationale.

Every patch is gated behind the WEBGL3D_RENDERER webpack flag where possible, so the upstream behaviour stays intact when the flag is off.

2.1 src/const.js

What changed: a single new constant after RIGHT: 8.

//  Direction constants … RIGHT: 8,

/**
 * Forces Phaser to use the experimental WebGL 3D Renderer. … (full
 * docblock as in the file)
 *
 * @name Phaser.WEBGL3D
 * @const
 * @type {number}
 * @since 4.2.0
 */
WEBGL3D: 9

Rebase rule: paste the WEBGL3D: 9 entry into the new upstream const.js. If upstream has added new direction constants, just make sure WEBGL3D keeps a unique numeric slot.

2.2 src/cache/CacheManager.js

What changed: two additions.

  1. New cache slot in the constructor:

    this.gltf = new BaseCache();

    With a /** @name Phaser.Cache.CacheManager#gltf */ block, placed right after this.atlas (last upstream cache).

  2. New entry in the destroy() keys array:

    var keys = [
        'binary', 'bitmapFont', 'json', 'physics', 'shader', 'audio',
        'video', 'text', 'html', 'tilemap', 'xml', 'atlas',
        'gltf'         // ← added
    ];

Rebase rule: re-apply both additions. If upstream adds more cache slots, push 'gltf' onto whatever keys array they end up with.

2.3 src/phaser.js

What changed: bottom-of-file feature flag block exposing the 3D namespaces.

if (typeof WEBGL3D_RENDERER)
{
    Phaser.GameObjects3D = require('./gameobjects3d');
    Phaser.Lights3D = require('./lights3d');
    //  …add new namespaces here if we expose anything else.
}

Note that Phaser.Cameras.ThreeD is exposed via src/cameras/index.js (see 2.6), and Phaser.Renderer.WebGL3D via src/renderer/index.js (see 2.7); both are pulled in transitively.

Rebase rule: re-add the block at the end of the upstream phaser.js. The block does not depend on anything 2D-specific.

2.4 src/scene/InjectionMap.js

What changed: three new keys at the end of the injection map.

//  WebGL3D scene plugins.
cameras3d: 'cameras3d',
add3D: 'add3D',
lights3d: 'lights3d'

These keys are the mapping strings registered by CameraManager3D, GameObjectFactory3D and LightManager3D via PluginCache.register.

Rebase rule: paste the three lines at the bottom of the map.

2.5 src/plugins/DefaultPlugins.js

What changed: a new feature-flagged block that adds the three 3D scene plugins to DefaultScene.

if (typeof WEBGL3D_RENDERER)
{
    DefaultPlugins.DefaultScene.push('CameraManager3D');
    DefaultPlugins.DefaultScene.push('GameObjectFactory3D');
    DefaultPlugins.DefaultScene.push('LightManager3D');
}

Placed after the existing PLUGIN_CAMERA3D block, before the PLUGIN_FBINSTANT block.

Rebase rule: paste the block back. Order does not matter as long as the WEBGL3D_RENDERER flag exists and DefaultPlugins.DefaultScene is the array we are pushing onto.

2.6 src/cameras/index.js

What changed: a feature-flagged tail block exposing the 3D camera namespace.

if (typeof WEBGL3D_RENDERER)
{
    module.exports.ThreeD = require('./3d');
}

Rebase rule: append at the end of the file.

2.7 src/renderer/index.js

What changed: a feature-flagged tail block alongside the existing WEBGL_RENDERER / CANVAS_RENDERER blocks.

if (typeof WEBGL3D_RENDERER)
{
    module.exports.WebGL3D = require('./webgl3d');
}

Rebase rule: append at the end of the file, after the existing renderer blocks.

2.8 src/core/CreateRenderer.js

What changed: three small spots.

  1. Validation branch in the renderType switch:

    else if (config.renderType === CONST.WEBGL3D)
    {
        if (!Features.webGL2)
        {
            throw new Error('Cannot create WebGL2 context (required by WEBGL3D renderer), aborting.');
        }
    }
  2. Variable declaration alongside the existing two:

    var CanvasRenderer;
    var WebGLRenderer;
    var WebGL3DRenderer;
  3. Early-return branch for the 3D renderer, placed before the regular WebGL / Canvas selection block so it short-circuits:

    if (typeof WEBGL3D_RENDERER && config.renderType === CONST.WEBGL3D)
    {
        WebGL3DRenderer = require('../renderer/webgl3d/WebGL3DRenderer');
        game.renderer = new WebGL3DRenderer(game);
        return;
    }

Rebase rule: re-apply all three. If upstream rewrites CreateRenderer.js significantly (it sometimes does), keep the same logic: validate Features.webGL2 for WEBGL3D, and short-circuit before the WebGL / Canvas fork.

2.9 src/device/Features.js

What changed: a webGL2 flag plus a testWebGL2() probe.

  1. New property on the Features object (alongside webGL: false):

    webGL2: false
  2. New JSDoc line in the Phaser.Device.Features typedef:

    //  @property {boolean} webGL2 - Indicates whether WebGL2 is available …
  3. New probe function inside init():

    var testWebGL2 = function () {
        if (!window['WebGL2RenderingContext']) { return false; }
        try {
            var canvas = CanvasPool.createWebGL(this);
            var ctx = canvas.getContext('webgl2');
            CanvasPool.remove(canvas);
            return !!ctx;
        }
        catch (e) { return false; }
    };
    Features.webGL2 = testWebGL2();

    Placed right after the existing Features.webGL = testWebGL();.

Rebase rule: re-add the property, the doc line and the probe. The probe is a self-contained block; it should drop in regardless of upstream changes.


3. Files outside src/ that need touching

These are not Phaser source files but they live in the same repository and must be kept patched when syncing.

3.1 config/webpack.config.js

new webpack.DefinePlugin({
    "typeof CANVAS_RENDERER": JSON.stringify(true),
    "typeof WEBGL_RENDERER":  JSON.stringify(true),
    "typeof WEBGL3D_RENDERER": JSON.stringify(true),     // ← added
    ...
});

3.2 config/webpack.dist.config.js

Two DefinePlugin blocks (debug + dist). Both need the WEBGL3D_RENDERER: JSON.stringify(true) line.

3.3 config/webpack-nospector.config.js

Same: one DefinePlugin block, same line added.

Rebase rule: drop the flag back in every webpack config that upstream ships. Tree-shaking depends on it.


4. The mechanical sync procedure

  1. Take the new upstream src/ (and config/ if it changed) into a scratch folder.
  2. Diff against your fork for each path listed in §2 and §3. The patch is small and well-bounded in every file; review and apply manually.
  3. Drag the files NOT in §2 and §3 from the new upstream into your fork. They cannot conflict with the 3D fork — none of them are touched.
  4. Leave §1 folders alone in your fork. They are exclusively yours.
  5. Run npm run build at the repo root. If the build is green, your fork is up to date with upstream + still ships 3D.
  6. Run npm run build in examples/vite-3d. If the sandbox boots, the integration still holds.
  7. Hand-smoke-test #/hello-cube, #/gltf-static, #/instanced-cubes and #/mix-3d-ui (when it exists). If they render, you are done.

5. Hard rules

These are the discipline guarantees that keep this list short:

  1. New 3D code goes in §1 folders only. If you find yourself wanting to edit a non-3D file, ask first whether a small new helper inside src/renderer/webgl3d/ could solve it instead.
  2. All non-3D file edits must be gated behind if (typeof WEBGL3D_RENDERER) so a build without the flag behaves like upstream Phaser.
  3. Every new modification of a 2D file must be reflected in §2 of this document in the same PR. No exceptions.
  4. No reformats / whitespace-only changes in 2D files. They inflate diffs and cause unnecessary merge conflicts on sync.
  5. Avoid renaming anything in §2. If a downstream change demands it, document the rename + reason here so the next sync knows.

6. Files explicitly NOT modified (so you do not panic)

Some 2D files reference 3D only through the public API (e.g. they load Phaser.Renderer.WebGL3D through the renderer index). These look suspicious in a grep for WEBGL3D but are NOT in our patch list:

  • src/textures/TextureSource.js — already had this.renderer.deleteTexture(...). We made sure WebGL3DRenderer exposes deleteTexture; we did not modify TextureSource.js.
  • src/core/Config.js — the webgl3d config block is read by WebGL3DRenderer directly via gameConfig.webgl3d. No upstream code change needed.

If you see these turn up in a grep, double-check before adding them to §2; in most cases they belong here in §6 instead.