RUMBLE
You are viewing a potentially older version of this package. View Latest Version
Install with App

Details

Date Uploaded
2 weeks ago
Downloads
143
Size
367KB

GymMaps 1.5.0

Requires MelonLoader, UIFramework, and RumbleModdingAPI. This release renames the mod to GymMaps, removes the automatic Frogian entrance, adds the default-off command setting and audio commands, and installs default maps only once.

Included default maps

Five default maps are embedded in the mod DLL: frogian.txt, rings.txt, towers.txt, slipnslide.txt, and gridtest.txt. Frogian includes its exported firework trigger, Gym button and respawn start marker. Rings 3, Slipnslide 2, and temporary test maps are no longer bundled.

On the first successful startup installation, the mod adds missing defaults to UserData/GymMaps and records .default-maps-installed in that folder. Later launches and Refresh do not reinstall them, so deleted defaults stay deleted. Existing files and user edits are preserved. A failed installation retries on the next launch. No separate map download is needed. Extra custom .txt maps are discovered normally. Maps appear in the selector; adding files does not automatically load course geometry.

Files are staged, parsed, then moved into place without overwriting existing maps. A failed default installation logs a warning and does not stop discovery of other maps. The source/DefaultMaps folder contains the exact exported files used for this release; the project embeds every .txt file there when built.

Naming and event datatypes

Name an authoring Cube Cube<identifier>.<event>.<command>; for example CubeFinish.OnTriggerEnter.play.sound.firework. The identifier can be any useful name. Dot-event markers must be Cube primitives. Their visible mesh and solid collider are omitted in game. Their exported position, rotation, and scale remain available to commands; entry markers use the oriented Cube volume for detection.

Event datatype Runs when Example
OnMapLoad Once after this map's geometry activates and physics transforms synchronize. Runs again when the map reloads. CubeSpawn.OnMapLoad.structure.summon.wall
OnTriggerEnter The local player enters or passes through the marker volume. CubeFinish.OnTriggerEnter.play.sound.firework

Dot template names contain letters, numbers, dots, underscores and hyphens, and begin with a letter. One dot event is allowed per object. Names and recognized tags are case-insensitive. A trailing Blender duplicate suffix such as .001 is stripped from a dot template. Avoid destination map filenames ending in a dot followed by three or more digits, because that ending conflicts with the duplicate suffix syntax.

Entering fires once per crossing; standing inside does not repeat it. If already inside when tracking starts, leave and reenter. Detection uses the local physics-body center and supports fast crossings between frames. A teleport through a volume may count as entry. Multiplayer synchronization is not implemented.

All command templates

The following table lists every built-in command/template and its recommended event. Standard registered commands can also be called from (OnEnter=COMMAND arguments) tags. Load commands run after map activation; entering commands use cooldown/once rules. Commands call mod functions, not operating-system shell commands.

Template after the event Recommended event Action
structure.summon.cube OnMapLoad Summon a native RockCube on valid ground below the marker.
structure.summon.wall OnMapLoad Summon a native Wall.
structure.summon.pillar OnMapLoad Summon a native Pillar.
structure.summon.ball OnMapLoad Summon a native Ball.
structure.summon.disk OnMapLoad Summon a native Disc.
structure.summon.disc OnMapLoad Alias for structure.summon.disk.
interface.respawn.start OnMapLoad Set the local player's respawn position and facing to this marker.
interface.killfloor.height OnMapLoad Set/create the kill floor using a required (Height=NUMBER) tag.
summon.asset.button.interface.teleport.gym OnMapLoad Spawn a native button that unloads the custom course and teleports to the Gym start when pressed.
summon.asset.button.interface.teleport.map.<mapname> OnMapLoad Spawn a native button that replaces the course with the named map and teleports to its start when pressed.
map.load.<mapname>.replace OnTriggerEnter Replace the current course with the named map when entered. Does not automatically teleport.
map.load.<mapname>.append OnTriggerEnter Add the named map alongside the current course when entered. Does not automatically teleport.
play.sound.telephone OnTriggerEnter Play the existing Gym telephone notification sound at the marker.
play.sound.firework OnTriggerEnter Play the shop purchase sound bank (GearMarket.unlockPurchaseSFX) at the marker.
play.sound.clip.id-<UTF8 hex asset name> OnTriggerEnter or OnMapLoad Play any loaded audio clip by its exported dot-safe ID.
timer.start OnTriggerEnter Restart and start the race timer.
timer.stop OnTriggerEnter Stop the timer and show elapsed seconds.
timer.reset OnTriggerEnter Reset the timer to zero.
log TEXT (OnEnter=log TEXT) Write TEXT to the mod log.
status TEXT (OnEnter=status TEXT) Show TEXT in the menu Status field and log it.

