Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
2431de4
Work on unharddcoding songs from the assets folder
superpowers04 Aug 22, 2026
d341c6a
Support arbitrary charts and other difficulties
superpowers04 Aug 23, 2026
fb883af
Remove useless traces
superpowers04 Aug 23, 2026
ca2c30f
oops
superpowers04 Aug 23, 2026
1bf9fe2
Pause menu
superpowers04 Aug 25, 2026
692e811
Merge 9bad89553ec550fbb942374662f74fcfe097cd17, 6e9bf167a717eec78cbd5…
superpowers04 Aug 25, 2026
358ec81
wait a bit before hiding
Vortex2Oblivion Aug 25, 2026
1e468cf
Really basic transitions
superpowers04 Aug 26, 2026
6e1e78e
forgor sounds
superpowers04 Aug 26, 2026
bbb73cb
Better method of darkening the screen instead of using a constantly r…
superpowers04 Aug 26, 2026
dec44a8
Text more readable, actually update difficulty when switching selecte…
superpowers04 Aug 26, 2026
d5852e6
ACTUALLY fix now
superpowers04 Aug 26, 2026
cc280c1
Fix BF not being positioned correctly and flipping
superpowers04 Aug 28, 2026
f4ab96d
Default to baseStage if no stage found, default to bf if character no…
superpowers04 Aug 28, 2026
0f35d00
a
superpowers04 Aug 28, 2026
12fcf7b
Merge remote-tracking branch 'origin/master'
superpowers04 Aug 28, 2026
711995f
me when paused substate gets fucekd by git
superpowers04 Aug 28, 2026
f3f8ad8
Optimized pngs
superpowers04 Aug 28, 2026
b7b377d
bf flip
superpowers04 Aug 28, 2026
f5ab02d
Merge remote-tracking branch 'origin/master'
superpowers04 Aug 28, 2026
2c3a4f8
Merge remote-tracking branch 'origin/master'
superpowers04 Aug 29, 2026
8dd3958
Merge remote-tracking branch 'origin/master'
superpowers04 Aug 29, 2026
0ab1829
Merge remote-tracking branch 'origin/master'
superpowers04 Aug 31, 2026
7bb49c7
auto flip
Vortex2Oblivion Sep 2, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions assets/characters/bf/character.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
function onCreateCharacter(character)
character.flipX = not character.flipX

character.animation:addByPrefix("idle" ,"BF idle dance", 24, false, {})
character.animation:addOffset("idle", -5, 0)

Expand All @@ -8,13 +10,16 @@ function onCreateCharacter(character)
character.animation:addByPrefix("singUP" ,"BF NOTE UP0", 24, false, {})
character.animation:addOffset("singUP", -46, 27)

character.animation:addByPrefix("singRIGHT" ,"BF NOTE RIGHT0", 24, false, {})
character.animation:addOffset("singRIGHT", -48, -7)
local right = flipX and "singLEFT" or "singRIGHT"
character.animation:addByPrefix(right ,"BF NOTE RIGHT0", 24, false, {})
character.animation:addOffset(right, -48, -7)

character.animation:addByPrefix("singLEFT" ,"BF NOTE LEFT0", 24, false, {})
character.animation:addOffset("singLEFT", 5, -6)
local left = flipX and "singRIGHT" or "singLEFT"
character.animation:addByPrefix(left ,"BF NOTE LEFT0", 24, false, {})
character.animation:addOffset(left, 5, -6)

character.animation:play("idle", true)


character.barColor = Color.new(49, 176, 209, 255)
end
Binary file modified assets/images/bad.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/images/combo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/images/good.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/images/num0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/images/num1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/images/num2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/images/num3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/images/num4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/images/num5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/images/num6.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/images/num7.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/images/num8.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/images/num9.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/images/shit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/images/sick.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/images/slungus.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/sounds/cancelMenu.ogg
Binary file not shown.
Binary file added assets/sounds/confirmMenu.ogg
Binary file not shown.
5 changes: 3 additions & 2 deletions assets/stages/mainStage/stage.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@ function onCreateStage(stage)


boyfriend.position.x = 700
boyfriend.position.y = 100

boyfriend.position.y = (boyfriend.characterName=="bf") and 400 or 100
stage:add(boyfriend)

dad.position.x = 100
dad.position.y = 100
dad.position.y = (boyfriend.characterName=="bf") and 350 or 100
stage:add(dad)

local stagecurtains = Sprite.new(-500, -300)
Expand Down
10 changes: 9 additions & 1 deletion src/funkin/Camera.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ namespace funkin {
flashColor = col;
flashDuration = duration;
flashAlpha = 1.0f;

flashIn=true;
}

