fivem icon indicating copy to clipboard operation
fivem copied to clipboard

Add native event for detecting when all server resources are loaded

Open samuelds opened this issue 2 months ago • 1 comments

Segment

Native function / Event

Importancy

Missing details

Improvement request

Summary

Add a native event or function to detect when all server resources have completed their initial loading phase during server startup.

Problem

Currently, there is no reliable way to detect when the server has finished loading all configured resources. Developers need this to:

  • Initialize post-startup hooks
  • Display accurate server status
  • Ensure all dependencies are loaded before framework initialization
  • Trigger "server ready" events for plugins/modules

Current API Limitations

Existing functions provide partial information:

  • GetNumResources() - Returns detected resources (not necessarily started or configured to start)
  • GetResourceState(resourceName) - Returns state of a specific resource
  • onServerResourceStart - Fires for each individual resource

However, there's no way to know:

  • Which resources are configured to start vs. merely detected
  • When all configured resources have finished starting
  • If the server has completed initialization

Current Workarounds

Developers use unreliable workarounds:

  1. Timeout-based stability detection - Assume loading is complete after X seconds of no activity
  2. Comparing counts - Incorrectly assume startedResources.size >= GetNumResources() means done
  3. Arbitrary delays - setTimeout(() => { /* hope everything loaded */ }, 5000)

All approaches are unreliable and cannot distinguish "not started yet" from "never will start".

Proposed Solution

Option 1: Native Event (Preferred)

on('onServerResourcesReady', () => {
  console.log('All configured resources have finished loading');
});

Fires once when:

  • All resources in server.cfg have been processed
  • Incompatible resources have been skipped
  • Before or early in player connection phase

Option 2: Native Function

const isReady = AreAllResourcesLoaded();

Option 3: Extended Resource Info

const intent = GetResourceIntent(resourceName);
// Returns: 'configured' | 'detected' | 'incompatible' | 'failed'

Real-World Use Case

We're building NextGen Core Framework and need this to:

  1. Monitor when all CitizenFX resources are ready
  2. Initialize our plugin system after dependencies load
  3. Emit framework-ready event

Currently forced to use 2-second stability timeout workaround.

Benefits

  • Eliminates hacky timeout solutions
  • Provides reliable initialization point for frameworks
  • Improves developer experience
  • Enables accurate startup timing/profiling
  • Reduces race conditions

Community Impact

Would benefit:

  • All major frameworks (ESX, QBCore, custom frameworks)
  • Server monitoring tools
  • Development/debugging tools
  • Any resource requiring post-startup initialization

Area(s)

FXServer

Additional information

Current Workaround Implementation

Our temporary solution using stability detection:

class ResourceMonitor {
  constructor() {
    this.stabilityTimeout = null;
    this.stabilityDelay = 2000; // 2 seconds of no new resources = "stable"
  }

  onResourceStart(resourceName) {
    // Reset timer every time a resource starts
    if (this.stabilityTimeout) {
      clearTimeout(this.stabilityTimeout);
    }

    this.stabilityTimeout = setTimeout(() => {
      // Assume loading is complete
      emit('allResourcesLoaded');
    }, this.stabilityDelay);
  }
}

This works but is not ideal. Native support would eliminate this hack.

Related Documentation

Example Use in Framework

// Wait for CitizenFX to finish loading all resources
on('onServerResourcesReady', () => {
  console.log('Server ready - initializing framework');

  // Now safe to:
  // - Load plugins that depend on other resources
  // - Initialize cross-resource communication
  // - Display "server ready" status
});

samuelds avatar Nov 10 '25 14:11 samuelds

Hi. You can check whether all resources have started as follows:

function areAllResourceLoaded()
{
    for (let i = 0; i < GetNumResources(); ++i) {
        const resName = GetResourceByFindIndex(i);
        const resState = GetResourceState(resName);

        if (resState !== "started" && resState !== "stopped") {
            return false;
        }
    }

    return true;
}

Then, using this, you can periodically check in an interval whether everything has started, and finally clear the interval.

const interval = setInterval(() => {
    if(areAllResourceLoaded()){
        // ...

        clearInterval(interval);
    }
}, 1000);

Dani4Web avatar Dec 05 '25 11:12 Dani4Web