log and status also accept no text in dot syntax. Use parenthesized OnEnter tags to supply spaces in command arguments. Unknown commands and missing map targets reject a load before the current course is removed. Other mods can register handlers before loading maps with MapCommands.Register("name", (context, arguments) => { ... });; the context supplies map name, primitive name and GameObject.

Structure spawning

Examples:

CubeSpawn.OnMapLoad.structure.summon.cube
CubeWall.OnMapLoad.structure.summon.wall
CubePillar.OnMapLoad.structure.summon.pillar
CubeBall.OnMapLoad.structure.summon.ball
CubeDisk.OnMapLoad.structure.summon.disk

Each command checks the nearest surface straight down, up to 100 Unity units from the marker's center. It must be CombatFloor (layer 9), face upward with normal Y at least 0.5, and not be Environment, a death surface or a gameplay structure. Missing/blocked ground logs a skip. The marker's complete world rotation is used; the lower rotated collider bounds are placed just above the hit surface. Gameplay physics apply afterward. Marker scale does not resize a spawned gameplay structure. Place markers above the intended ground, not inside it.

Replace/unload returns structures still owned by the map set to the pool. Pooled instances subsequently fetched for other uses are no longer owned by this mod. Append preserves existing structures.

Respawn start

CubeStart.OnMapLoad.interface.respawn.start

The marker origin is the intended standing position. Its yaw supplies upright facing. During each local native reset step, the actual spawn-point table and any captured destination are redirected to the marker, then the Gym table is restored before yielding. Existing spawn indexes/types are preserved. This avoids relying on an IL2CPP spawn-selection call being intercepted. The native fade, health reset and reset flow are preserved. The last loaded respawn marker wins. Append without a new start keeps the existing one; replace/unload clears it.

Exact kill-floor height

CubeFloor.OnMapLoad.interface.killfloor.height(Height=-10.5)

Height specifies the kill floor's top surface in Unity world Y, independently of the marker's position. Negative heights, decimals and zero are supported. The value must be finite. The tag is required, and supplying it more than once is rejected. Existing floors move to that exact top height; if none is found, an invisible death-trigger floor is created there. Example: (Height=3.25) places its top at Y=3.25.

This shares floor selection, creation and cleanup with Tools > Raise Kill Floor. An entering variant, CubeFloorZone.OnTriggerEnter.interface.killfloor.height(Height=-5), sets the height when entered.

Spawned teleport buttons

CubeGymButton.OnMapLoad.summon.asset.button.interface.teleport.gym
CubeMapButton.OnMapLoad.summon.asset.button.interface.teleport.map.RisingLeftFlow

Both use the native RumbleModdingAPI button asset. The root spawns at the marker's center with its full rotation and the asset's normal size. Marker scale does not resize the button. Tutorial button callbacks are replaced with this mod's action. No teleport occurs when the marker loads: the player must press the spawned button. Presses during map loading are ignored.

The Gym button fades to the native Gym Startup spawn, clears velocities, resets health and unloads the complete custom map set. It uses the Gym start rather than a custom respawn marker. The Gym scene stays loaded.

