Skip to content

[WIP] feat(custom-extensions): init#210

Closed
gradylink wants to merge 59 commits intomainfrom
feat/custom-extensions
Closed

[WIP] feat(custom-extensions): init#210
gradylink wants to merge 59 commits intomainfrom
feat/custom-extensions

Conversation

@gradylink
Copy link
Member

@gradylink gradylink commented Aug 5, 2025

Extension Repository

Warning

This PR is currently being rewritten to use WASM instead of dynamically loaded libraries, this was chosen instead of creating a new PR so we can reuse parts of this PR. This will severely limit the scope of what this PR can do (and therefore what extensions can be made) but many features will be possible to replace.

Note

Unlike with other PRs this one is going to completely incompatible (won't even compile) until that platform is checked off in the checklist. There are also going to be points in this PR where backtracking is done to make it even possible to port to another platform; during these times it is possible that this entire branch will not work and not compile at all for any platform.

Note

Wii, GameCube, and Switch all seem to be impossible to support with this because there are no homebrew libraries for dynamic libraries.

Note

A lot of the files marked as changed in this PR are only due to a minor change in the .clang-format file.

Checklist

  • Docs (they were done, but I keep forgetting to update them...)
    • Dev Docs
      • API Docs
      • Example Extension
    • User Docs
  • Detecting used extensions
  • Loading libraries
  • Calling block callbacks
    • Number Reporters
    • Boolean Reporters
    • String Reporters
    • Command Blocks
    • Hat Blocks
  • Run Code on Update
    • Before Scratch 3DS
    • Before Rendering
    • After Rendering
    • After Scratch 3DS
  • Show warning about external/unofficial code when loading projects with custom extensions. (waiting for UI overhaul)
  • Make it a compilation flag
  • Pass runtime data
    • API
    • Implementation

WASM Checklist

This is the checklist for rewriting this PR to use WASM instead of dynamically loaded libraries.

  • Remove old loading systems
  • Get WASM3 compiled for each platform
  • Replace the old system was WASM3

@gradylink
Copy link
Member Author

I think I'm going to use the Bitwise extension for testing, or is there a better extension?

@gradylink
Copy link
Member Author

I just realized there is no need for an extension.json file. Everything I need is already in the .sb3 file.

@KirbySuper008
Copy link

I think I'm going to use the Bitwise extension for testing, or is there a better extension?

Not a Turbowarp extension, but the "Music:" extension with instruments and drums might be easy (apart from the actual audio playback, lol)

@gradylink
Copy link
Member Author

gradylink commented Aug 6, 2025

Well the issue with that is this is for custom extensions. I think built-in extensions will be handled differently.

EDIT: I'm implementing Bitwise rn anyway so I'll just use that.

@gradylink
Copy link
Member Author

gradylink commented Aug 6, 2025

@NateXS, may I ask why you're using an enum for opcodes instead of just storing them as strings.

EDIT: asking because it means I need to set up a special system specifically for custom extension blocks.

@NateXS
Copy link
Member

NateXS commented Aug 7, 2025

@NateXS, may I ask why you're using an enum for opcodes instead of just storing them as strings.

EDIT: asking because it means I need to set up a special system specifically for custom extension blocks.

Mostly for performance, although I don't think it gave any noticable improvements to be honest.
I can change it back to strings if it'll make this easier

@gradylink
Copy link
Member Author

gradylink commented Aug 7, 2025

Yeah, it would, probably do that on the feat/custom-extensions branch because I think it should be part of this PR. It would use a std::map, right?

@gradylink
Copy link
Member Author

I meant to say "used" not "loaded" but... I don't want to force push, so I guess it's just going to be that now.

@gradylink
Copy link
Member Author

gradylink commented Aug 7, 2025

I'm going to need to take a small break from this PR because my CMake setup just decided to completely break itself (I'm using CMake for the TurboWarp Extension Ports).

@gradylink
Copy link
Member Author

