Skip to content

Limits & Constraints

Understanding HoloScript's runtime limits helps you build performant applications.

Runtime Limits (All Formats)

These limits apply regardless of which file format you use:

ConstraintValueNotes
Max Nodes1,000THE critical limit
Max Execution Time5 secondsPer frame/update
Max Depth50 levelsNesting depth
Max Call Stack100Function call depth
Max Particles1,000/systemPer particle system

Critical Limit

The 1,000 node limit is the primary constraint. Design around lazy loading and object pooling to maximize capability.


Individual Format Limits

.hs Limits

LimitValue
Max File Size50KB code
Max Blocks100 per file
Max Nesting Depth10 levels
Keywords100+ available

.hsplus Limits

LimitValue
VR Traits55 available
Lifecycle Hooks80+ available
Scale Range0.1x - 10x
Inventory Stack10 items

.holo Limits

LimitValue
Compositions1 per file
TemplatesUnlimited
ObjectsUnlimited
NestingUnlimited

Combined Power

When using all formats together:

CapabilityCombined Value
VR Traits55 (stackable - 20+ per object)
Lifecycle Hooks80+ (combinable)
Builtin Functions90+
Import ChainsUnlimited
Nesting DepthUnlimited (AST level)

The Power Formula

COMBINED = .holo(∞ scene) × .hsplus(55 traits + 80 hooks) × .ts(logic)
PRACTICAL_CAP = 1,000 nodes OR 5 seconds (whichever hits first)

Optimization Strategies

Stay Under Node Limit

holo
// ❌ Bad: Creates 10,000 nodes at once
@for x in range(0, 100) {
  @for y in range(0, 100) {
    object "Tile_${x}_${y}" { position: [x, 0, y] }
  }
}

// ✅ Good: Lazy loading with chunks
spatial_group "World" {
  @lazy_load(chunk_size: 100, view_distance: 50)
  
  @for x in range(0, 100) {
    @for y in range(0, 100) {
      object "Tile_${x}_${y}" { position: [x, 0, y] }
    }
  }
}

Object Pooling

hsplus
// Create a pool of reusable objects
@pool("Bullet", capacity: 50)

function fire() {
  let bullet = pool_get("Bullet")
  bullet.position = gun.position
  bullet.velocity = aim_direction * 100
  
  delay 3s then {
    pool_return("Bullet", bullet)
  }
}

Level of Detail (LOD)

holo
object "DetailedBuilding" {
  @lod(
    near: { model: "building_high.glb", max_distance: 20 },
    mid: { model: "building_med.glb", max_distance: 100 },
    far: { model: "building_low.glb", max_distance: 500 },
    cull: { min_distance: 500 }
  )
}

Disable Distant Physics

hsplus
orb distantObject {
  @physics(enabled: distance_to_player < 50)
  @collidable(enabled: distance_to_player < 30)
}

Performance Monitoring

Built-in Stats

hsplus
@debug_overlay {
  show_node_count: true
  show_frame_time: true
  show_memory: true
}

Profiling

holo
logic {
  @profile("SpawnWave") {
    spawn_wave()
  }
  
  when node_count > 800 {
    warn("Approaching node limit!")
    cleanup_distant_objects()
  }
}

Platform-Specific Limits

PlatformRecommended NodesNotes
Quest 2500Mobile GPU
Quest 3700Better GPU
PCVR1,000Full limit
Web800Browser overhead
Mobile AR400Battery/thermal

Memory Considerations

ResourceTypical SizeLimit
Scene graph1-10 MB50 MB
Textures5-50 MB200 MB
Audio1-20 MB50 MB
Models5-100 MB500 MB

Texture Guidelines

holo
// Recommended texture sizes
object "Optimized" {
  // Mobile/Quest
  texture: "texture_1k.jpg"   // 1024x1024
  
  // PCVR
  texture: "texture_2k.jpg"   // 2048x2048
  
  // Use compressed formats
  texture: "texture.ktx2"     // GPU-compressed
}

Key Takeaway

The 1,000 node runtime limit is the only practical constraint. Everything else (imports, nesting, traits) is unlimited or very high. Design around lazy loading and object pooling to maximize capability.

Released under the MIT License.