The map button loads <mapname>.txt from UserData/GymMaps, replaces the current map set, runs the new map's load commands, and then fades to its CubeStart.OnMapLoad.interface.respawn.start marker. The destination must contain that load-time start marker; otherwise the load is rejected and the existing course stays active. The destination is the last start marker registered by its load commands. Physics velocities are cleared and health resets. If Safety Platform is enabled, its single check occurs after this teleport. Missing player subsystems report a teleport error.

Buttons stay when appending and are removed on replace, unload or scene exit.

Map entry transitions

CubePortal.OnTriggerEnter.map.load.rings3.replace
CubePortal.OnTriggerEnter.map.load.towers.append

<mapname> is a filename without .txt; use letters, numbers, dots, underscores and hyphens. Targets are local files directly in UserData/GymMaps; subdirectories are not supported.

Replace clears the complete current map set, triggers, race timer, structures, safety platform, respawn marker, spawned buttons and floor-tool changes before activating the new map. Append adds incoming geometry at its exported world coordinates, preserves existing triggers/state, and runs only the incoming map's load commands. An already-present map is not appended again at identical coordinates. Unload removes the whole set. Map transitions keep the player's current position; use the spawned map teleport button for a transition that also moves the player.

Audio and race examples

The included sound-templates.md lists 253 clips discovered in the Gym, with ready-to-copy OnTriggerEnter and OnMapLoad tags. Each command uses play.sound.clip.id-<UTF8 hex asset name>; copy the generated ID exactly. IDs preserve spaces and punctuation without breaking dot tags and are resolved dynamically for future markers. Enable trigger commands must be on. Missing or unloaded assets log an error instead of blocking map loading. Generic clips play once at the marker, reuse a matching AudioSource mixer and volume when available, and clear on replace/unload. This enumerates loaded Unity assets, not every file in an unloaded game bundle.

CubeTelephone.OnTriggerEnter.play.sound.telephone(Cooldown=2)
CubeFinish.OnTriggerEnter.play.sound.firework(Once)
CubeStart.OnTriggerEnter.timer.start
CubeFinish.OnTriggerEnter.timer.stop(Once)
CubeReset.OnTriggerEnter.timer.reset
CubeMessage(Trigger)(OnEnter=log Checkpoint reached)(OnEnter=status Checkpoint reached)

Telephone playback uses the loaded Gym PhoneHandler's notification clip. Firework playback uses the shop GearMarket's purchase SFX bank with its native weighted clip choice, mixer group, pitch and volume settings. Both play at the marker on separate one-shot audio emitters. No shop purchase or purchase animation is triggered. If the referenced asset is unavailable, the command logs an error. Sound emitters clear on replace/unload and persist across append until playback finishes. The purchase sound reference was inspected in the game assemblies; playback has not been tested.

All additional tags

Tag/datatype Meaning Example
(OnEnter=COMMAND arguments) Add an entry callback; repeat the tag for multiple commands, in name order. CubeZone(Trigger)(OnEnter=timer.start)
(Trigger) Remove solid collision; retain the visible primitive unless hidden. CubeZone(I)(Trigger)(OnEnter=log hello)
(Once) Entry callbacks fire only once per map load, including across player respawns. CubeFinish.OnTriggerEnter.timer.stop(Once)
(Cooldown=SECONDS) Minimum interval between entry callbacks, default 0.5; zero is allowed. CubeBell.OnTriggerEnter.play.sound.telephone(Cooldown=2)
(Placeholder) Omit the authoring object entirely. Cannot be combined with an event command. CubeGuide(Placeholder)
(Height=NUMBER) Finite world Y height for interface.killfloor.height; one value per object. CubeFloor.OnMapLoad.interface.killfloor.height(Height=-10.5)

A dot-event Cube removes its physical/visible authoring primitive automatically; it does not need (I) or (Trigger). A separate (Placeholder) omits the whole entry, so it cannot run commands. Ordinary solid primitives with OnEnter callbacks still collide; use a separate Cube volume above a standing platform for body-center entry detection. (Once) and (Cooldown) affect entry behavior, not load-time callbacks.

All primitive modifier tags

