Locations and languages
Use localization files to translate your mod’s text. Register a locale only when adding a language choice to the game. A location is the arena background and fighter placement used by a fight.
Recovered location compatibility: the legacy bridge name uses the installed
night_bridge artwork and layout because the original Bridge images are missing.
Its runtime name stays bridge. A registered custom location uses its own supplied
layout and artwork. A location without a music setting can still be previewed;
its encounter supplies the battle track.
sf2.locales.register
Section titled “sf2.locales.register”Signature: sf2.locales.register(definition)
Returns: The qualified locale ID as a string.
When: During mod loading.
Requires: content.register.
| Field | Meaning |
|---|---|
id |
Required local identifier. |
name |
Required display name. |
locale |
Required locale code. |
alias |
Optional legacy identifier, default empty. |
is_asian |
Optional boolean, default false; selects the corresponding text layout behavior. |
file_icon, file_icon_selected |
Optional existing icon names, default empty. |
loader_image, preloader_image |
Optional existing image names, default empty. |
fonts |
Optional font configuration described below. |
If fonts is supplied, content, title, and button are required font-name strings. size_scale, line_spacing, and custom_line_spacing_scale default to 1 and must be positive finite numbers. Font and image names must resolve to supported game resources; this function does not import a font file.
local language_id = sf2.locales.register { id = "custom_english", name = "Custom English", locale = "eng",}This registers the language option. Put translated strings in localization files separately; see Localization.
For procedural warnings and pose-based hazard sensors, see Arena regions and markers. Lua owns their timing and damage policy.
sf2.locations.register
Section titled “sf2.locations.register”Signature: sf2.locations.register(definition)
Returns: A location handle.
When: During mod loading.
Requires: content.register; declare dependencies for external assets.
| Field | Default and meaning |
|---|---|
id |
Required local identifier. |
color |
"0x000000"; background color string. |
width, height |
1936, 512; positive arena dimensions. |
min_width |
Same as width; positive minimum width. |
wall, floor |
200, 80; arena boundaries. |
position_y |
0; vertical offset. |
friction_force, grid_size |
0; physics/layout settings. Grid size cannot be negative. |
dojo |
false; opt this location into saved dojo selection . At most 256 choices across active mods. |
music |
Optional single audio handle; cannot be combined with nonempty music_choices. |
music_choices |
Optional dense array of up to 16 distinct audio handles. Empty/omitted means no choices. |
layers |
Required, nonempty array of layer tables. |
tags |
Optional array of up to 16 stage tags, such as { "night", "lamps" }, so effects that pick stages by tag include yours. Needs presentation.visuals. |
Each layer has type (integer, default 1), factor (number, default 1), and scaling (boolean, default false). It needs images or fighter placements. Use type = 2 for a layer with fighters.
An image requires a sprite handle. x and y default to 0; positive width and height default to 1. opaque, flip_x, flip_y, and mask are booleans defaulting to false. A fighter placement requires all four numbers: player_x, player_y, enemy_x, enemy_y. Coordinates and numeric settings must be finite.
local arena = sf2.locations.register { id = "training_arena", width = 1936, height = 512, floor = 80, wall = 200, layers = { { type = 1, images = { { sprite = sf2.assets.sprite( "core:textures/locations/battlefield/battlefield_bg1.back_1"), width = 1936, height = 1024, } }, }, { type = 2, fighters = { player_x = 868, player_y = -94, enemy_x = 1068, enemy_y = -94, }, }, },}These dimensions are a starting point for this particular background. Check both fighter positions and camera framing in game when changing the art.
sf2.locations.name
Section titled “sf2.locations.name”Signature: sf2.locations.name(location)
Returns: The location’s qualified ID as a string.
When: During mod loading, after obtaining the location handle.
Requires: A valid location handle belonging to the current scripting context; no additional capability.
Converts a location handle to the name expected by a fight’s location field. Passing a plain string or a handle of another kind is an error.
local arena_name = sf2.locations.name(arena)-- Use location = arena_name inside sf2.fights.register { ... }.Stage tags
Section titled “Stage tags”Stage tags say what a stage looks like: its light, its weather and what is in it.
Visual effects pick their stages by tag (tags and exclude_tags),
so an effect written for fire runs on every burning stage, including stages from
other mods, without listing their names. Tags are presentation only: they are never
saved and do not change which mods can play together online.
Every stage has exactly one light tag. The others are optional.
| Tag | Meaning |
|---|---|
day |
Open daylight, or daylight through windows. |
dusk |
Low sun: sunset, sunrise or golden haze. |
night |
A night sky or moonlight. |
dark |
Little natural light at all: caves, voids, deep rooms. |
indoor |
Under a roof or inside a cave. |
raid |
A raid boss arena. |
fire |
Open flames, lava or something burning. |
lamps |
Lanterns, candles or lit windows. |
otherworld |
An unnatural glow: magic, machines, portals. |
rain |
Rain. |
snow |
Snow or ice. |
mist |
Fog, haze or drifting dust. |
heat |
Shimmering hot air. |
foliage |
Trees, leaves or grass. |
petals |
Blossoms or flowers. |
water |
A lake, river, sea or waterfall. |
Tag the stages you register with tags in
sf2.locations.register. To add tags to a stage that
already exists, use sf2.locations.tag.
The game’s stages
Section titled “The game’s stages”| Stage | Tags |
|---|---|
american_event_24 |
day, snow |
arena |
dusk, mist |
arkhos_raid |
raid, dark, fire |
autumn |
day, foliage |
bamboo_grove |
day, foliage, mist |
battlefield |
dusk, mist |
blackness_raid |
raid, dark, otherworld, water |
bridge |
day, petals, water, mist |
burning_town |
night, fire, heat |
capsules |
dark, otherworld, mist |
castle_and_bridge |
day, foliage, water, mist |
cave |
dusk, indoor, mist |
chess_yard |
day, mist |
dark_room |
day, indoor |
dock |
day, water, mist |
dojo |
day, indoor, petals |
dojo_8_march |
day, indoor, petals |
dojo_american_event |
day, indoor |
dojo_american_event_22 |
day, indoor |
dojo_american_event_26 |
day, indoor |
dojo_cny25 |
dusk, lamps |
dojo_hw21 |
dusk, indoor |
dojo_hw22 |
night, indoor, lamps, otherworld |
dojo_hw24 |
dusk, indoor, lamps |
dojo_india24 |
dusk, indoor, lamps |
dojo_india25 |
dusk, indoor, lamps |
dojo_indian_event |
day, indoor, petals |
dojo_indian_event_22 |
dusk, indoor, petals |
dojo_new_year_22 |
night, indoor, snow |
eggs |
dark, otherworld, mist |
emerald_forest |
day, foliage, mist |
factory |
day, otherworld, mist |
fall_event_24 |
night, foliage, mist |
fatum_raid |
raid, dark, fire, mist |
fear_raid |
raid, dark, otherworld |
flooded_village |
day, rain, water, mist |
flowers_field |
day, foliage, petals |
flying_rocks |
dusk, mist |
flying_rocks_small |
dusk, mist |
fuji |
day, snow |
fungus_raid |
raid, dark, otherworld, mist |
gatekeeper_raid |
raid, dark, indoor, lamps, otherworld |
graveyard_ships |
day, heat |
haloween_dojo |
night, indoor |
haloween_dojo_2019 |
night, indoor |
heaven |
day |
hoaxen_raid |
raid, day, otherworld, mist |
hunger_raid |
raid, dark, fire |
hunter_raid |
raid, day, otherworld |
hw24_ancient_temple |
night, lamps, foliage, otherworld |
hw24_village_night |
night, lamps |
hw24_waterfall_night |
night, lamps, water, mist |
ice_cave |
day, indoor, snow |
lamps_on_water |
night, lamps, water, mist |
magic_rocks |
dusk, fire, heat |
megalith_raid |
raid, day, indoor |
moon |
night, mist |
mountain |
dusk, foliage, mist |
mountains_ny_25 |
day, snow, foliage |
neural_network |
dusk, otherworld |
new_year_china_dojo |
day, indoor, lamps, petals |
night_bridge |
night, lamps, foliage, water, mist |
pink_lake |
dusk, water, mist |
ritual_battle_raid |
raid, day, indoor |
ritual_fungus_raid |
raid, dark, otherworld, mist |
ritual_hunger_raid |
raid, dark, fire |
ritual_vulcan_raid |
raid, dark, fire, heat |
road |
day, foliage, petals |
ruins_village |
dusk, mist |
ruins_village_small |
dusk, mist |
sakura |
dusk, petals, mist |
saturn_raid |
raid, night, otherworld |
shadow_gate |
dusk, mist |
ships |
dusk, water |
skyport |
dark, indoor, lamps, otherworld |
snowy_peak |
day, snow |
spaceship |
dusk, otherworld, mist |
spaceship_thorny |
dusk, otherworld, mist |
statue |
dusk, lamps, foliage, mist |
stone_dragon |
day, mist |
stone_forest |
day, water, mist |
stone_forest_thorny |
day, mist |
swamp |
day, rain, foliage, water, mist |
two_faced_city |
night, lamps |
village |
day, foliage |
volcano |
dusk, fire, heat |
vortex_raid |
raid, day, indoor, otherworld, water, mist |
vulcan_raid |
raid, dark, fire, heat |
war_raid |
raid, dusk, fire, heat |
waterfall |
dusk, water, mist |
waterfall_small |
dusk, water, mist |
whisper_raid |
raid, night, indoor, lamps |
sf2.locations.tag
Section titled “sf2.locations.tag”Signature: sf2.locations.tag(stage, tags)
Returns: Nothing.
When: During mod loading.
Requires: presentation.visuals.
Adds stage tags to a stage. stage is a game stage’s name, such
as "dock", or a location handle from sf2.locations.register.
tags is an array of 1–16 tags from the list above. Tags only add: a stage keeps
its own tags and every other mod’s. An unknown tag is an error.
-- The dock is lit by harbour lanterns in this mod's art.sf2.locations.tag("dock", { "lamps" })
-- Tag a stage this mod registers after the fact.local arena = sf2.locations.register { id = "ash_arena", layers = { ... } }sf2.locations.tag(arena, { "dusk", "fire", "heat" })Animated image curves
Section titled “Animated image curves”Optional motion_x, motion_y, rotation and opacity tables apply to
location images. Each is { offset = 0, points = { ... } }. Points require
period (seconds) and value; ease defaults to zero. Curves loop from the last
point back to the first. Each period is the time from that point to the next.
Offset advances the initial phase in seconds.
Position values are displacements in native arena units; positive Y motion uses
the native effect’s upward axis (the image’s base y coordinate is inverted by
the location loader). Rotation uses native degrees. Opacity values are percentages
from 0 to 100. ease = 0 gives linear interpolation. Other values use the native
quadratic curvature coefficient, not a named easing preset, and can overshoot.
local drift = { offset = 0.25, points = { { period = 1, value = -8 }, { period = 1, value = 8 } },}-- Inside a location layer's images array:local image = { sprite = sf2.assets.sprite("my.mod:sprites/scenery/banner"), width = 128, height = 256, motion_y = drift, rotation = { points = { { period = 1, value = -2 }, { period = 1, value = 2 } } },}Each curve requires 2–64 points. Periods must be between 1/60 and 120 seconds, and offsets between zero and the sum of periods. Values must be finite and in -10000..10000; opacity narrows this to 0..100. Ease must be zero or have magnitude 0.0001..1000 to avoid unstable native coefficients. Zero-duration segments are rejected because the native loop cannot safely advance an all-zero curve. Animated images cannot be masks or marked opaque; flipping remains supported.
These are decorative picture effects using the native scenery clock. They do not grant collision, damage, hazard timing, atlas animation or particle control. Pause behavior must be tested in the intended scene; scenery timing is not the combat callback clock. Curves participate in content fingerprints. Existing static images keep their original projection. Numerical and Lua/projection tests pass; full-game visual, pause and lifetime acceptance remains outstanding.
Random fight music
Section titled “Random fight music”Set music_choices on a location to let the native game choose
one track at fight entry. Each entry has equal probability; a track may repeat
on the next entry. The chosen track loops. This is not a sequential playlist,
and selection is not tied to a mode’s saved random stream.
-- Add this field to your location definition alongside its id and layers.music_choices = { sf2.assets.audio("core:gamedata/music/fight1_samurai_spirit"), sf2.assets.audio("core:gamedata/music/fight2_blade_dance"),},Use audio handles, not filenames or pipe-separated strings. Declare dependencies
for tracks from another mod. Duplicate assets, sparse arrays, more than 16 entries,
wrong handle kinds and combining a nonempty array with music are rejected.
Both a location’s single track and its choices take priority over the fight’s
music setting. Omitting both retains the existing fight/default fallback.
The ordered choices are part of the content fingerprint. They do not save a live playback position. Apply & Restart is required after changing the definition. Native selection/projection tests pass; audible playback, volume/mute behavior and scene transitions still need a game test. See the Animated Arena example.
sf2.locations.dojo_picker
Section titled “sf2.locations.dojo_picker”Signature: sf2.locations.dojo_picker { id = "...", button = sprite, button_pressed = sprite, title = key, choices = { { location = ..., name = key, preview = sprite }, ... } }
Returns: The qualified name of the picker’s dojo-menu button, <mod-id>.<id>.
When: During loading (at the top level of your scripts). It is a registration, not something to call from a callback.
Requires: content.register and presentation.dojo. No ui.create is
needed: Eclipse draws the picker itself.
Declares a ready-made dojo picker. Eclipse adds your button to the dojo’s side
menu (below the disciple toggle, like sf2.ui.dojo_button)
and opens the picker when it is pressed. You only describe the choices; no Lua
runs while the picker is open.
The picker shows a large medallion of the focused dojo with its name, over a dimmed scene tinted by a soft, slowly turning copy of the same art. A strip of all the medallions sits underneath and glides with the focus; the focused one is enlarged and the others shrink and fade with distance. Changing the focus slides the new medallion in from that side. The dojo the player is using now is tinted gold and labelled CURRENT DOJO.
| Control | Action |
|---|---|
Left/Right arrows, A/D, mouse wheel, D-pad or left stick, the < > arrows, clicking a medallion in the strip |
Move the focus (holding repeats). |
Enter, Space, gamepad A, clicking the large medallion or the focused strip medallion |
Enter that dojo: the medallion pulses, the choice is saved as with sf2.locations.select_dojo and the dojo reloads through the usual scene fade. Choosing the current dojo just closes the picker. |
Esc, Backspace, gamepad B |
Close without changing anything. |
| Field | Required/default | Meaning |
|---|---|---|
id |
Required | 1–64 lowercase ASCII letters, digits, _ or -. The button is named <mod-id>.<id> and counts toward your mod’s four dojo buttons. |
button |
Required | Sprite handle for the dojo-menu button. |
button_pressed |
The button sprite, darkened |
Sprite handle shown while the dojo-menu button is held down. Same size as button. |
title |
"CHOOSE YOUR DOJO" |
Localization handle for the heading (shown in capitals). |
choices |
Required | 1–64 choices, in display order, without duplicate locations. |
choices[i].location |
Required | A core:locations/<name> string or a location handle this mod registered with dojo = true. |
choices[i].name |
Required | Localization handle shown under the large medallion (in capitals). |
choices[i].preview |
Required | Sprite handle for the medallion. Square art with a transparent surround works best; it is drawn at up to 330 × 330 units. |
A mod may declare one picker. Choices whose native location is not installed,
or whose preview fails to load, are left out when the picker opens; if none
remain the button does nothing and a warning is logged. The button does not send
a dojo_button story event; plain sf2.ui.dojo_button buttons
still do.
local sf2 = require("sf2")
local choices = {}for _, name in ipairs({ "dojo", "dojo_india24", "haloween_dojo_2019" }) do choices[#choices + 1] = { location = "core:locations/" .. name, name = sf2.localization.key("dojo_name." .. name), preview = sf2.assets.sprite("sprites/dojos/" .. name), }end
sf2.locations.dojo_picker { id = "dojo_picker", button = sf2.assets.sprite("sprites/dojos/button"), button_pressed = sf2.assets.sprite("sprites/dojos/button_pressed"), title = sf2.localization.key("dojo_picker.title"), choices = choices,}sf2.locations.select_dojo
Section titled “sf2.locations.select_dojo”Signature: sf2.locations.select_dojo(location_or_core_id)
Returns: nil.
When: After a game profile has loaded, normally from a selector’s UI callback. The new backdrop applies on the next dojo or shop entry; it does not refresh an already open scene. The shop renders the selected dojo’s native layers and ambient effects behind its fighter preview and controls, including registered mod locations.
Requires: presentation.dojo and either this mod’s registered location handle
with dojo = true, or a core:locations/name string for an installed native
location with gamedata/locations/name/params.xml. UI creation separately
requires ui.create.
-- arena is a location handle registered earlier with dojo = true.-- Call inside your selector's on_click callback.sf2.locations.select_dojo(arena)sf2.ui.close(view)-- Select an installed native dojo without copying its location definition.sf2.locations.select_dojo("core:locations/dojo_india24")The host writes the preference into the current profile’s existing save DOM and requests the normal profile save. The call does not synchronously flush to disk. The preference takes priority over the native quest-selected dojo, and never changes ordinary battle locations. No fighter or inventory definition is changed.
The latest explicit selection replaces the previous preference. A mod can select its own registered choices or an installed native location. No selection is made automatically when a mod loads. Invalid handles or core IDs, missing native params, non-dojo mod locations, unavailable profiles and missing capability raise an error before changing the preference. If a selected core location becomes unavailable on a later run, the host temporarily uses the native dojo and preserves the saved choice until its params return.
sf2.locations.selected_dojo
Section titled “sf2.locations.selected_dojo”Signature: sf2.locations.selected_dojo()
Returns: Saved qualified location ID string, or nil for the native default.
When: After a game profile has loaded.
Requires: presentation.dojo.
local selected = sf2.locations.selected_dojo()local using_this_arena = selected == sf2.locations.name(arena)This reports the saved preference, including a currently unavailable location. It does not report the temporary fallback or the currently rendered scene. When its provider mod is absent, the game uses the native dojo and preserves the preference. Reenabling the provider restores it at the next dojo entry.
sf2.locations.reset_dojo
Section titled “sf2.locations.reset_dojo”Signature: sf2.locations.reset_dojo()
Returns: nil.
When: After a game profile has loaded, normally from a reset button.
Requires: presentation.dojo. The saved choice must belong to this mod, be
a core location, or already be empty; another mod’s preference
cannot be cleared by this function.
local selected = sf2.locations.selected_dojo()if selected == nil or selected == sf2.locations.name(arena) then sf2.locations.reset_dojo()endReset explicitly clears the preference and requests a profile save; it preserves unrelated save data. The native/default dojo returns on the next entry. Switching profiles and shutting down unload the active binding. Unknown or malformed preference data is retained and selection operations remain unavailable for that profile.
The Dojo Selector example opens a game-themed chooser from a custom map entry using deferred mode preparation. Closing it cancels preparation without entering a fight. Native menu insertion and automatic scene navigation are not supplied by these functions. Registration, Lua UI callbacks and save-store tests pass; full-game persistence, art rendering and scene transitions still need acceptance.