Compare commits

...

7 commits

Author SHA1 Message Date
RandomityGuy
717d4eb5c6 update readme 2026-04-06 22:42:11 +01:00
RandomityGuy
6fd8d12386 next update 2026-04-06 13:24:40 +01:00
RandomityGuy
6ffd04038c fix chat escaping 2026-04-06 12:31:24 +01:00
RandomityGuy
7a648a8aeb this button too 2026-04-05 02:40:36 +01:00
RandomityGuy
14c7885f58 this last change 2026-04-03 17:33:49 +01:00
RandomityGuy
1ec04251e8 update changelog 2026-04-03 00:22:31 +01:00
RandomityGuy
d7b1e68b21 try this to make them be singleplayer 2026-04-02 20:46:13 +01:00
8 changed files with 51 additions and 19 deletions

View file

@ -1,3 +1,26 @@
# 1.7.3
Hotfix time!
- Fixed chat messages being escaped a bit too much.
# 1.7.2
This update brings the following bugfixes:
- Added Import and Export Progress to Options menu to transfer game progress between devices.
- Added momentum based scrolling on touch devices for menus.
- Added TURN server support for multiplayer. Players behind strict NATs should now be able to play multiplayer without issues.
- Made the game files to be case insensitive to allow running the game on case sensitive filesystems without issues.
- Escaped all user input to prevent HTML injection in the UI.
- Fixed various race condition issues.
- Improved camera sensitivity on touch devices.
- Implemented camera centering for touch controls when free look is disabled.
- Various performance improvements and crash fixes.
- Implemented console cheat commands. DefaultMarble.attribute = value; to change marble attributes.
- Fixed a bug with the timer when playing a replay.
- Fixed a crash that could happen in multiplayer.
- Fixed not being able to load textures in certain custom levels.
- Fixed softlock when playing a user installed custom level.
- Fixed gravity changes not rewinding properly.
- Fixed skies not rendering correctly at times in the web version.
# 1.7.1 # 1.7.1
This update brings the following bugfixes: This update brings the following bugfixes:
- Fixed a crash when the marble goes out of bounds. - Fixed a crash when the marble goes out of bounds.

View file

@ -11,15 +11,15 @@ The browser port supports touch controls, meaning it can be played on mobile dev
### Marble Blast Platinum: [Play](https://marbleblast.randomityguy.me/) ### Marble Blast Platinum: [Play](https://marbleblast.randomityguy.me/)
### Marble Blast Ultra: [Play](https://marbleblastultra.randomityguy.me/) ### Marble Blast Ultra: [Play](https://marbleblastultra.randomityguy.me/)
## Windows and Mac ## Windows and Mac
### Marble Blast Gold: [Download](https://github.com/RandomityGuy/MBHaxe/releases/tag/1.1.12) ### Marble Blast Gold: [Download](https://github.com/RandomityGuy/MBHaxe/releases/tag/1.1.13)
### Marble Blast Platinum: [Download](https://github.com/RandomityGuy/MBHaxe/releases/tag/1.7.1) ### Marble Blast Platinum: [Download](https://github.com/RandomityGuy/MBHaxe/releases/tag/1.7.3)
### Marble Blast Ultra: [Download](https://github.com/RandomityGuy/MBHaxe/releases/tag/1.2.5-mbu) ### Marble Blast Ultra: [Download](https://github.com/RandomityGuy/MBHaxe/releases/tag/1.2.5-mbu)
## Mac Instructions - Important ## Mac Instructions - Important
Put the .app file in either /Applications or ~/Applications in order to run it properly. Put the .app file in either /Applications or ~/Applications in order to run it properly.
You will also have to bypass Gatekeeper since the .app is not signed. You will also have to bypass Gatekeeper since the .app is not signed.
## Android ## Android
### Marble Blast Gold: [Download](https://github.com/RandomityGuy/MBHaxe/releases/download/1.1.12/MBHaxe-Gold.apk) ### Marble Blast Gold: [Download](https://github.com/RandomityGuy/MBHaxe/releases/download/1.1.13/MBHaxe-Gold.apk)
### Marble Blast Platinum: [Download](https://github.com/RandomityGuy/MBHaxe/releases/download/1.7.1/MBHaxe-Platinum.apk) ### Marble Blast Platinum: [Download](https://github.com/RandomityGuy/MBHaxe/releases/download/1.7.3/MBHaxe-Platinum.apk)
### Marble Blast Ultra: [Download](https://github.com/RandomityGuy/MBHaxe/releases/download/1.2.5-mbu/MBHaxe-Ultra.apk) ### Marble Blast Ultra: [Download](https://github.com/RandomityGuy/MBHaxe/releases/download/1.2.5-mbu/MBHaxe-Ultra.apk)
## Xbox (NEW!) ## Xbox (NEW!)
@ -103,12 +103,11 @@ In browser, you can just resize your window. You can use the browser zoom featur
In native version, you can just resize the window if windowed or use the resolution options in the menu or just directly modify settings.json In native version, you can just resize the window if windowed or use the resolution options in the menu or just directly modify settings.json
## How do I change my FOV? ## How do I change my FOV?
Edit settings.json for native version, edit the MBHaxeSettings key in LocalStorage in browser. There is an FOV slider in the options menu.
In the Platinum and Ultra versions, there is an FOV slider.
## How do I unlock/lock FPS? ## How do I unlock/lock FPS?
You cannot unlock fps in the browser, it is forever set to vsync. You cannot unlock fps in the browser, it is forever set to vsync.
In the native version, use the options menu to unlock/lock fps, or edit settings.json and set "vsync" to false to unlock fps. In the native version, use the options menu to unlock/lock fps.
## Hey can you please add this new feature? ## Hey can you please add this new feature?
If this new feature of yours already exists in MBG but not in this port, then I will try to add it, if I get time to do so, otherwise chances are, I won't add it since I have other things to do and would rather not waste my time on this any further. You are free to do pull requests if you have already implemented said feature. If this new feature of yours already exists in MBG but not in this port, then I will try to add it, if I get time to do so, otherwise chances are, I won't add it since I have other things to do and would rather not waste my time on this any further. You are free to do pull requests if you have already implemented said feature.