Short tag Full alias Effect
(I) (Invisible) Hide the rendered primitive; collision remains unless removed by another tag.
(W) (Wall) Wall collision; adds a BoxCollider alongside the normal mesh collision.
(E) (Environment) Layer 10 Environment: player support/slide surface, breaks structures on impact, and is excluded from summonable ground.
(V) (Visual) Visible geometry without solid ground collision.
(D) (Death) Add a death barrier. Contacts with the local player request its native reset, using the current course start if present.

Combine tags as needed, for example CubeKillFloor(D)(I) or CubeSlide(E). Legacy unparenthesized names containing Invisible, Wall, Environment, Visual or Death are also recognized; parentheses avoid accidental matches. Event template text is excluded from modifier detection.

Supported primitive shape prefixes are Cube, Sphere, Capsule, Cylinder, Plane and Quad. Exported maps keep the existing five-line records (name, RGB color, XYZ position, XYZ Euler rotation, XYZ scale), preceded by an object count. Dimensions must be nonzero and numbers finite. No Blender exporter changes are required.

Menus and tools

F9 > GymMaps > Maps provides Load, Refresh and Unload. Load validates and builds incoming geometry before removing the existing course. Maps are available in the Gym. Loading and unloading also clears CustomMapCreatorTool objects under StoreHere; unrelated loaders are not managed. Refresh scans valid .txt maps directly in UserData/GymMaps.

F9 > GymMaps > Tools contains:

  • Enable trigger commands: off on each launch. Description: "Allows commands that change game and player behavior. Use at your own risk." Gates all OnMapLoad/OnTriggerEnter commands and spawned-button actions. Enabling later does not replay skipped OnMapLoad commands; reload the map to run them.

  • Safety Platform: off on each launch. When enabled, check support once after each successful replace/append. Supporting ground within 0.5 units below the feet (including Environment, excluding death surfaces) prevents a spawn. Otherwise create a fixed light-blue 4 x 0.25 x 4 platform with its top 0.05 below the feet. If the body is not ready, wait up to five seconds before skipping that load. Enabling does not immediately spawn or start continuous monitoring. Disable, replace, unload or scene exit removes it.

  • Kill floor raise amount: default 1, range 0.25 to 25 Unity units per click.

  • Raise Kill Floor: select the largest broad horizontal death collider (at least 10 x 10, thin relative to its width/depth) and raise it by the chosen amount. Vertical walls are excluded. If none exists, first create a floor 5 units below the lowest course geometry, or 10 below the player without a course. Created floors cover the course plus margins and are at least 200 x 200. Further clicks raise them.

Existing floors moved by either the tool or height template return to their original position on replace, unload or scene exit. Created floors are removed. Append preserves current floor changes unless its own height template changes the floor.

Custom death surfaces and the selected floor use this mod's local-player reset path because the game's generic kill handler can throw a null-reference error on primitive/player-child contacts. Non-player contacts do not trigger it. A selected kill floor also checks the player's feet against its top and horizontal bounds each frame; fast falls that skip the thin trigger still reset. This height check runs only for the floor managed by Tools or the height template. Native reset-in-progress and a short cooldown prevent repeated requests during one reset.

Installation and build

With RUMBLE closed, replace Mods/GymMaps.dll with the included DLL. Keep one installed copy. Source targets .NET 6 and references the game's generated IL2CPP assemblies, MelonLoader, UIFramework and RumbleModdingAPI. source/GymMaps.csproj can be built with a .NET SDK; set GameRoot for a non-default installation. Game libraries are not included in this package.

This release was compiled against local game/mod references. See test-results.txt for completed checks and their limits.

Scene restrictions

GymMaps gameplay features only run in the Gym. Matches, the Park, and other scenes block map loading, commands, spawned-button actions, structure summons, safety-platform spawning, and kill-floor checks. Leaving the Gym cancels pending map work and clears owned objects and effects. Returning to the Gym re-enables these features; load the desired map again.

Thunderstore development is made possible with ads. Please consider making an exception to your adblock.