Puzzlum / Gamepad Enforcer / Dungeon

Dungeon Developer's Guide

A self-contained maintenance guide for the JavaScript Dungeon project, its Editor, GE integration, save-slot model, actor and ability data, asset pipeline, and current engineering conventions.

Document date2026-07-03
AudienceDevelopers and maintainers
Primary root/public/alpha/Dungeon/
StatusLiving guide / implementation notes

1. Scope and Ground Rules

This guide describes the Dungeon project as maintained inside the Puzzlum/Gamepad Enforcer ecosystem. It is intended for a developer who already knows JavaScript, browser debugging, and file-based game data, but does not yet know the rules of this codebase.

Most important rule: do not assume the original files under the public project root are the active state. Dungeon can save active map/project changes into server-side private save storage. When behavior diverges from what the source assets appear to say, inspect the selected active save slot first.

Dungeon is one of the GE-supported games. It should be maintained as part of the shared GE-supported game family, not as a one-off island. Whenever a behavior is shared across GE-supported games, patch shared GE code instead of special-casing Dungeon unless Dungeon truly needs different behavior.

  • Use actor terminology everywhere. Do not add new NPC wording or npc.json references.
  • Use conditions.json for tunable game logic rather than hardcoding behavior into Dungeon.js.
  • Keep save slots, public publishing, and server-side storage separate and explicit.
  • Preserve existing project style: Windows newlines, tabs for indentation, path-preserving deltas, and no stubs.

2. Mental Model

Dungeon is a JavaScript port of an older Dungeon game concept, now living under a browser-based master-engine workflow. The project mixes stable gameplay, experimental systems, test maps, broken levels, and editor-driven data. That mixture is expected. Do not treat every weird level or actor as a defect.

Game runtime Loads active project data, resolves GE input, evaluates conditions, runs actor/tile logic, renders the map, handles UI panels, battle mode, shops, inventory, BGM, and save-state behavior.
Dungeon Editor Edits maps, actors, tiles, abilities, sprite assignments, inventory slots, and save-slot selection. The Editor is also responsible for saving into the correct active private save slot.
GE support Provides input abstraction, overlay behavior, HUD items, GE-Ink asset conversion/loading, and common support modules shared by Dungeon and other GE-supported games.
Server-side saves Private save slots can override the original public assets. Publishing copies the selected private save state into public assets for authorized users.

When debugging, identify which layer owns the behavior before changing code. A rendering symptom may come from actor ZIndex data. An input symptom may belong in GE. An ability sprite symptom may come from abilities.csv normalization, not from the battle renderer.

3. Roots, Releases, and Saves

Release roots

Dungeon is expected to exist under both experimental and stable release directories:

/public/alpha/Dungeon/
/public/official/Dungeon/

The alpha tree is the normal active development target. The official tree is the stable/released target.

Public assets vs. private save slots

The canonical public asset path for the development release looks like this:

/public/alpha/Dungeon/assets/

Logged-in persistent save assets belong under the private flavor-specific save tree. Treat the exact save identifier as a slot/save-name value selected by the Editor:

/<flavor>-private/users/<username>/<project>/saves/<save-slot>/assets/

For example, an ability file may resolve as either:

/public/alpha/Dungeon/assets/abilities.csv
/<flavor>-private/users/<username>/Dungeon/saves/<save-slot>/assets/abilities.csv
Save-slot rule: the Editor must expose a save-slot selection drop-down. The selected slot determines which private save tree is loaded and written. Newly created save slots must be saveable and overwriteable just like existing slots.

Publish behavior

The Editor needs a Publish action available only to the users admin and joy. Publish means: copy/save the current selected private save state into the public project asset state. It does not mean “save the current editor form somewhere unspecified.” It specifically promotes the current private save slot to public.

ActionAllowed usersSourceDestinationNotes
SaveLogged-in editor userEditor stateSelected private save slotMust work for existing and new slots.
LoadLogged-in editor userSelected private save slot, falling back to public where appropriateEditor stateDo not silently read originals when a private save exists.
Publishadmin, joySelected private save slotPublic project assetsUse for promoting a private save into public.