BIN
data/ui/discord.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View file

@ -42,7 +42,7 @@ class MarbleGame {
static var instance:MarbleGame; static var instance:MarbleGame;
static var currentVersion = "1.7.2"; static var currentVersion = "1.7.3";
var world:MarbleWorld; var world:MarbleWorld;

View file

@ -89,10 +89,10 @@ class ChatCtrl extends GuiControl {
if (StringTools.trim(this.chatHudInput.text.text) != "") { if (StringTools.trim(this.chatHudInput.text.text) != "") {
sendText = '<font color="#F29515">${StringTools.htmlEscape(Settings.highscoreName.substr(0, 20))}:</font> ${StringTools.htmlEscape(this.chatHudInput.text.text.substr(0, 150))}'; sendText = '<font color="#F29515">${StringTools.htmlEscape(Settings.highscoreName.substr(0, 20))}:</font> ${StringTools.htmlEscape(this.chatHudInput.text.text.substr(0, 150))}';
if (Net.isClient) { if (Net.isClient) {
NetCommands.sendChatMessage(StringTools.htmlEscape(sendText)); NetCommands.sendChatMessage(sendText);
} }
if (Net.isHost) { if (Net.isHost) {
NetCommands.sendServerChatMessage(StringTools.htmlEscape(sendText)); NetCommands.sendServerChatMessage(sendText);
} }
} }
this.chatHudInput.text.text = ""; this.chatHudInput.text.text = "";
@ -118,7 +118,7 @@ class ChatCtrl extends GuiControl {
} }
public function addChatMessage(text:String) { public function addChatMessage(text:String) {
var realText = StringTools.htmlEscape(text); var realText = text;
this.chats.push({ this.chats.push({
text: realText, text: realText,
age: 10.0 age: 10.0

View file

@ -434,10 +434,10 @@ class MPPlayMissionGui extends GuiImage {
if (StringTools.trim(chatInput.text.text) != "") { if (StringTools.trim(chatInput.text.text) != "") {
var sendText = '<font color="#F29515">${StringTools.htmlEscape(Settings.highscoreName.substr(0, 20))}:</font> ${StringTools.htmlEscape(chatInput.text.text.substr(0, 100))}'; var sendText = '<font color="#F29515">${StringTools.htmlEscape(Settings.highscoreName.substr(0, 20))}:</font> ${StringTools.htmlEscape(chatInput.text.text.substr(0, 100))}';
if (Net.isClient) { if (Net.isClient) {
NetCommands.sendChatMessage(StringTools.htmlEscape(sendText)); NetCommands.sendChatMessage(sendText);
} }
if (Net.isHost) { if (Net.isHost) {
NetCommands.sendServerChatMessage(StringTools.htmlEscape(sendText)); NetCommands.sendServerChatMessage(sendText);
} }
} }
chatInput.text.text = ""; chatInput.text.text = "";
@ -728,7 +728,7 @@ class MPPlayMissionGui extends GuiImage {
} }
public static function addChatMessage(s:String) { public static function addChatMessage(s:String) {
var realText = StringTools.htmlEscape(s); var realText = s;
allChats.push(realText); allChats.push(realText);
if (allChats.length > 100) { if (allChats.length > 100) {
allChats = allChats.slice(allChats.length - 100); allChats = allChats.slice(allChats.length - 100);

View file

@ -259,6 +259,16 @@ class MainMenuGui extends GuiImage {
js.Browser.window.open("https://marbleblastultra.randomityguy.me"); js.Browser.window.open("https://marbleblastultra.randomityguy.me");
} }
this.addChild(mbu); this.addChild(mbu);
var discord = new GuiButton(loadStaticButtonImages("data/ui/discord"));
discord.horizSizing = Right;
discord.vertSizing = Top;
discord.position = new Vector(0, 320);
discord.extent = new Vector(152, 60);
discord.pressedAction = (sender) -> {
js.Browser.window.open("https://discord.gg/q4JdnRbVhF");
}
this.addChild(discord);
#end #end
#if js #if js

View file

@ -96,7 +96,7 @@ class HuntMode extends NullMode {
} }
} else if (element._type == MissionElementType.SimGroup) { } else if (element._type == MissionElementType.SimGroup) {
var scanPls = true; var scanPls = true;
if (Net.connectedServerInfo.oldSpawns) { if (Net.isMP && Net.connectedServerInfo.oldSpawns) {
if (element._name.toLowerCase() == "newversion") { if (element._name.toLowerCase() == "newversion") {
// Remove this // Remove this
elToRemove.push(element); elToRemove.push(element);
@ -121,8 +121,8 @@ class HuntMode extends NullMode {
}; };
override function getSpawnTransform() { override function getSpawnTransform() {
var idx = Net.connectedServerInfo.competitiveMode ? idealSpawnIndex : Math.floor(rng2.randRange(0, playerSpawnPoints.length - 1)); var idx = (Net.isMP && Net.connectedServerInfo.competitiveMode) ? idealSpawnIndex : Math.floor(rng2.randRange(0, playerSpawnPoints.length - 1));
if (!Net.connectedServerInfo.competitiveMode) { if (!(Net.isMP && Net.connectedServerInfo.competitiveMode)) {
var allTaken = true; var allTaken = true;
for (spw in spawnPointTaken) { for (spw in spawnPointTaken) {
if (!spw) { if (!spw) {
@ -370,7 +370,7 @@ class HuntMode extends NullMode {
var gemPos = gemElem.gem.getAbsPos().getPosition(); var gemPos = gemElem.gem.getAbsPos().getPosition();
if (level.mission.missionInfo.game == "PlatinumQuest") { if (level.mission.missionInfo.game == "PlatinumQuest") {
if (Net.connectedServerInfo.oldSpawns) { if (Net.isMP && Net.connectedServerInfo.oldSpawns) {
// Spawn chances! // Spawn chances!
var chance = switch (gemElem.gem.gemColor.toLowerCase()) { var chance = switch (gemElem.gem.gemColor.toLowerCase()) {
case "red.gem": case "red.gem":
@ -836,7 +836,7 @@ class HuntMode extends NullMode {
} }
override function update(t:src.TimeState) { override function update(t:src.TimeState) {
if (Net.connectedServerInfo.competitiveMode) { if (this.level.isMultiplayer && Net.connectedServerInfo.competitiveMode) {
if (competitiveTimerStartTicks != 0) { if (competitiveTimerStartTicks != 0) {
var currentTime = Net.isHost ? t.ticks : @:privateAccess level.marble.serverTicks; var currentTime = Net.isHost ? t.ticks : @:privateAccess level.marble.serverTicks;
var endTime = competitiveTimerStartTicks + (20000 >> 5); var endTime = competitiveTimerStartTicks + (20000 >> 5);