Introduction

This document lists and explains the technologies used to develop SFMB.

Development tools

  • As development spanned a long time, the toolchain was continuously updated to newer versions.
    • Visual Studio 2015
    • Visual Studio 2017
    • Visual Studio 2019
    • Visual Studio 2022
  • Visual Studio Code
    • Used only for server and bot development.

Programming languages

  • C++ 17
  • Javascript (NodeJS)

Game engine

Core libraries

NaLib

  • A library of foundational code, written by hand, expected to be reusable beyond just the game.
  • Developed with cross-platform support in mind, based on experience from a previous job.
  • "Na" is short for NeoArc, used as a class prefix. It does not mean sodium.
  • In practice, NaLib holds much of SFMB's core code, and SFMB is built on top of it.

ExtLib

  • A bundle of open-source libraries.
  • Box2D
    • The well-known 2D physics engine used in games like Angry Birds.
    • Brought in to try replacing the game's physics engine, but ended up unused.
  • catch2
    • Unit testing framework
  • cppcodec
  • cxxopts
  • dirent
    • Filesystem-related library
    • Used in the early implementation, but became unnecessary after moving to modern C++.
  • fmt
    • String formatting library
  • JsonLib
  • libpng
  • magic_enum
  • MemoryModule
  • miniz
  • miniz-cpp
  • msgpack
  • PicoSHA2
  • zlib
  • discordbuddy
    • A hand-ported reimplementation of BatteryShark's discordbuddy
  • discord-rpc
  • discord-sdk
    • Used for Discord Rich Presence
  • rapidjson
    • Included because the discord library uses it.
  • curl
    • Networking library
  • DirectX 9.1
  • OpenGL
  • SDL
  • FMOD
  • BASE