I just realized that file extension code is useless 'cause a lot of this is platform dependent...

@gradylink
Copy link
Member Author

I like how GitHub told me there were conflicts, and they couldn't be fixed by the web editor and when I merged it locally there were no conflicts...

@gradylink
Copy link
Member Author

@NateXS how are hat blocks handled, it looks to me like they are called every frame, and they run if they return BlockResult::CONTINUE?

Hat blocks run with BlockExecutor::runAllBlocksByOpcode(), and since they don't do anything by themselves, they return BlockResult::CONTINUE to run the blocks inside of the hat block.

So I would need to implement a loop to run each of the custom extension hat blocks every frame, and then I would then have them return a bool to say if they should run. And then run BlockExecutor::runAllBlocksByOpcode() on a dummy block with the same name as the custom block? Would that work, @NateXS?

@NateXS?

currently untested because I'm on vacation and Cemu is just not working...
@gradylink
Copy link
Member Author

gradylink commented Aug 12, 2025

After looking into it, 3DS support is going to require a major rewrite of the extension blocks system...

Also, extensions are going to be designed to made primarily with C after the change.

EDIT: I've looked more into what I'm going to need to do to get this to work on 3DS, and I can only reasonably say that there's a roughly 60/40 (in favor of the 3DS) that I can support it. I hope I can get libffi to work on the 3DS because I think that's the only way this will be possible.

@gradylink
Copy link
Member Author

gradylink commented Aug 15, 2025

I think I'm going to end up with a pointer pointing to a pointer pointing to a pointer pointing to a string... (for lists)

EDIT: This is probably going to be leaking a lot of memory at first.

@gradylink
Copy link
Member Author

gradylink commented Aug 15, 2025

NEVERMIND. THE HOMEBREW DISCORD IS AMAZING AND THEY'VE HELPED ME FIGURE OUT AN ALTERNATIVE SOLUTION USING ALLOCATOR MAGIC AND OVERRIDING THE NEW OPERATORS.

EDIT: I've begun implementing this, I'll hopefully have a version for you to test some time in the next few days (I'm still on vacation).

@gradylink
Copy link
Member Author

And, for extensions in .js format, we can use this backend created by Symbitic Symbitic/CTRJS

@DevelopCMD, sorry I didn't state my reasoning for not supporting JS extensions very well earlier. The main issue is that JavaScript extensions hook directly into scratch-vm so I would have to write a pretty complicated compatibility interface between Scratch-3DS and the equivalent scratch-vm APIs. That would mean it would require a pretty significant amount of memory and CPU time, which we are already struggling with.

@gradylink
Copy link
Member Author

gradylink commented Aug 19, 2025

This is actually really painful to work on, if I can't at least get it working on Wii U (and make it a Wii U specific feature), I'm going to migrate to an interpreted language like JavaScript or Lua.

EDIT: actually, if it doesn't work, I'll just make extensions statically linked, so they'll need to be built directly in.

@gradylink
Copy link
Member Author

gradylink commented Aug 29, 2025

Ok, due to the fact that we have (and will have) so many platforms, I think I'm going to switch from using dynamically loaded libraries to using WASM with https://github.com/wasm3/wasm3, that means a major refactor.

EDIT: i've been trying to compile wasm3, it seems to have a few issues with devkitpro. So I might try a few other libraries like https://github.com/bytecodealliance/wasm-micro-runtime

@gradylink
Copy link
Member Author

OK, so I think I'm going to close this PR due to the fact that this implementation of custom extensions is not very portable and incredibly hard to create. This does not mean I am completely scrapping custom extensions, it just means they're being put on hold for a little while until I can figure out the best way to create an alternative implementation that is more portable.

@gradylink gradylink closed this Aug 30, 2025
@gradylink gradylink deleted the feat/custom-extensions branch September 13, 2025 03:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[REQUEST] Implement "Network" and "Local Storage" TurboWarp extensions

4 participants