Replies: 7 comments
-
|
Hello @scambier! One of the current focuses of Boa is to improve the API and fulfill the use cases of out users, so all feedback is welcome. I'm glad to see that you were able to use Boa directly for your project, but feel free to report any rough edges you might have found. On the performance side, there are multiple things to it. First, I don't have access to the code, so it's difficult to give a different answer. If the Rust version is doing computation on native code, then that would explain why it's so much faster. On the difference with TIC-80, I'm not aware on how does it work to allow JavaScript in the engine. Does it somehow pre-compile it? Does it have a full JavaScript engine embedded with it? I can talk a bit on Boa's performance. Until now, we have been mostly working on "making it work", which means that our time has been mostly spent on getting an engine that can actually run proper JavaScript (getting the spec right), and not so much on performance. We have made some performance changes, of course, and it's slowly improving. We have some issues open where we have found room for performance optimizations. Nevertheless, since the effort of getting the spec covered is currently taking us most of our effort, I cannot give you estimates on when will we be able to improve the performance of the engine, or how much will it improve. Note that a fast engine that is not conformant is, from our perspective, worse than a conformant and slower engine. In any case, it would be very good to get some performance numbers from your code. Would it be possible for you to run the commands in the profiling documentation to see where is the engine spending time in your case? We might be able to find bottlenecks we don't know about, and even improve the engine for your particular use case. |
Beta Was this translation helpful? Give feedback.
-
|
Thanks for that answer!
It uses Duktape, but I didn't dig the internals for more more details.
I totally agree with this sentiment. I mean, if Boa isn't fast enough for this very particular usecase, fair enough. Embedding JS in Rust to make games is not really common :p
I tried running the profiler, but something isn't working as it should $ summarize summarize .\my_trace.mm_profdata
thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', decodeme\src\lib.rs:117:26
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
$ crox .\my_trace.mm_profdata
thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', decodeme\src\lib.rs:117:67
note: run with `RUST_BACKTRACE=1` environment variable to display a backtraceI'm on Windows, if that matters. So, if you'd like to take a look at my project, I just uploaded it here: https://github.com/scambier/sim-engine. It's obviously in a rough state, but you should be able to start the benchmark without any issue. The parts related to boa are here and here. Thanks! |
Beta Was this translation helpful? Give feedback.
-
|
@scambier Did you ever solved those panics? I am having a similar issue now. |
Beta Was this translation helpful? Give feedback.
-
|
@ItsEthra no sorry :/ And I haven't tried it since |
Beta Was this translation helpful? Give feedback.
-
15 months later, a small update on the numbers, on the same computer
So, for this synthetic benchmark, the performances of Boa have nearly doubled 🙌 |
Beta Was this translation helpful? Give feedback.
-
Small but steady steps. We'll get there eventually :) |
Beta Was this translation helpful? Give feedback.
-
|
I use boa for my ui scripts which are quite tiny and I get well above 60fps. I chose js because it allows me to make ui's in my browser without needing to load my game and lets me use all the amazing ui building tools for web (far better than any other ui builders imo). My biggest complaints if I had to say some would be the boa compile times are very slow and wish we could configure the GC more because the GC does mess with the frame times a bit. <div id="hotbar" src="textures/hotbar.png" style="justify-self: center; bottom: 10px;">
<item-grid id="items" item_box_size_px="34" columns="9" rows="1" margin="(1,0)" padding="(2,2)"
onclick="items_grid_click()"
style="left: 4px; top: 5px">
</item-grid>
</div>
<script>
// noinspection JSUnusedGlobalSymbols
function init() {
ui.set_stop_movement_on_click(InterfaceId.HotBar, "hotbar", false);
}
// noinspection JSUnusedGlobalSymbols
function always_tick() {
// This is used in very rare cases where we want to always tick the interface even when it is not visible.
// We do it here since if we hide hotbar when inventory is open, we need to be able to show it when inventory is closed
// (which we can't do if we're invisible unless we use this method).
let should_hide = inters.has_main_open();
ui.set_visible(InterfaceId.HotBar, "hotbar", !should_hide);
}
// noinspection JSUnusedGlobalSymbols
function tick(viewport_width, viewport_height, delta) {
// Now lets iterate our inventory and set the items (ideally we don't do this every tick)
for (let slot = 0; slot < 9; slot++) {
let inventory_item = player.get_inventory_item(slot);
if (inventory_item) {
ui.set_grid_item(InterfaceId.HotBar, "items", slot, inventory_item.id, inventory_item.amount);
} else {
// Sets to -1 (which sets to null) if item is null
ui.set_grid_item(InterfaceId.HotBar, "items", slot, -1, -1);
}
}
// Lastly lets mark our current slot as active
let hotbar_slot = vars.get_int(PlayerVariables.HotbarSlot);
ui.set_grid_highlight_slot(InterfaceId.HotBar, "items", hotbar_slot);
if (player.allow_player_input()) {
// Handle key presses
let key_slot = undefined;
if (ui.is_key_pressed(KeyCode.Key1)) {
key_slot = 0;
} else if (ui.is_key_pressed(KeyCode.Key2)) {
key_slot = 1;
} else if (ui.is_key_pressed(KeyCode.Key3)) {
key_slot = 2;
} else if (ui.is_key_pressed(KeyCode.Key4)) {
key_slot = 3;
} else if (ui.is_key_pressed(KeyCode.Key5)) {
key_slot = 4;
} else if (ui.is_key_pressed(KeyCode.Key6)) {
key_slot = 5;
} else if (ui.is_key_pressed(KeyCode.Key7)) {
key_slot = 6;
} else if (ui.is_key_pressed(KeyCode.Key8)) {
key_slot = 7;
} else if (ui.is_key_pressed(KeyCode.Key9)) {
key_slot = 8;
}
// If we pressed a key, set the hotbar slot to that key
if (key_slot !== undefined) {
// Set the hotbar slot to the one we pressed
vars.set_int(PlayerVariables.HotbarSlot, key_slot);
// Set the hotbar item id to the one we pressed
let inventory_item = player.get_inventory_item(key_slot);
let id = inventory_item ? inventory_item.id : 0;
player.set_hotbar_item_id(id);
// Send click packet to server
net.send_click(InterfaceId.HotBar, "items", key_slot);
}
}
}
// noinspection JSUnusedGlobalSymbols
function destroy() {
}
// noinspection JSUnusedGlobalSymbols
function items_grid_click(x, y) {
// Get the slot we clicked
let slot = ui.get_grid_slot_at(InterfaceId.HotBar, "items", x, y);
if (slot == null) {
return;
}
// Set the hotbar slot to the one we clicked
vars.set_int(PlayerVariables.HotbarSlot, slot);
// Set the hotbar item id to the one we clicked
let inventory_item = player.get_inventory_item(slot);
let id = inventory_item ? inventory_item.id : 0;
player.set_hotbar_item_id(id);
// Send click packet to server
net.send_click(InterfaceId.HotBar, "items", slot);
}
</script> |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Hello, I'm building a small game engine for myself - think something between Love2D and TIC-80 - and reviewed a few scripting languages. I'd love to use Boa because it would allow me to use TypeScript and easily distribute my games for the web. I made a small PoC that's doing fine, except that performances are very underwhelming.
I wrote small benchmark that spawns bouncing rectangles until I reach 50fps, and compared results between Boa, Rust, and TIC-80 (that uses Duktape as its JS engine):
Now it's not impossible that I made some obvious mistake while implementing Boa, but even then, a 10:1 difference against a similar project is surprising.
Are there long-term improvements planned for performances?
Beta Was this translation helpful? Give feedback.
All reactions