Render engine

  • Initially built around DirectX 9.1, then abstracted to try supporting OpenGL.
  • The following features were implemented for each renderer:
    • Letterboxing (preserving the content's aspect ratio and filling the rest with black)
    • Bitmap loading (bmp, png)
    • Drawing a portion of a texture at a desired position
      • Rotation
    • Creating custom textures
    • Effects via pixel shaders
    • Text output with Windows fonts

Pixel shaders

  • Mostly used for color conversion.
  • Still a beginner-level implementation.

Sprite handling

  • Loads the texture suited to the required theme, and uses the .sprite file to control the sub-region data of the sprite sheet.
  • HD textures
    • If a file matching (texture filename) + @2x exists, it is loaded as an HD texture.
    • A 2x-size texture is loaded and rendered scaled down to 50%.
  • Each frame, the sprites to be drawn are gathered, sorted by Z-order, and rendered in order.

Input handling

DirectInput

  • Joystick input handling
    • Joystick input is analyzed and translated into keyboard input.
  • Keyboard input handling

Mouse

  • Mouse input simply uses the mouse messages (WM_MOUSE…).
  • The UI engine converts mouse clicks into button clicks.

Sound handling

FMod

  • Used to play mp3, ogg, and wav files.
  • Supports simultaneous multi-channel playback and per-channel volume.
  • Supports loop points.

BASE

  • Used to implement music blocks differently from Mario Maker.
  • Can load sound fonts and play MIDI music.

Scene

  • Implemented as a state machine.
  • Mainly handles transitions from one scene to another.
    • Automatically after a certain time
    • Through the UI
  • Some transitions are requested by the player object.
  • During a transition, a dedicated effect (fade, circle, curtain, etc.) is also played.

Networking

  • Most in-game networking is processed on a transaction thread to keep it asynchronous.
  • When a networking task on the transaction thread finishes, it calls a callback implemented within the GameState.

Game objects

  • Implemented as a state machine.
  • All game objects share a common list of states.
    • Idle
    • Walk
    • Jump
    • Swim
    • SpinJump
    • GroundPound
    • WallSlide
    • PropellerJump
    • Die
    • More than 150 such states are defined.
  • Originally implemented with raw pointers, but after hitting limits tracking down mysterious crashes, the structure was later improved.

Stage

  • One of the classes with the most code in the game.
  • Manages the tile map.
  • Manages the live objects within the map.

Camera

  • The class that handles which part of the stage to show.
  • Ground shaking and forced scrolling are also handled through the camera.

Physics engine

  • Built by hand, implemented in a brute-force way.
  • Its structure was heavily reworked for performance whenever it hit a wall.
  • Roughly, it does the following every frame:
    • Gathers all live objects in the stage
    • Moves each object to its target position based on its current speed
    • Checks whether each object collides with tiles
      • If it collides, sets flags per tile type
        • Normal tile
        • Jump block
        • Marimba block
        • Water
        • Lava
        • Poison
        • Star block / Death block
    • Checks whether each object collides with slopes and corrects position/speed
    • Compares objects against each other to check for collisions (N^2)
      • Uses AABB by default, but also supports circular hitboxes and objects with multiple hitboxes
      • Builds and stores a list of mutually colliding objects
    • Processes feedback based on the state of the colliding objects
      • Just remembers the collision state (default)
      • Pushed apart (when one object does not allow overlap)
      • Ridden on top (platforms, etc.)
    • Restores each object to its original position

UI engine

  • Built by hand, with only the minimal components and features needed.
  • Basic components
    • Panel
    • Container
    • Text
    • AreaText
    • Button
    • ImageButton
    • CheckBox
    • Edit
    • Spin
    • Rectangle (Image)
    • AnimationRectangle
    • Tooltip
    • Popup
    • List
    • VirtualList
    • ScrollForm
  • Game-specific components
    • AbilityFlagImage (ability display)
    • CountryFlagTextButton (country flag button)
    • UserAvatarButton / UserNameButton (user avatar/name button)
    • SingleStageButton / WorldStageButton (stage button)
    • CustomGameButton
    • CommentDollEdit
  • A separate editing tool was also built to make laying out UI screens easier.

Game

Application

Windows

  • Implemented as a Win32 application.
  • Creates a window and passes the window handle to DirectX / OpenGL for rendering.
  • For SDL, window creation is handled by SDL itself, so it is done differently.

CustomURL Scheme

  • Used to implement various integrations through the "sfmb://" protocol.
  • The CustomURL scheme is registered on game launch (written directly to the registry).
  • Used for Force Update and Direct Play.

MAC OS

  • (Hard to remember exactly, as it was long ago) Developed as an application with a GLView.
  • A GLView can be thought of as a prebuilt window that supports OpenGL.

Scenes

  • The game is composed of many scenes; grouped by purpose:

Startup / system

  • Logo
  • Title
  • RegisterUser
  • Profile
  • Credits
  • AppUpdate
  • GameThemeUpdate
  • SystemAlert
  • ErrorMessage

World / stage selection

  • WorldStage
  • WorldStageDirectPlay
  • LocalStagePack
  • EnterStage
  • StageIntro / SkyIntro

In-play movement / events

  • Enter/Exit Door, Pipe, Warp, Sky
  • PageScroll
  • Play
  • NpcTalk / Speech
  • MessageBlock
  • ShapeChange
  • LoseHP
  • Die

Clear / end

  • Goal
  • HitGoalBox / HitGoalOrb / HitGoalPost
  • FlagDown
  • CutBridge
  • RescuePrincess
  • SingleStageClear / SingleStageGameOver
  • GameOver
  • TimeUp

Other modes / features

  • ChallengeMode / ChallengeSummary
  • MiniGame
  • Gallery / Showcase
  • ReportStage
  • ShowUserList
  • ManageDevice
  • Pause
  • AvatarPaint
    • A paint feature for drawing your own avatar, implemented by hand. (canvas 144 x 144)
    • Pencil, Eraser, Bucket tools
    • Color palette
    • Undo / Redo (up to 10 steps)
    • Grid display toggle
    • Multiple slots + copy between slots
    • Animation support
    • Presets provided
    • Export

Map editor

Toolbar

  • Originally written as an MDI application with a toolbar.
  • As the toolbar buttons grew, the icons became hard to tell apart and felt cluttered, so the toolbar was replaced with a ribbon bar.

Dynamic ribbon construction

  • Rather than building the ribbon bar with MFC's designer, the menus are constructed dynamically at the code level.
    • The bitmaps used as icons are also generated dynamically from the DesignPalette image.
  • The menu layout is sent from the server.
    • That is, it was designed so the game cannot be played via an offline crack. (since 7.0)

Dynamic Design Palette switching

  • Because each theme needs different icons, the entire ribbon bar's icons are reloaded whenever the active stage changes.
  • It gathers every button control and replaces them with newly generated bitmaps.
  • For this, it uses a hand-built class instead of the default ribbon button.

Property window

  • Uses MFC's PropertyGrid.
  • By inheriting the NaPropertyObjectBase class, the properties of any implemented object can be shown easily.
  • Custom PropertyItem classes were implemented as needed for certain property value types.
    • Bool : shows a checkbox instead of selecting true/false
    • Enum(int) : actually an int value, but shown as meaningful text rather than a magic number
    • Color(int) : clicking opens a custom color picker
    • Extended : shows the value field as a button that opens a separate editor on click

Status bar

  • Shows information needed while editing, such as the current cursor position (tile coordinates), the active stage info, and the selected object.

Document window

  • The inside of the MDI Document is drawn directly by the game engine.
  • For high performance, only a single frame is rendered when a WM_PAINT message occurs.

Dialogs

  • The map editor has many dedicated windows for managing themes and various resources.

Theme / background

  • Theme management window (clone game theme, manage theme settings)
  • Theme definition window (sky color, parallax background, background objects, etc. / see [[sfmb_tutorial_theme_settings]])
  • Theme selection window
  • Custom theme selection window

Pixel art management window

  • Import from a file
  • Favorites
  • Animation frame selection
  • A paint feature is implemented by hand.
    • Pencil, Eraser, MagicEraser, Bucket, ColorPicker tools
    • Color palette / color spectrum
    • Undo / Redo
    • Grid display toggle
    • Canvas size change

Pixel art creation window

  • Creates a new pixel art by selecting a canvas size.

Custom enemy / block management window

  • Custom enemy management / gallery / favorites
  • Character definition editing
  • Custom block management

Costume / character / ability selection window

  • Costume selection
  • Character selection
  • Weapon position selection
  • Voice type selection

AbilityFlag selection window

  • Select the ability flags (AbilityFlag) an object will have
  • Manage ability presets

Music / sound window

  • Background music selection
  • Sound effect selection
  • Music block helper / tuner

Others

  • Stage preview
  • Sub-stage settings
  • Object list
  • Tag selection
  • Tileset import
  • Live text editing
  • Creator comment

Game server

  • At first, online mode was serverless, with no server app.
  • After a hack wiped out the entire server database, a server app was developed to prevent it from happening again.
  • Implemented in Node.js
    • Express : communication with the game, stage upload handling
    • Firebase : stores users, stages, leaderboards, ban lists, etc.
    • Integrates with Google Sheets, Discord
    • The operating environment is split into alpha / beta
  • The cloud setup process is documented in [[make_nodejs_server_on_oracle_cloud]].

Discord bot

  • A separate bot for running the beta-test community (Discord server), also implemented in Node.js.
    • discord.js : slash commands, modal input handling
    • canvas, gifencoder : profile card, GIF image generation
    • Commands are split by permission level (regular / moderator / admin, etc.)