Skip to content

Environment and Geometry

Swifter edited this page Nov 3, 2024 · 30 revisions

Prerequisites

Creating

While Heck uses a single array on the difficulty for environment and geometry objects called environment, ReMapper splits them into separate environment and geometry arrays.

map.environment
map.geometry

This also means that environment and geometry objects are separate, so Environment has no geometry object on it.

Environment

You can create an environment statement just like you would expect:

rm.environment(map, {
    id: 'Sun',
    lookupMethod: 'Contains', // lookupMethod is "Contains" by default
})

Geometry

A geometry statement is also created similarly:

rm.geometry(map, {
    type: 'Cube',
    material: {
        shader: 'Standard'
    }
})

If you are using the same material for multiple objects, it is a good idea to make materials part of the difficulty and then reference them. This allows them to all be rendered in one draw call, which is important for performance.

map.geometryMaterials['myMaterial'] = {
    shader: 'Standard'
}

rm.geometry(map, {
    type: 'Cube', // type is 'Cube' by default
    material: 'myMaterial'
})

Light ID and Light Type Shortcuts

On both Environment and Geometry, lightID and lightType will initialize the corresponding properties in the ILightWithId component:

rm.geometry(map, {
   lightID: 3,
   lightType: rm.EventGroup.BACK_LASERS
})

// equivalent to:

rm.geometry(map, {
    components: {
        ILightWithId: {
            lightID: 3,
            type: rm.EventGroup.BACK_LASERS
        }
    }
})

Regex

When trying to use the Regex lookup method on Environment, there are a lot of patterns that can be noticed:

image

To try to capitalize on these patterns, the Regex class can be used to construct a string by chaining functions.

rm.regex('LightRailingSegment').vary(2).separate(1).add('NeonTubeDirectionalL').end()

This statement targets LightRailingSegment (2).[1]NeonTubeDirectionalL, and evaluates to:

LightRailingSegment \(2\)\.\[1\]NeonTubeDirectionalL$

The rm.regex() function creates an rm.Regex class. It has an optional parameter to initialize the string. rm.Regex contains the following members:

  • string the internal string.
  • add(string: string) adds text to the end of the string.
  • end() returns the final string with $ appended, which signifies the end of the line in regex.
  • start() specifies the start of the string with the end of a previous separator: "]".
  • separate(index?: number) handles the .[x] part of IDs (e.g. Object.[0]Object).
    • If index is undefined, it will resolve to \.\[\d*\] which accepts any number.
    • If index is defined, it will resolve to \.\[<index>\], as a definite index.
  • vary(number?: number) handles the (x) part of IDs (e.g. Object (1)).
    • if number is undefined, it will resolve to (|\s\(\d*\)) which accepts any number (Object (x), or no variation at all (Object).
    • if number is defined, it will resolve to \(<number>\) as a definite variation. If number is zero, no variation at all.
  • verify() checks if the statement is a valid regex statement, or if it has syntax errors.

Removal

If you want to clear out a bunch of objects at the start of the map to make way for what you'll be doing, you can use the rm.environmentRemoval() function to list a bunch of them out.

It will take an array of strings, as well as a lookup method to construct Environment objects with. Their position will be set really far away, which virtually removes them from the scene.

// Lookup method not provided, defaults to `Contains`
rm.environmentRemoval(map, [
    'Clouds',
    'Mountains',
    'WaterRainRipples',
    'Smoke',
    'Rail',
])

// or 

rm.environmentRemoval(map, [
    'Clouds',
    'Mountains',
    'WaterRainRipples',
    'Smoke',
    'Rail',
], 'Contains')

Base Environment

The "base environment" refers to the root object in the environment hierarchy. image

rm.getBaseEnvironment will find an environment statement for this object and ensure there is only ever one in the difficulty passed to it.

You can then edit this environment statement however you want.

rm.getBaseEnvironment(map, env => {
    env.position = [0, -10000, 0]
})

An additional rm.setBaseEnvironmentTrack helper function exists that is used by the fog system.

Clone this wiki locally