HyperQuark compiles Scratch projects to WebAssembly, with the aim of running them quicker than scratch and also quicker than TurboWarp, which compiles to javascript. HyperQuark is not at feature parity with scratch, but is useable for a number of projects that only use the blocks listed on the home page. Projects listed on the homepage should function correctly, but are designed for debugging and so you may need to open up your browser's devtools (usually ctrl+shift+j/i) to see say/think block 'bubbles'.
- Rust v1.65.0 or later
- the
wasm32-unknown-unknown
target (rustup target add wasm32-unknown-unknown
) - wasm-bindgen-cli (
cargo install -f wasm-bindgen-cli
) - wasm-opt (install binaryen using whatever package manager you use)
cargo-outdir
(cargo install cargo-outdir
)
./build.sh -Wp # use -Wd for a debug build without optimisation
You may need to run chmod +x build.sh
if it says it doesn't have permission.
The build script has additonal configuration options; run ./build.sh -h
for info on these.
If you experience runtime stack overflow errors in debug mode, try using the -s
or -z
options to enable wasm-opt, or build in production mode; weird wasm errors in production mode may conversely be solved by disabling wasm-opt using the -o
flag.
If an error occurs during execution and you need a stack trace, run with the -D
flag to enable panicking with DWARF debug symbols. You need to set up your browser to display a proper stack trace using these debug symbols. You'll need to disable wasm-opt using -o
for this to work, as wasm-opt currently crashes when it encounters DWARF.
To preview the website (e.g. to run a project), use npm run watch
. Do not just run vite
as this will build in debug mode which doesn't work.
To add a new block named category_opcode
, if it cannot be reduced to simpler blocks:
- create
src/instructions/category/opcode.rs
. Make sure touse super::super::prelude::*
and create the relevantpub
items:
- (optional)
pub struct Fields
(must beDebug
andClone
) pub fn wasm(func: &StepFunc, inputs: Rc<[IrType]>, (fields: &Fields)?) -> HQResult<Vec<InternalInstruction>>;
-
- wasm is generated using the
wasm_gen::wasm
macro. See its README for usage instructions, or e.g. say.rs for an example.
- wasm is generated using the
pub fn acceptable_inputs() -> HQResult<Rc<[IrType]>>;
-
- these should really be base types (see
BASE_TYPES
in types.rs)
- these should really be base types (see
pub fn output_type(inputs: Rc<[IrType]>, (fields: &Fields)?) -> HQResult<ReturnType>;
-
- the output type should be as restrictive as possible; loose output types can cause us to lose out on some optimisations
-
- Most output types should be either
ReturnType::None
orSingleton(IrType)
(included in the module prelude); blocks can return multiple values viaMultiValue(Rc<[IrType]>)
but probably shouldn't.
- Most output types should be either
- ensure to add relevant
instructions_test!
s - see instructions/tests.rs for usage
- add
pub mod opcode;
tosrc/instructions/category.rs
, creating the file if needed
- if you're creating the category file, add
mod category;
tosrc/instructions.rs
- add the block to
from_normal_block
insrc/ir/blocks.rs
; in most cases this should be a direct mapping ofBlockOpcode::category_opcode => IrOpcode::category_opcode
- add the block's input names to
input_names
insrc/ir/blocks.rs
If the block can be reduced to simpler steps, only carry out steps 3 and 4 above.
name | number of bytes | optional? | description |
---|---|---|---|
sprite_info | 80 * number of sprites (i.e. target num - 1 ) |
yes | see src/wasm/sprite.rs |
threads | 4 * thread_num | present iff using the CallIndirect scheduler | indices of the next step funcs of currently running threads |
All values should be guaranteed to have the maximum possible alignment for that value type. Unused/padding bytes are not guaranteed to have any specific values and may be overwritten.
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.