Areamap Library
Areamap is a map library for SugarCube designed for room-to-room movement like Darkest Dungeon or node-to-node movement like Faster Than Light — NOT for grid movement like Zelda or Final Fantasy Tactics.
Areamap takes a space-separated 2D text grid and converts it into a functional map for player movement (mapmove). All grid spaces with the same id will be treated as one big room (maparea) — regardless of how many grid spaces it occupies or whether it is continuous or not. Adjacent mapareas will be connected by exits that allow navigation between them.
Features:
- Built-in navigation options:
- compass rose with directional buttons (
rose) - visual map with optionally clickable
mapareas(mapview)
- compass rose with directional buttons (
- TwineScripts payloads: Scripts can be assigned to run at various stages of the
mapmoveprocess. - Separation of map logic & map view: The 2D grid used to generate the
mapviewcan be configured independently from the 2D grid useed for map logic. - Linked
story variables: Map state can be linked tostory variablesfor map behavior manipulation. - Movement link manipulation: Movement links can be
hidden(links hidden),disabled(links disabled,mapmoveprevented), orblocked(links available,mapmoveattempted but fails). - JavaScript methods: for manipulating
areamaps,roses, andmapviews - Configurable defaults: for various settings
• • •
Macros
<<new_areamap>>
Defines a new areamap. This macro must be called in StoryInit. It accepts a 2D grid layout via its contents and supports optional child tags for advanced configuration.
- Arguments:
mapname: (string) name ofareamapstart: (string) starting position in map, must be a validmapareaidcolumns: (number) # of columns in the logic representation griddiagonals: (boolean) (optional) whether diagonal movement is allowed
- Contents:
- 2D space-separated text grid representing map logic, must be rectangular.
- Child Tags:
<<mapview>>: (optional) Defines a different 2D grid to use formapviewinstead of the map logic grid- Arguments:
columns(number) # of columns in the visual representation grid - Contents: 2D space-separated grid, must be rectangular.
- Arguments:
<<mapvars>>: (optional) Links map state tostory variablesfor map behavior manipulation.positionwill update automatically whenmapmovesucceeds. These must all bestory variablesnames starting with$.- Arguments:
position: (string) stores currentareamapposition, as a stringdisabled: (string) (optional) stores whetherroseandmapviewlinks to eachmapareaare shown but disabled, as an object of booleanshidden: (string) (optional) stores whetherroseandmapviewlinks to eachmapareeashould be hidden, as an object of booleansblocked: (string) (optional) stores whethermapmoveto eachmapareashould fail, as an object of booleansfrozen: (string) (optional) stores whether ALLroseandmapviewlinks for anareamaparedisabled, as a boolean
- Arguments:
<<mapareas>>: (optional) Defines additional metadata for eachmaparea. Partial objects will be filled with default values.- Arguments:
name: (string) (optional) used for links inroses& for theshow_namesoption inmapviews, default is themapareaidtype: (“floor”|“wall”) (optional)floorscan be occupied by a player,wallscan’t and block movement; default"floor"tile: (HTML string) (optional) inserted into each space in themapview, default none
- Arguments:
- Examples:
<<set _mapareas = { MB: {name: 'Master Bedroom'}, GB: {name: 'Guest Bedroom'}, HW: {name: 'Hallway'}, LR: {name: 'Living Room'}, ST: {name: 'Stairs'}, DR: {name: 'Dining Room'}, KT: {name: 'Kitchen'}, PT: {name: 'Pantry'}, }>> <<new_areamap mapname 'small_house' columns 7 diagonals false start 'KT' >> . . . . LR LR LR . KT . . LR . ST PT DR ST . HW . . . . . . HW . . . . . . HW GB . . . . . MB . . <<mapview columns 16 >> . . . . . . . . . . . . . . . . . . . . KT KT KT KT KT . LR LR LR LR LR . . . . . KT KT KT KT KT . LR LR LR LR LR . . PT PT PT KT KT KT KT KT . LR LR LR LR LR . . PT PT PT DR DR DR DR ST . HW GB GB GB ST . . PT PT PT DR DR DR DR ST . HW GB GB GB ST . . PT PT PT DR DR DR DR DR . HW MB MB MB MB . . PT PT PT DR DR DR DR DR . HW MB MB MB MB . . . . . . . . . . . . . . . . . <<mapareas _mapareas>> <</new_areamap>>
<<place_arearose>>
Generates a 3x3 grid of directional links for navigation.
- Arguments:
mapname: (string) name ofareamapautoupdate: (boolean) (optional) whether theroseautomatically updates after eachmapmoveor when the areamap changes, default set inoptionsbackground: (HTML string) (optional) inserted as a background element for therose
- Examples:
<<place_arearose mapname 'small_house' background '<img src="./assets/rose.png">' >>
<<update_arearose>>
Manually updates a rose element.
- Arguments:
selector: (selector string) jQuery selector for theroseelement to update
- Examples:
<<update_arearose selector '.macro-areamap-rose'>>
<<place_areamapview>>
Renders a visual representation of the areamap with the tiles configured in the <<mapareas>> child tag of <<new_areamap>>, using the 2D grid defined in the <<mapview>> child tag of <<new_areamap>>. If no <<mapview>> was used, the 2D logic map is used. Can optionally be made clickable for navigation or to display maparea names.
- Arguments:
mapname: (string) name ofareamapautoupdate: (boolean) (optional) whether themapviewautomatically updates after eachmapmoveor when theareamapchanges, default set inoptionsclickable: (boolean) (optional) whether mapareas can be clicked to navigate, default set inoptionsshow_names: (boolean) (optional) whether to display names for eachmaparea, default set inoptionsbackground: (HTML string) (optional) inserted as a background element for themapview
- Examples:
<<place_areamapview mapname 'small_house' background '<img src="./assets/small_house.png">' >>
<<update_areamapview>>
Manually updates a mapview element.
- Arguments:
selector: (selector string) jQuery selector for themapviewelement to update
- Examples:
<<update_areamapview selector '.macro-areamap-mapview'>>
<<set_areascripts>>
Assigns TwineScript logic to run during the mapmove process (areascripts). Arguments can be used to control which mapareas trigger the areascripts. This macro must be called in StoryInit. Child tag order is preserved, but <<onmapattempt>> tags always run first, followed by:
- when mapmove succeeds: <<onmapstart>> then <<onmapend>>
- when mapmove fails: <<onmapabort>>
- Arguments:
mapname: (string) name ofareamap
- Child Tags:
<<onmapattempt>>: (optional) Always runs, immediately when a mapmove is attempted<<onmapstart>>: (optional) Only runs whenmapmovesucceeds, before position is updated<<onmapend>>: (optional) Only runs when mapmove succeeds, after position is updated<<onmapabort>>: (optional) Only runs when mapmove fails- Arguments: All these child tags take the same arguments
to: (string|array<string>|“any”) (optional) id(s) of themapareathe player is moving to; either as a string, an array of strings, or “any”from: (string|array<string>|“any”) (optional) id(s) of themapareathe player is moving from; either as a string, an array of strings, or “any”
- Contents:
- TwineScript to run when the tag is triggered
- Examples:
<<set_areascripts mapname 'small_house'>> <<onmapattempt>> <<run $time++>> <<onmapstart from 'ST'>> <<run $energy-->> <<onmapend to ['KT', 'PT']>> <<run $hunger++>> <</set_areascripts>>
<<areamapmove>>
Manually triggers a mapmove attempt. This macro does not check exits — allowing for more flexible navigation — but blocked will still apply and cause the mapmove to fail.
- Arguments:
mapname: (string) name ofareamaptarget: (string)mapareato move toforce_abort: (boolean) (optional)trueforces themapmoveto fail, defaultfalse
- Examples:
<<areamapmove mapname 'small_house' target 'MB'>>
• • •
JavaScript Methods
Javascript methods are stored on the Areamap window object. All methods take an argObj argument object.
new_areamap
Creates a new areamap. The <<new_areamap>> macro is a wrapper for this method.
- argObj Properties:
mapname: (string) name ofareamapstart: (string) starting position on map, must be a validmapareaidcolumns: (number) number of columns in the map gridmaparray: (array<string>) 1D array ofmapareaids representing the map navigation logic, length must be divisible bycolumnsdiagonals: (boolean) (optional) whether diagonal movement is allowed, default set inoptionsmapview: (object) (optional) data defining a separate grid for the mapviewmapview.columns: (number) number of columns in themapviewgridmapview.array: (array<string>) 1D array ofmapareaids representing the mapview navigation logic, length must be divisible bymapview.columns
mapareas: (object) (optional) additional metadata formapareas, partial objects will be filled with default valuesmapareas.name: (string) (optional) used for links inroses& for theshow_namesoption inmapviews, default is themapareaidmapareas.type: (“floor”|“wall”) (optional)floorscan be occupied by a player,wallscan’t and block movement; default"floor"mapareas.tile: (HTML string) (optional) inserted into each space in themapview; defaultundefined
mapvars: (object) (optional) data defining links tostory variables,positionwill update automatically whenmapmovesucceeds — these must all bestory variablesnames starting with$mapvars.position: (string) stores currentareamapposition, as a stringmapvars.disabled: (string) (optional) stores whetherroseandmapviewlinks to eachmapareaare shown but disabled, as an object of booleansmapvars.hidden: (string) (optional) stores whetherroseandmapviewlinks to eachmapareeashould be hidden, as an object of booleansmapvars.blocked: (string) (optional) stores whethermapmoveto eachmapareashould fail, as an object of booleansmapvars.frozen: (string) (optional) stores whether ALLroseandmapviewlinks for anareamaparedisabled, as a boolean
- Examples:
Areamap.new_areamap({ mapname : 'small_house', start : 'ST', columns : 3, maparray : ['ST', 'KT', 'PT', 'MB', 'GB', 'BB'], mapview : { columns : 3, array : ['ST', 'KT', 'PT', 'MB', 'GB', 'BB'] }, mapareas: { ST : {name: 'Starting Room'}, KT : {name: 'Kitchen'}, PT : {name: 'Pantry'}, MB : {name: 'Master Bedroom'}, GB : {name: 'Guest Bedroom'}, BB : {name: 'Bathroom'}, }, });
create_rose
Creates a jQuery rose element. The <<place_arearose>> macro calls this method and appends the result to the macro output.
- argObj Properties:
mapname: (string) name of theareamapautoupdate: (boolean) (optional) whether theroseautomatically updates, default set inoptionsbackground: (HTML string) (optional) inserted as a background element
- Returns: (jQuery object) the created
$roseelement - Examples:
Areamap.create_rose({ mapname : 'small_house', autoupdate : true, background : '<div>Background</div>', });
update_rose
Manually updates rose elements in the DOM. If the jQuery object passed to this method references multiple roses, all of them will update. Non-rose elements will be ignored. The <<update_arearose>> macro is a wrapper for this method.
- argObj Properties:
rose: (jQuery object) the specific$roseelement to refresh
- Examples:
Areamap.update_rose({ rose: $('#rose-element'), });
create_mapview
Creates a jQuery mapview element. The <<place_areamapview>> macro calls this method and appends the result to the macro output.
- argObj Properties:
mapname: (string) name of theareamapautoupdate: (boolean) (optional) whether themapviewautomatically updates, default set inoptionsclickable: (boolean) (optional) whethermapareascan be clicked to navigate, default set inoptionsshow_names: (boolean) (optional) whether to display names for eachmaparea, default set inoptionsbackground: (HTML string) (optional) inserted as a background element
- Returns: (jQuery object) the created
$mapviewelement - Examples:
Areamap.create_mapview({ mapname : 'small_house', clickable : true, background : '<div>Background</div>', });
update_mapview
Manually updates mapview elements in the DOM. If the jQuery object passed to this method references multiple mapviews, all of them will update. Non-mapview elements will be ignored. The <<update_areamapview>> macro is a wrapper for this method.
- argObj Properties:
mapview: (jQuery object) the specific$mapviewelement to refresh
- Examples:
Areamap.update_mapview({ mapview: $('#mapview-element'), });
set_areascripts
Assigns TwineScript logic to run during the mapmove process. The <<set_areascripts>> macro is a wrapper for this method.
- Script Types:
onmapattempt: always fire, immediately beforemapmovepass/fail is determinedonmapstart: fires ifmapmovesucceeds, immediately before the player’s location is updatedonmapend: fires ifmapmovesucceeds, immediately after the player’s location is updatedonmapabort: fires ifmapmovefails
- argObj Properties:
mapview: (jQuery object) the specific$mapviewelement to refreshscripts: (array<object>) array of script objects, each object contains:scripts[].type: ("onmapattempt"|"onmapstart"|"onmapend"|"onmapabort") the script triggerscripts[].contents: (string) theTwineScriptcode to executescripts[].areas: (object)scripts[].areas.to: (string|array<string>|“any”) (optional) id(s) of themapareathe player is moving toscripts[].areas.from: (string|array<string>|“any”) (optional) id(s) of themapareathe player is moving from
- Examples:
Areamap.set_areascripts({ mapview: $('#mapview-element'), scripts: [ { type: 'onmapattempt', contents: '<<run $time++>>', }, { type: 'onmapstart', contents: '<<run $energy-->>', areas: { from: 'ST', }, }, { type: 'onmapend', contents: '<<run $hunger++>>', areas: { to: ['KT', 'PT'], }, }, ], });
begin_mapmove
Begins the mapmove procedure and fires the areamap:mapmove_began event. This method does not check exits. The <<areamapmove>> macro is a wrapper for this method.
- argObj Properties:
mapname: (string) name of theareamapid_target: (string) themapareaid to move toforce_abort: (boolean) (optional)trueforces themapmoveto fail, defaultfalse
- Examples:
Areamap.begin_mapmove({ mapname: 'small_house', id_target: 'PT', force_abort: false, });
get_map
Retrieves a copy of a map object. Manipulating the returned object will not affect or update the original map. Use Areamap.edit_map to edit areamaps.
- argObj Properties:
mapname: (string) name of theareamapto retrieve
- Returns: An object containing the map’s structure, including
mapname,columns,maparray,diagonals,mapview,mapareas,mapvars,exits, andscripts. - Examples:
const myMap = Areamap.get_map({ mapname: 'small_house', });
edit_map
Allows for dynamic modification of an existing areamap. This method will automatically update the areamap’s exits and update any roses or mapviews set to autoupdate.
- argObj Properties:
mapname: (string) name of theareamapto modifydiagonals: (boolean) (optional) new diagonal movement statecolumns: (number) (optional) new column count, must form a rectangular grid withmaparraymaparray: (array<string>) (optional) new logic grid array, must form a rectangular grid withcolumnsmapview: (object) (optional) newmapviewconfigurationmapview.columns: (number) (optional) new column count, must form a rectangular grid withmapview.arraymapview.array: (array<string>) (optional) newmapviewarray, must form a rectangular grid withmapview.columns
mapareas: (object) (optional) update metadata for one or moremapareas, incomplete objects will retain existing values for missing datamapareas.[id]: (object)mapareas.[id].name: (string) (optional) new namemapareas.[id].type: (“floor”|“wall”) (optional) new maparea typemapareas.[id].tile: (HTML string) (optional) new HTML string to display inmaparea
- Examples:
Areamap.edit_map({ mapname: 'small_house', mapareas: { GB: { type: 'wall', }, }, });
• • •
Events
Areamap fires several events that allow for manipulating player movement and tracking map changes. All Areamap events fire off #passages and resolve on document. Authors that intend to intercept Areamap events should place their listeners on #story.
areamap:mapmove_began
Triggered immediately when any mapmove attempt begins
- Event Data:
mapname: (string) name of theareamaptriggering themapmoveid_origin: (string) id ofmapareathe player is moving fromid_target: (string) id ofmapareathe player is moving toforce_abort: (boolean) true forces themapmoveto fail
areamap:mapmove_resolved
Triggered after any mapmove resolves
- Event Data:
mapname: (string) name of theareamapthat triggered themapmoveid_origin: (string) themapareaID the player moved fromid_target: (string) themapareaID the player moved tosucceeded: (boolean) whether the movement was successful
areamap:map_edited
Triggered after the edit_map method completes, useful if you need to perform additional UI updates not covered by the standard autoupdate functionality.
- Event Data:
mapname: (string) name of theareamapthat was modified
• • •
Options
- Default values: can be overridden by passing in argumnts to their respective macros
setup['@areamap/options'].default.wall_id: (string) default id used to represent walls in the map grid- value:
. - used in:
<<new_areamap>>andAreamap.new_map
- value:
setup['@areamap/options'].default.diagonals: (boolean) whether diagonal movement is allowed- value:
false - used in:
<<new_areamap>>andAreamap.new_map
- value:
setup['@areamap/options'].default.autoupdate_rose: (boolean) whether theroseautomatically updates- value:
true - used in:
<<place_arearose>>andAreamap.create_rose
- value:
setup['@areamap/options'].default.autoupdate_mapview: (boolean) whether themapviewautomatically updates- value:
true - used in:
<<place_areamapview>>andAreamap.create_mapview
- value:
setup['@areamap/options'].default.clickable_mapview: (boolean) whether themapviewis clickable- value:
true - used in:
<<place_areamapview>>andAreamap.create_mapview
- value:
setup['@areamap/options'].default.show_names_on_mapview: (boolean) whether themapviewshows names for themapareas- value:
false - used in:
<<place_areamapview>>andAreamap.create_mapview
- value:
• • •
Usage Tips & Styling
- The algorithm that checks
exitsout of eachmapareawill not remove duplicates say ifmaparea-Ahas twoexitstomaparea-Bin two different directions. This is especially important when using thediagonalsoption. Authors will need to shape their navigation map accordingly. - Changing
disabledorfrozenvalues totruewill not prevent amapmove— it only disables the link generated inrosesandmapviews. - Changing
blockedvalues totrueinside anareascriptwill prevent amapmoveonly if done insideonmapattempt. <<areamapmove>>andAreamap.begin_mapmovedon’t check against validexits— this is useful for moving the player to areas normally inaccessible to their current location or to disconnected parts of the map (eg. if an author chooses to implement stairs manually).- Clickable links have the
.macro-areamap-linkclass. hiddenmapareasstill generate tiles and links, but withvisibility: hidden.mapviewtiles have thedata-traversableHTML attribute that indicates whether it is traversable, or the current positiontrue: available formapmovevia clicking on themapviewfalse: not available formapmovecurrent: current map position
mapviewtiles have thedata-typeHTML attribute that indicates their typewall: wall tilefloor: floor tile
- Each grid cell on
roseshas thedata-dirHTML attribute which indicates its directionN,E,S,W: cardinal directionsNE,NW,SW,SE: ordinal directionsC: center
- Several HTML string arguments accept TwineScript instead of raw HTML — but authors use this feature at their own discretion. These include:
backgroundargument in<<place_arearose>>andAreamap.create_rosebackgroundargument in<<place_areamapview>>andAreamap.create_mapviewtileargument in<<place_areamapview>>andAreamap.create_mapview
- If an author chooses to intercept the
areamap:mapmove_beganevent,mapmovewill not resolve unless they allow the event to propagate todocumentor fire anotherareamap:mapmove_beganevent.