Vector2 Camera::getScreenToWorld(const Vector2 pos) const { return GetScreenToWorld2D(pos, camera); }
Expand All @@ -47,7 +49,13 @@ namespace funkin {
position, Vector2{.x = static_cast<float>(GetScreenWidth()) / 2.0f, .y = static_cast<float>(GetScreenHeight()) / 2.0f});
camera.zoom = zoom;
camera.rotation = angle;
if (flashAlpha > 0.0) {
if(flashIn){
flashAlpha += delta / flashDuration;
if(flashAlpha >= 1.0){
flashIn=false;
flashAlpha=1;
}
}else if (flashAlpha > 0.0) {
flashAlpha -= delta / flashDuration;
}
}
Expand Down
7 changes: 4 additions & 3 deletions src/funkin/Camera.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ namespace funkin {

float angle = 0.0f;
float zoom = 1.0f;
float flashAlpha = 0.0f;
float flashDuration = 0.0f;
Color flashColor = BLANK;

Vector2 target = Vector2Zero();
Vector2 position = Vector2Zero();
Expand All @@ -44,9 +47,7 @@ namespace funkin {
void update(float delta);
graphics::Shader premultiplyShader;
private:
float flashAlpha = 0.0f;
float flashDuration = 0.0f;
Color flashColor = BLANK;
bool flashIn = false;
Camera2D camera{};
RenderTexture canvas{};
};
Expand Down
2 changes: 2 additions & 0 deletions src/funkin/Game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ namespace funkin {

scene = std::move(newScene);
scene->create();

defaultCamera->flash(BLACK, 0.5f);
switching = false;
nextScene = nullptr;
}
Expand Down
6 changes: 3 additions & 3 deletions src/funkin/Group.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@
\
template<Is##base T> \
void name<T>::remove(std::shared_ptr<T> object) { \
if (std::ranges::find(members, object) != members.end()) { \
members.erase(std::ranges::find(members, object)); \
} \
if (auto ranges = std::ranges::find(members, object); ranges != members.end()) { \
members.erase(ranges); \
} \
} \
\
template<Is##base T> \
Expand Down
31 changes: 19 additions & 12 deletions src/funkin/data/Song.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,31 @@ using json = nlohmann::json;
namespace funkin::data {
SongData Song::parseSong(const std::string &songName, const std::string &difficulty) {
const std::string songPath = "assets/songs/" + songName + "/";
if (FileExists((songPath + difficulty).c_str())) {
return parseLegacy(songPath + difficulty);
}
if (FileExists((songPath + songName + "-metadata.json").c_str())) {
return parseVSlice(songName, difficulty);
return parseVSlice(songPath + songName, difficulty);
}
return parseLegacy(songName, difficulty);
return parseLegacy(songPath + songName + "-" + difficulty + ".json");
}

SongData Song::parseLegacy(const std::string &songName, const std::string &difficulty) {
const std::string path = "assets/songs/" + songName + "/" + songName + "-" + difficulty + ".json";
SongData Song::parseSongFromPath(const std::string &path, const std::string &difficulty) {
if (FileExists((path + "-metadata.json").c_str())) {
return parseVSlice(path, difficulty);
}
if (FileExists((path + ".json").c_str())) {
return parseLegacy(path+".json");
}
return parseLegacy(path);
}
SongData Song::parseLegacy(const std::string &path) {
auto chart = std::ifstream(path);
auto parsedChart = json::parse(chart);
chart.close();


std::vector<NoteData> playerNotes = {};
std::vector<NoteData> opponentNotes = {};

std::vector<EventData> events = {};

nlohmann::json_abi_v3_12_0::json song;
Expand Down Expand Up @@ -97,8 +106,8 @@ namespace funkin::data {
}

// load events from json
if (FileExists(("assets/songs/" + songName + "/events.json").c_str())) {
auto eventStream = std::ifstream("assets/songs/" + songName + "/events.json");
if (FileExists((path + "/events.json").c_str())) {
auto eventStream = std::ifstream(path + "/events.json");
auto parsedEvents = json::parse(eventStream);
eventStream.close();

Expand Down Expand Up @@ -151,9 +160,7 @@ namespace funkin::data {
.spectator = spectator};
}

SongData Song::parseVSlice(const std::string &songName, const std::string &difficulty) {
const std::string path = "assets/songs/" + songName + "/" + songName;

SongData Song::parseVSlice(const std::string &path, const std::string &difficulty) {
auto chart = std::ifstream(path + "-chart.json");
auto meta = std::ifstream(path + "-metadata.json");

Expand All @@ -171,7 +178,7 @@ namespace funkin::data {
for (auto note: parsedChart["notes"][difficulty]) {
bool player = note["d"] < 4;

auto noteData = NoteData{.player = player,
NoteData noteData = NoteData{.player = player,
.lane = static_cast<uint8_t>(static_cast<short>(note["d"]) % 4),
.time = note["t"],
.length = note.contains("l") ? static_cast<float>(note["l"]) : 0.0f};
Expand Down
4 changes: 3 additions & 1 deletion src/funkin/data/Song.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,15 @@ namespace funkin::data {
std::string player;
std::string opponent;
std::string spectator;
std::string path;
} SongData;


class Song {
public:
static SongData parseSong(const std::string &songName, const std::string &difficulty);
static SongData parseSongFromPath(const std::string &path, const std::string &difficulty);
static SongData parseVSlice(const std::string &songName, const std::string &difficulty);
static SongData parseLegacy(const std::string &songName, const std::string &difficulty);
static SongData parseLegacy(const std::string &path);
};
} // namespace funkin::data
1 change: 1 addition & 0 deletions src/funkin/modding/LuaScript.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ namespace funkin::modding {
lua_Character.set("type", &objects::Character::type);
lua_Character.set("barColor", &objects::Character::barColor);
lua_Character.set("cameraOffset", &objects::Character::cameraOffset);
lua_Character.set("characterName", &objects::Character::characterName);

auto lua_Stage = state.new_usertype<objects::Stage>("Stage");
lua_Stage.set("stageName", &objects::Stage::stageName);
Expand Down
27 changes: 12 additions & 15 deletions src/funkin/objects/Character.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@ namespace funkin::objects {
Character::Character(const float x, const float y, const std::string &characterName, const CharacterType type) : Sprite(x, y) {
this->characterName = characterName;
this->type = type;

const std::string basePath = "assets/characters/" + characterName;
std::string basePath = "assets/characters/" + characterName;
if(!FileExists(basePath.c_str())){
TraceLog(5,("Unable to load character '"+this->characterName+"'. Fallbacking to bf").c_str());
this->characterName="bf";
basePath = "assets/characters/bf";
}

loadTexture(basePath + "/spritesheet.png");
if (FileExists((basePath + "/spritesheet.txt").c_str())) {
Expand All @@ -17,7 +21,8 @@ namespace funkin::objects {
}

if (type == CharacterType::BOYFRIEND) {
barColor = LIME;
barColor = LIME;
flipX = true;
}

script = std::make_shared<modding::LuaScript>(basePath + "/character.lua");
Expand All @@ -28,21 +33,13 @@ namespace funkin::objects {

bool Character::canDance(const float stepCrochet) const {
const auto animationName = getCurrentAnimation()->name;
return (holdTimer > stepCrochet * 0.0011f * singDuration && animationName.starts_with("sing") && !animationName.ends_with("miss") ||
holdTimer == 0.0f);
return (holdTimer == 0.0f ||
holdTimer > singDuration && animationName.starts_with("sing") && !animationName.ends_with("miss"));
}

void Character::dance(const bool force) {
if (dancesLeftAndRight) {
if (danced) {
animation.play("danceRight", force);
} else {
animation.play("danceLeft", force);
}
danced = !danced;
} else {
animation.play("idle", force);
}
animation.play(dancesLeftAndRight ? ((danced=!danced) ? "danceLeft" : "danceRight") : "idle", force);

holdTimer = 0.0f;
}

Expand Down
2 changes: 1 addition & 1 deletion src/funkin/objects/Character.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace funkin::objects {
bool dancesLeftAndRight = false;
std::uint8_t danceEvery = 2;
float holdTimer = 0.0f;
float singDuration = 4.0f;
float singDuration = 1.0f;
CharacterType type = CharacterType::DAD;
Color barColor = RED;
Vector2 cameraOffset = Vector2Zero();
Expand Down
10 changes: 9 additions & 1 deletion src/funkin/objects/Stage.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
#include "Stage.hpp"

#include <fstream>
#include <iostream>

#include "funkin/modding/LuaScript.hpp"

namespace funkin::objects {
Stage::Stage(const std::string &stageName, const std::shared_ptr<Character> &boyfriend, const std::shared_ptr<Character> &dad,
const std::shared_ptr<Character> &girlfriend) {

this->stageName = stageName;
script = std::make_shared<modding::LuaScript>("assets/stages/" + stageName + "/stage.lua");
if(!FileExists(("assets/stages/" + stageName + "/stage.lua").c_str())){
TraceLog(5,("Unable to load stage '"+stageName+"'. Fallbacking to mainStage").c_str());
this->stageName="mainStage";
}
script = std::make_shared<modding::LuaScript>("assets/stages/" + this->stageName + "/stage.lua");
script->set("boyfriend", boyfriend);
script->set("dad", dad);
script->set("girlfriend", girlfriend);
Expand Down
Loading