Help Needed with 404 Error in Babylon.js Project with Webpack Dev Server

Hello Babylon.js Community,

I’m working on a Babylon.js project using webpack and webpack-dev-server, and I’ve run into a persistent issue that I hope you might be able to help me with.

Whenever I try to load a .glb file in my project using the SceneLoader.LoadAssetContainer function, I receive a 404 error in the console. The issue only happens in the development environment when using webpack-dev-server. The file loads successfully when I use the built version of the project, suggesting that the issue might be with webpack-dev-server or my configuration of it.

Here is the code I’m using to load the .glb file:
player.ts


import { Mesh, Scene, SceneLoader, AssetContainer } from “@babylonjs/core”;
import { Vector3, Quaternion, Matrix } from “@babylonjs/core/Maths/math”;
import { GLTFFileLoader } from ‘@babylonjs/loaders’;
import { PointerEventTypes } from “@babylonjs/core”;

// Register the GLTF file loader
SceneLoader.RegisterPlugin(new GLTFFileLoader());

export class Player {
private _mesh: Mesh;
private _scene: Scene;
private _targetPosition: Vector3;
private _initialPosition: Vector3;
public _isMoving: boolean = false;
public _isTurning: boolean = false;
private _currentDirection: Vector3;
private _turnStepSize: number; // The amount to turn by in each step, in degrees
private _maxTurn: number; // The maximum amount the player can turn, in degrees
private _targetAngle: number; // The angle that the player is trying to turn to
private _position: Vector3;
private _modelPath: string;

constructor(scene: Scene, modelPath: string, initialPosition: Vector3) {
this._scene = scene;
this._targetPosition = Vector3.Zero();
this._isMoving = false;
this._isTurning = false;
this._initialPosition = initialPosition.clone();
this._position = initialPosition.clone();
this._modelPath = modelPath;

// Set forward direction based on model's orientation
this._currentDirection = new Vector3(0, 1, 0);  // Replace with your model's forward vector
this._turnStepSize = 60; // Adjust as needed
this._maxTurn = 360; // Adjust as needed

// Subscribe to pointer events
scene.onPointerObservable.add((pointerInfo) => {
  switch (pointerInfo.type) {
    case PointerEventTypes.POINTERDOWN:
      const pickResult = scene.pick(pointerInfo.event.clientX, pointerInfo.event.clientY);
      if (pickResult && pickResult.hit) {
        this.setTargetPosition(pickResult.pickedPoint);
        this._isMoving = true;
        this._isTurning = true;
      }
      break;
  }
});

this.load();

}

public async load(): Promise {
console.log(Loading model from: ${this._modelPath}); // Debug print statement

return new Promise((resolve, reject) => {
  SceneLoader.LoadAssetContainer(
    "",
    this._modelPath,
    this._scene,
    (container: AssetContainer) => {
      container.addAllToScene();
      if (container.meshes.length > 0) {
        this._mesh = container.meshes[0] as Mesh;
        this._mesh.position = this._initialPosition; // Set the mesh position here
        this._position = this._mesh.position.clone(); // Update _position here
        // Rest of the code...
      //  this._mesh.addRotation(0, Math.PI/2, 0);
      } else {
        reject(new Error('No meshes found in the player model'));
      }
    },
    null, 
    (message, exception) => {
      // Handle errors during loading
      reject(exception);
    }
  );
});

}


HexWorld.ts:


import * as BABYLON from ‘@babylonjs/core’;

import { GLTFFileLoader } from ‘@babylonjs/loaders’;

import { SkyMaterial, WaterMaterial } from ‘@babylonjs/materials’;

import { HexTile } from ‘…/HexTile’;

import store from ‘store’;

// Register the GLTF loader plugin

BABYLON.SceneLoader.RegisterPlugin(new GLTFFileLoader());

previous code

load(): Promise {
return new Promise((resolve) => {
this.prepareCamera();
this.prepareLights();
this.prepareEnvironment();

         // Register the GLTF loader plugin
         //BABYLON.SceneLoader.RegisterPlugin(new GLTFFileLoader());

        // Initialize the players
        const playerModels = [
          "/Resources/models/yacht2.glb", 
          "/Resources/models/1067.glb", 
          "/Resources/models/2186.glb", 
          "/Resources/models/2774.glb",
          /* more model paths... */
        ];
        
        const initialPositions = [new Vector3(0, 0, 0), new Vector3(10, 0, 0), new Vector3(20, 0, 0), new Vector3(30, 0, 0) /* more initial positions... */];
     

        const players = playerModels.map((modelPath, index) => {
          const player = new Player(this.scene, modelPath, initialPositions[index]);
          return player;
        });
        
        Promise.all(players.map(player => player.load()))
        .then(() => {
          console.log("All player models loaded successfully");
        })
        .catch((error) => {
          console.error("Error loading player models: ", error);
        });
        
      

        // ... more setup code ...
        
        this.prepareNetwork();
  
        // Hide preloader
        this.scene.getEngine().hideLoadingUI();
  
        // Force pointer lock
        GameManager.inputManager.setForcePointerLock(true);

        this.scene.onPointerObservable.add((pointerInfo) => {
          switch (pointerInfo.type) {
            case BABYLON.PointerEventTypes.POINTERDOWN:
              const pickResult = this.scene.pick(pointerInfo.event.clientX, pointerInfo.event.clientY);
              if (pickResult && pickResult.hit) {
                const clickedMesh = pickResult.pickedMesh;
                if (clickedMesh instanceof BABYLON.InstancedMesh) {
                  this.player.setTargetPosition(clickedMesh.position);
                  this.player._isMoving = true;
                  this.player._isTurning = true;
                }
              }
              break;
            
            
          }
        });
        

        resolve(this);
  });
}

And here is my webpack config:


const path = require(‘path’);
const HtmlWebpackPlugin = require(‘html-webpack-plugin’);
const CopyWebpackPlugin = require(‘copy-webpack-plugin’);

module.exports = {
entry: {
main: ‘./src/index.ts’,
},
module: {
rules: [
{
test: /.tsx?$/,
loader: ‘ts-loader’,
exclude: /node_modules/,
options: {
compilerOptions: {
sourceMap: true,
esModuleInterop: true,
},
},
},
{
test: /.s[ac]ss$/i,
use: [
{ loader: ‘style-loader’ },
{ loader: ‘css-loader’ },
{ loader: ‘sass-loader’ },
],
},
{
test: /.(jpg|png|gif|env|dds|hdr|glb|gltf)$/i,
use: [
{
loader: ‘url-loader’,
options: {
limit: false,
name: ‘static/resources/[name].[hash:8].[ext]’,
},
},
],
},
{
test: /.fx/i,
use: [
{
loader: ‘raw-loader’,
},
],
},
],
},
resolve: {
extensions: [‘.tsx’, ‘.ts’, ‘.js’],
},
plugins: [
new HtmlWebpackPlugin({
inject: true,
template: ‘./public/index.html’,
}),
new CopyWebpackPlugin({
patterns: [
{ from: ‘./src/Resources/’, to: ‘Resources’ },
],
}),
],
output: {
filename: ‘static/js/[name].[fullhash:8].js’,
chunkFilename: ‘static/js/[name].[fullhash:8].chunk.js’,
path: path.resolve(__dirname, ‘public’),
publicPath: ‘/’,

},
devServer: {
static: path.join(__dirname, ‘public/’),
watchFiles: [“src/**/*”],
devMiddleware: {
// contentBase: path.join(__dirname, ‘public’), // serve from public folder
publicPath: ‘/’ // make sure publicPath is root
},
port: 8080,
hot: true,
compress: true,

}
};


I’ve tried various solutions such as checking the file paths and names, modifying the webpack configuration (like changing the publicPath and contentBase options), updating the webpack-dev-server to the latest version, and double-checking the HTMLWebpackPlugin configuration. Unfortunately, none of these attempts have resolved the issue.

This is the error I encounting:


[webpack-dev-server] Server started: Hot Module Replacement enabled, Live Reloading enabled, Progress disabled, Overlay enabled.
log.js:24 [HMR] Waiting for update signal from WDS…
thinEngine.js:603 Babylon.js v6.4.0 - WebGL2 - Parallel shader compilation
Player.ts:56 Loading model from: /Resources/models/yacht2.glb
logger.js:49 BJS - [02:03:19]: Wrong sceneFilename parameter
_LogEnabled @ logger.js:49
Player.ts:56 Loading model from: /Resources/models/1067.glb
logger.js:49 BJS - [02:03:19]: Wrong sceneFilename parameter
_LogEnabled @ logger.js:49
Player.ts:56 Loading model from: /Resources/models/2186.glb
logger.js:49 BJS - [02:03:19]: Wrong sceneFilename parameter
_LogEnabled @ logger.js:49
Player.ts:56 Loading model from: /Resources/models/2774.glb
logger.js:49 BJS - [02:03:19]: Wrong sceneFilename parameter
_LogEnabled @ logger.js:49
Player.ts:56 Loading model from: /Resources/models/yacht2.glb
logger.js:49 BJS - [02:03:19]: Wrong sceneFilename parameter
_LogEnabled @ logger.js:49
Player.ts:56 Loading model from: /Resources/models/1067.glb
logger.js:49 BJS - [02:03:19]: Wrong sceneFilename parameter
_LogEnabled @ logger.js:49
Player.ts:56 Loading model from: /Resources/models/2186.glb
logger.js:49 BJS - [02:03:19]: Wrong sceneFilename parameter
_LogEnabled @ logger.js:49
Player.ts:56 Loading model from: /Resources/models/2774.glb
logger.js:49 BJS - [02:03:19]: Wrong sceneFilename parameter


Any insight or advice you could provide would be greatly appreciated. Thank you in advance for your help!

With kind regards,
Deny Heam

Hi!

I use vite instead of webpack but it should be te same approach so let’s try this: Put your models in the public folder of your app. For example you’ll end up with:

image

The cube will be accessible at /models/cube.glb so to load it:

await SceneLoader.ImportMeshAsync(
  null,
  '/models/',
  'cube.glb'
);
1 Like

Still not working :confused: I have attached some screenshots:


The versions I use:

Babylonjs:

├─┬ babylonjs-gui@5.0.0-alpha.65
│ └── babylonjs@5.0.0-alpha.65
├─┬ babylonjs-inspector@5.0.0-alpha.65
│ ├─┬ babylonjs-loaders@5.0.0-alpha.65
│ │ └── babylonjs@5.0.0-alpha.65 deduped
│ ├─┬ babylonjs-materials@5.0.0-alpha.65
│ │ └── babylonjs@5.0.0-alpha.65
│ ├─┬ babylonjs-serializers@5.0.0-alpha.65
│ │ └── babylonjs@5.0.0-alpha.65
│ └── babylonjs@5.0.0-alpha.65
├─┬ babylonjs-loaders@5.57.1
│ └── babylonjs@5.57.1
└── babylonjs@6.8.0

Webpack:

├─┬ clean-webpack-plugin@3.0.0
│ └── webpack@5.82.0 deduped
├─┬ copy-webpack-plugin@11.0.0
│ └── webpack@5.82.0 deduped
├─┬ css-loader@3.6.0
│ └── webpack@5.82.0 deduped
├─┬ css-minimizer-webpack-plugin@2.0.0
│ └── webpack@5.82.0 deduped
├─┬ file-loader@6.2.0
│ └── webpack@5.82.0 deduped
├─┬ html-webpack-plugin@5.5.0
│ └── webpack@5.82.0 deduped
├─┬ mini-css-extract-plugin@1.6.2
│ └── webpack@5.82.0 deduped
├─┬ raw-loader@4.0.2
│ └── webpack@5.82.0 deduped
├─┬ sass-loader@10.2.0
│ └── webpack@5.82.0 deduped
├─┬ style-loader@2.0.0
│ └── webpack@5.82.0 deduped
├─┬ terser-webpack-plugin@2.3.8
│ └── webpack@5.82.0 deduped
├─┬ ts-loader@8.3.0
│ └── webpack@5.82.0 deduped
├─┬ url-loader@4.1.1
│ └── webpack@5.82.0 deduped
├─┬ webpack-cli@4.9.1
│ ├─┬ @webpack-cli/configtest@1.1.0
│ │ └── webpack@5.82.0 deduped
│ └── webpack@5.82.0 deduped
├─┬ webpack-dev-server@4.15.0
│ ├─┬ webpack-dev-middleware@5.3.3
│ │ └── webpack@5.82.0 deduped
│ └── webpack@5.82.0 deduped
└─┬ webpack@5.82.0
└─┬ terser-webpack-plugin@5.3.7
└── webpack@5.82.0 deduped

Can you share a github repository or your whole project zipped? You can do it in a private message if you don’t want to share it with everyone. I will point out the error in no time :sunglasses: I hope so :joy::joy::joy:

2 Likes

So, this seems a bit odd, because you are using the @babylonjs packages (es6) but referenced the UMD packages. Also - the versions are inconsistent.

Now - to the direct error - I believe you are using the loader incorrectly. Probably not providing one of the variables needed. But as @roland said - it is very hard to understand without seeing the code in a structured way.

Hi :smiley: , here is the link to the github repo @RaananW @roland : GitHub - apeharbour/Babylon_Warships at alpha

Hey!

This doesn’t show the errors you were asking about, only a bunch of warnings and an another error:

1 Like

Did you have check-out the alpha branch? This is the latest one :slight_smile:

Damned, I just clicked on the link… Wait a moment

That’s because you don’t have an alpha branch.

However, dude, sorry, but this is a total mess :see_no_evil: Don’t worry, I’ll tide up your code and write an explanation what did you wrong and how has to be done it the correct way just push your alpha brach online.

As @RaananW wrote:

2 Likes

1 Like

Hey, thanks a lot! The alpha branch should be up-to-date. The latest change I have done was yesterday, checked with “multiple player importer”.

Offtopic question. Will it be a turn-based game?

Yes! A turned-based warship game :slight_smile:

Yes the warship is obvious from the repo name :stuck_out_tongue:

As @RaananW wrote:

Do you have an action plan or recommendations for me? :slight_smile:

I wrote you that I’ll explain you how to do it corretly.

The other thing is that even in this branch there is no call to the player.load() function in the whole project. I’ll create one.

Now it breaks on:

Because you don’t set GameManager.assetManager to I don’t know what was the intention here.

image

1 Like

So:

  1. package.json
    remove all other packages, leave there only these 3:
    image

Please read this:

  1. all your imports must come from `@babylonjs/…’ packages. (READ the previous article :smiley: ) So I’ve changed all your imports to for example:
import { SkyMaterial } from '@babylonjs/materials'
import { ArcRotateCamera, ArcRotateCameraKeyboardMoveInput, ArcRotateCameraMouseWheelInput, ArcRotateCameraPointersInput, Color3, HemisphericLight, MeshBuilder, StandardMaterial, Tools, Vector3 } from '@babylonjs/core';

and that’s it!

Fix your program logic, so the assetManager is not undefined and I can help you further if you get stuck.

And I fixed your sky as well:

EDIT: I’ve opened a pull request, so you don’t have to do it again yourself.

2 Likes

hey, thanks for your help! Unfortunately the master brunch you used as base is out dated, in the current brunch i’m working on, the alpha branch, not the master, i already made sure the imports are correct. I have reworked the json and yarn file, but still have the same error message. just pushed my changes again, can you maybe download the right allpha branch now?