4. Runtime Boot Flow

The exact implementation can change, but maintainers should preserve this boot order as the architectural intent:

  1. Resolve release/flavor/project root.
  2. Resolve current user and selected save slot when running the Editor or loading user-specific state.
  3. Load GE support configuration and shared input aliases.
  4. Load conditions.json before evaluating game logic.
  5. Load map, tile, actor, ability, sprite, sound, and UI data from the active asset root.
  6. Normalize data into runtime structures: actors, tiles, inventory slots, ability frames, BGM metadata, hitboxes, and ZIndex ordering.
  7. Initialize input capture rules for HUD, Party Panel, Battle Mode, shops, and editor pop-ups.
  8. Start the render/update loops only after essential data and input systems are ready.

Do not scatter one-off loading fallbacks throughout gameplay code. Asset-root resolution and data normalization should happen early, then runtime systems should consume normalized structures.

5. Data and Asset Files

Dungeon is data-heavy. Many gameplay fixes should be implemented by improving loading, normalization, validation, or editor persistence rather than by patching a render loop directly.

File / familyRoleDeveloper notes
assets/abilities.csvAbility/item definitions and sprite assignment metadata.Sprite assignment lives here. Preserve explicit animation frame columns and the legacy sprite: token form.
actor.jsonActor definitions and properties.Use actor naming. Obsolete npc.json references.
conditions.jsonGame logic, conditions, thresholds, timing, and tuning knobs.Use this as the source of game logic where possible. Avoid hidden hardcoded logic.
assets/tiles/*.csvTile graphics/data.Editor galleries should show processed image previews with filename prefix labels.
assets/sounds/*.mp3BGM and sound effects.Tracks are identified by the filename stem, e.g. battle maps to assets/sounds/battle.mp3.
GE/*.jsonGE runtime configuration.Includes chords, input mapping, conditions, overlay behavior, and other shared support data.

CSV conventions

  • .csv means comma-separated values.
  • GE-Ink should convert CSV directly to JSON unless plain or raw flags are present.
  • CSV should convert to PNG only when the png flag is present.
  • Flags do not need assigned values; a flag can be present as a bare query switch.

6. Actors, Granters, and Receivers

The term actor is the universal runtime term. Do not use NPC in new data, UI, documentation, file names, or code comments. Existing npc.json references should be renamed to actor.json and covered by an obsoletion script where needed.

Actor property expectations

  • Unique Name: stable actor metadata for human-readable identification.
  • Blocking: one boolean checkbox in the Editor, not competing numeric and checkbox controls.
  • Hidden: prevents visual rendering on the map without removing gameplay logic.
  • ZIndex: affects render order and hitbox priority. Doors must not sort below other actors by accident.
  • BGM: actor-level property/behavior. Any actor can carry BGM behavior; it is not simply a Hexdot feature.
  • Receiver: includes/merges traits from a referenced Granter actor.
  • Trade: enables shop-panel item transfer behavior.
  • Purge: marks a free shop/container source with zero-Ess transfer behavior and zero-unit purge handling.

Granters and Receivers

A Granter is an Actor that defines a reusable trait set. Other Actors and Tiles include those traits through the Receiver property. Runtime logic should merge referenced Granter traits before evaluating actor/tile behavior.

{
	"Unique Name": "BGM - Catacombs",
	"Granter": true,
	"BGM": "catacombs",
	"Loop": true,
	"Crossfade": true
}

{
	"Unique Name": "Hexdot - West Hall",
	"Receiver": "BGM - Catacombs"
}
Reference compatibility: Hexdot destination references should still support actor index references where requested. Adding Unique Name must not break existing index-based references.

7. Abilities and Inventory

Ability sprites

Ability sprite assignments are stored in abilities.csv. The runtime and Editor should normalize both known sprite forms:

Battle Stats token:
"sprite:frame1.csv,frame2.csv,frame3.csv,frame4.csv"

Explicit animation columns:
columns 11, 12, 13, 14 = Frame 1, Frame 2, Frame 3, Frame 4

When saving from the Editor, preserve first-class animation-frame columns so ability sprite assignments survive reloads and private save persistence.

Ability display rule

Every listed ability in any panel must display its animated sprite before its name.

  • In the Editor, missing/no ability animation should display the Empty animation.
  • In the live game, a listed ability without an animation should display a grey placeholder box.
  • The live grey placeholder rule applies only to listed abilities without animations, not to every missing/non-ability sprite context.

Inventory amounts

Item and ability amounts are floats, not integers. Storage, transfer, depletion, keys, and locks must preserve fractional quantities. Displayed item counts should show the rounded-up amount.

stored amount: 0.25
shown count:   1

stored amount: 1.10
shown count:   2

Use a single amount/depletion system for ordinary items, keys, locks, shop transfers, chests, and purge containers. Do not create a separate integer-only key path.

Actor inventory slots

Actors need a per-Actor inventory slot manager with up to 15 item/ability slots. Slot assignment should use an abilities.csv-driven pop-up Abilities Gallery picker, not a free-typed item-name field.

8. Conditions-Driven Logic

Dungeon should use conditions.json for game logic and tuning. The intent is to keep rules data-driven, testable, and adjustable without hunting through hardcoded branches.

Preferred pattern: load condition/tuning values from GE/conditions.json or the active project conditions file, normalize defaults once, and have Dungeon.js consume the normalized values.

Good candidates for conditions

  • Battle mode action timing and selection rules.
  • Auto-Walk cadence, stall prevention, and movement gating.
  • Input capture behavior for Party Panel and Battle Mode.
  • Shop transfer rules, depletion, and purge behavior.
  • Door, lock, key, ZIndex, hitbox, and interaction priorities.

If a fix requires a magic number, add a named condition/tuning value instead of embedding the number directly in event handlers or render loops.

9. Dungeon Editor

The Editor is not just a visual map tool. It is the persistence authority for active save slots and the authoring interface for tiles, actors, ability sprites, inventory, and public publishing.

Required Editor behaviors

  • Expose a save-slot selection drop-down.
  • Load and save against the selected slot.
  • Allow new save slots to be saved over.
  • Provide a Publish button only for admin and joy.
  • Publish from the selected private save slot to public assets.
  • List/edit all available actor properties.
  • Use a single checkbox for boolean values where appropriate.
  • Keep Blocking as a single checkbox, not duplicate numeric/checkbox UI.

Galleries and pickers

  • The shared pop-up Sprite Gallery should include Empty as the first animation option.
  • Actor inventory slot assignment should use a pop-up Abilities Gallery picker.
  • The Abilities Gallery should be driven by abilities.csv.
  • The Editor needs an abilities.csv editor.
  • abilities.csv items must support assigning sprite frames.

Tile/image operations

The Editor should support tile/image operations for:

  • flip horizontally;
  • flip vertically;
  • roll horizontally with edge wrap;
  • roll vertically with edge wrap;
  • reassigning a selected tile/image where supported.

CSV tiles from /assets/tiles/*.csv should display literally in a gallery grid as processed image previews. Show each filename prefix below its preview. Selecting a preview loads that tile into the editor.

10. GE Integration

Dungeon participates in the shared GE-supported game list. The support module family includes Gamepad Enforcer, GE-Ink, GE-Overlay, and GEDU.

DungeonGamepad EnforcerGE-InkGE-OverlayGEDUalphaofficial

Input abstraction rules

  • Do not assume raw axes are assigned the same across all controllers.
  • Cursor and gameplay movement should use GE-resolved aliases/config mappings.
  • Face button handling should map through the alias chain, not raw browser input indexes.
  • Raw A, B, X, Y labels are Xbox-style by default, not Nintendo.
  • Nintendo-style labels should be selected only when config/device indicates Nintendo/Switch/Joy-Con/8BitDo Nintendo-style layout or face labels are in Nintendo order.

Overlay and HUD consistency

GE Overlay and Rankings visual/click feedback should be consistent across all GE-supported games. Shared GE code should provide the same press/bump behavior on hitbox click/release and the same active/brighter outline behavior when toggled on/open.

HUD hitboxes need ZIndex-aware handling. GE HUD items should remain available even when Party Panel or Battle Mode is consuming regular gameplay input.

11. GE-Ink and Asset Loading

GE-supported games should use direct public paths and JavaScript GE-Ink. They should not use obsolete ink.php paths for scripts, assets, maps, bundles, or game loading. Legacy projects may still have ink.php; GE-supported games should not depend on it.

Allowed path model

JavaScript-based file manipulation should be limited to:

${ink.origin}/Gamepad-Enforcer/
${ink.origin}/${ink.release_dir}/${ink.project_dir}/

PHP-based file manipulation should be limited to the corresponding server-side public roots. Extra GE-Ink allowlisted roots for Gamepad-Enforcer, GE, and Gamepads should only be enabled when ge_paths is explicitly truthy. Default ge_paths should be false.

Request shape

GE-Ink request strings should be relative to the active project/asset root. A typical generated image request looks like:

assets/textures/json/WATR_004_24.json?png=1&frame=0&w=8&h=8&style=cover

GE-Ink expands the path according to origin, release directory, project directory, and asset-prefix rules.

12. Rendering, Z Index, and Hitboxes

Rendering order and click/input targeting are both ZIndex-sensitive. Treat visual ZIndex and hitbox ZIndex as related concerns. A sprite that looks correct but has a stale hitbox priority will still feel broken.

Rules

  • Doors must not accidentally use a lower ZIndex than other actors when they need to be interactable above them.
  • Hitboxes need explicit ZIndex priority when visual layers overlap.
  • Hidden actors should not render, but their gameplay logic can still participate where intended.
  • Ability placeholders are context-specific: grey live placeholders are for listed abilities without animations only.

Debug approach

  1. Confirm whether the actor/tile exists in the active save slot.
  2. Inspect normalized actor properties, including Hidden, Blocking, and ZIndex.
  3. Inspect the hitbox table separately from the rendered sprite list.
  4. Confirm HUD hitboxes still outrank panel/gameplay input where required.

13. Panels, Battle Mode, and Input Capture

Party Panel and Battle Mode should consume mouse, keyboard, and gamepad inputs so background gameplay does not accidentally react while panels are active. The exception is GE HUD activation: inputs that activate GE HUD items should remain available.

Battle Mode rules

  • Action choice must apply the desired selected action, not a stale/default selection.
  • Selection state should be explicit and updated before action execution.
  • Panel input handlers should stop propagation to gameplay handlers.
  • GE HUD handlers should be allowed to run where designed.

Auto-Walk

Auto-Walk has previously been vulnerable to periodic stalls. When investigating stalls, check the movement clock, condition gates, input consumption, actor blocking, destination occupancy, and whether a panel or battle state is swallowing movement updates incorrectly.

14. Shops, Chests, Purge, and Trade

Dungeon uses shop-panel mechanics for more than ordinary merchants. Chests and other container actors can use the same transfer machinery.

Trade

Actors with a Trade flag allow item transfer via the shop panel in both directions. Chests have the Trade flag by default.

Purge

Actors with Purge: 1 host a free shop/container source. Chests and Body Bags have Purge by default. A Purge source behaves like a zero-Ess shop/container with slot transfer behavior and zero-unit purge handling.

Transfer rules

  • Use matching slots when possible.
  • Fall back to an empty slot when no matching slot exists.
  • Preserve fractional amounts.
  • Purge zero-unit stacks after transfer/depletion.
  • Display Essence/appraisal values with a space before the unit, e.g. 12 Ess, not 12Ess.

15. Audio and BGM

BGM is an actor property/behavior generally, not simply a Hexdot feature. Any actor can carry BGM behavior/properties, with looping crossfade support.

Public audio tracks live under:

/public/<release>/Dungeon/assets/sounds/<track>.mp3

Logged-in persistent sound assets live under:

/<flavor>-private/users/<username>/Dungeon/saves/<save-slot>/assets/sounds/<track>.mp3

Tracks are uniquely identified by <track>, the filename stem. Do not store absolute local paths as gameplay identifiers.

16. Migration and Obsoletion

Dungeon has accumulated legacy names and data shapes. Migrations should be explicit, reversible where possible, and delivered with obsoletion scripts when requested.

Known migration themes

  • Rename NPC wording to actor.
  • Rename npc.json references to actor.json.
  • Normalize abilities.csv sprite frame columns 11–14.
  • Preserve legacy sprite: Battle Stats tokens while writing first-class frame columns.
  • Move logic constants into conditions.json.
  • Remove GE-supported game dependencies on obsolete ink.php loading paths.

PowerShell obsoletion scripts

When a migration affects deployed paths, include a PowerShell obsoletion/normalization script at the same level as the public folder unless the task specifies another location. Back up changed files with a clear migration suffix.

# Example style only, not a complete migration script:
$root = Join-Path $PSScriptRoot "public\alpha\Dungeon"
$target = Join-Path $root "assets\abilities.csv"
$backup = "$target.c2-migration.bak"

17. Debugging Checklist

When something looks wrong in the game

  1. Confirm whether the active data is public or private-save-slot data.
  2. Confirm the selected save slot in the Editor.
  3. Inspect network requests for wrong roots, obsolete ink.php paths, or absolute local Windows paths leaking into browser URLs.
  4. Inspect loaded GE JSON state and aliases.
  5. Inspect normalized actors, abilities, inventory slots, ZIndex, hitboxes, and conditions.
  6. Confirm whether the issue is shared GE behavior or Dungeon-specific behavior.

When the Editor saves but the game disagrees

  1. Check whether the Editor saved to the selected private save slot.
  2. Check whether the game loaded that same selected save slot.
  3. Check whether public originals are being inspected instead of server-side saved copies.
  4. Check whether the save wrote all required derived files, such as abilities.csv frame columns.
  5. Check cache/localStorage only after confirming server-side state.

When input is broken

  1. Check panel/battle input capture first.
  2. Check GE HUD exceptions second.
  3. Check alias mapping rather than raw browser input indexes.
  4. Check gamepad slot timestamp behavior if inputs freeze.
  5. Check whether GE Overlay or Rankings behavior belongs in shared GE code.

18. Coding and Packaging Style

Dungeon work should follow the same practical maintenance discipline used across the project.

  • Review before changing.
  • Debug before guessing.
  • Explain the moment of clarity when delivering a patch.
  • Update only what changed.
  • Preserve archival paths in any delta zip.
  • Name zip files cleanly, without escaped characters.
  • Validate that zip files are valid before delivery.
  • No stubs. Do not ship placeholder implementations.
  • Use Windows newlines and tabs for code changes.
Patch strategy: if only a delta is requested, include only changed files while preserving the project-relative paths needed to overlay them onto the existing project tree.

19. Quick Reference

TopicRule
TerminologyUse actor, not NPC.
Actor dataUse actor.json, not npc.json.
LogicUse conditions.json; avoid hardcoded game logic.
Save stateInspect active private save slot before public originals.
PublishOnly admin and joy; selected private save to public.
AbilitiesSprite frames live in abilities.csv; columns 11–14 are explicit frame columns.
AmountsStore floats; display rounded-up counts.
InventoryActors support up to 15 slots selected through the Abilities Gallery.
Ability displayAnimated sprite before name in every panel.
Missing ability animationEditor: Empty animation. Live game: grey placeholder box.
TradeBidirectional shop-panel transfer. Chests default to Trade.
PurgeFree shop/container source; Chests and Body Bags default to Purge.
Ess displayUse a space: 12 Ess.
Audioassets/sounds/<track>.mp3; identify by <track>.
GE inputUse aliases/config mappings, not fixed raw axes/indexes.
GE-Ink CSVCSV → JSON by default; CSV → PNG only with png flag.
PackagingPath-preserving delta, valid zip, no stubs.