Questions About Using OneJS

Hello! I am considering using OneJS for the development of my game. However, I have some concerns: - If I implement not only the UI but also the game logic using OneJS, will there be any performance issues such as a drop in frame rate? - It is mentioned to "Do Everything in TypeScript," but is it compatible with deploying to consumer games like those on Nintendo Switch? - Is it possible to use CSS frameworks like React-Bootstrap? - Is it possible to automatically convert TS files to C# before starting the game and execute them without going through Jint to improve performance? I would appreciate your feedback on these points. Thank you.
14 Replies
Singtaa
Singtaa3mo ago
Hello!
If I implement not only the UI but also the game logic using OneJS, will there be any performance issues such as a drop in frame rate? Is it possible to automatically convert TS files to C# before starting the game and execute them without going through Jint to improve performance?
Performance is greatly improved in OneJS V2 which is in preview right now. It uses Puerts (which allows V8/QuickJS/NodeJS) instead of Jint. So performance-wise, it should be the best possible in this kind of environment.
It is mentioned to "Do Everything in TypeScript," but is it compatible with deploying to consumer games like those on Nintendo Switch?
OneJS isn't tested on the Switch. But I think OneJS V1 with Jint would probably work there as Jint is pure .Net. OneJS V2 using V8/QuickJS/NodeJS won't work on consoles. In general, I can only test OneJS on Windows, Mac, iOS, and Android. WebGL for OneJS V2 will be supported in the future.
Is it possible to use CSS frameworks like React-Bootstrap?
You would most likely need to make adjustment as UI Toolkit only provide a subset of CSS features. https://onejs.com/docs/limitations
はどはど/HADHAD
OneJS isn't tested on the Switch. But I think OneJS V1 with Jint would probably work there as Jint is pure .Net. OneJS V2 using V8/QuickJS/NodeJS won't work on consoles.
Personally, I would be happy if V2 could be used when deploying to the Switch as well... Is it possible to transpile the TS files to C# in advance and then, when deploying to specific environments like the Switch, have the prepared C# files executed without going through Jint?
Singtaa
Singtaa3mo ago
Is it possible to transpile the TS files to C# in advance
OneJS certainly can not do this. And, I don't think there's a reliable way of achieving this, definitely not in a general purpose way.
はどはど/HADHAD
Hmm... I see. In my game, I intended to write a large portion, including the game logic, in TypeScript while maintaining performance as much as possible. Given that V2 cannot fundamentally operate on consoles, does this mean that support for V2 on consumer games will not be considered in the future? Or, if there are any best practices for this, could you please share them?
Singtaa
Singtaa3mo ago
AFAIK, only Jint (a pure interpreter) can work on console environments. But if you intend to do game logic with it (update loop), you will most likely run into performance issues. There are a few custom solutions for embedding browser/js-engine on console such as https://ultralig.ht/ But their console versions will require custom license (and presumably much more expensive)
はどはど/HADHAD
What are other usage patterns, besides implementing in the Update Loop, that are likely to be affected in terms of performance when developing a game with V1?
Singtaa
Singtaa3mo ago
So you'd want to avoid frame-by-frame operations with Jint as the interop will generate GC.alloc (and you most likely wanna avoid doing that every frame). Another thing Jint is slow on is deeply nested recursive calls. Jint works well with retained-mode UI systems like UI Toolkit where everything is event-driven (no polling/update loop)
はどはど/HADHAD
I see, thank you. In that case, I will consider using V1 for my game development while trying to focus as much as possible on event-driven development, coroutines, and UniRX. However, will there be continuous updates for the version using Jint in future upgrades, or is there a plan to discontinue it?
Singtaa
Singtaa3mo ago
Yes V1 with Jint will be continuously updated until it possibly gets merged into V2. Jint has its own advantages over the native engines. Smallest build size, built-in support for operator overloading, available for all platforms, etc. That said, if you do require Nintendo Switch platform support, it's probably best to test Jint on there first.
はどはど/HADHAD
By the way, if Puerts becomes compatible with consoles, is there a possibility that it will be supported by OneJS as well?
Singtaa
Singtaa3mo ago
Yes, if they do end up with a solution, OneJS will do its best to support as well. Though I have to say, there is no public or open-source project that supports embedding native js engines on consoles currently (only a few proprietary ones). This also has to do with Consoles' strictness with script code execution in general.
はどはど/HADHAD
Even when writing the Update Loop in the following way, is it still difficult to mitigate the impact on performance?
using System;
using UnityEngine;

public class DynamicMono : MonoBehaviour
{
public Action UpdateAction;

void Update()
{
UpdateAction?.Invoke();
}
}

public class DynamicScriptAdder : MonoBehaviour
{
public void AddDynamicScript(GameObject target, Action updateAction)
{
DynamicMono dynamicScript = target.AddComponent<DynamicMono>();
dynamicScript.UpdateAction = updateAction;
}
}
using System;
using UnityEngine;

public class DynamicMono : MonoBehaviour
{
public Action UpdateAction;

void Update()
{
UpdateAction?.Invoke();
}
}

public class DynamicScriptAdder : MonoBehaviour
{
public void AddDynamicScript(GameObject target, Action updateAction)
{
DynamicMono dynamicScript = target.AddComponent<DynamicMono>();
dynamicScript.UpdateAction = updateAction;
}
}
import * as e from "UnityEngine";

const targetObject = require("TargetObject") as e.GameObject;
const globals = require("Globals") as e.GameObject;

const dsa = globals.GetComponent("DynamicScriptAdder") as any;
dsa.AddDynamicScript(targetObject, () => {
// ...
});
import * as e from "UnityEngine";

const targetObject = require("TargetObject") as e.GameObject;
const globals = require("Globals") as e.GameObject;

const dsa = globals.GetComponent("DynamicScriptAdder") as any;
dsa.AddDynamicScript(targetObject, () => {
// ...
});
Singtaa
Singtaa3mo ago
Everybody's target device and performance requirements are different. I think you should test your use case with Jint (it's open source and very easy to use in Unity). Your test code will be generating GC.alloc every frame, not just due to UpdateAction?.Invoke() but also because your JS closure will most likely call C#/UnityEngine stuff. This kind of interop stuff always generate garbage in Jint. Whether or not that's acceptable to you depends on your own requirements. Best thing to do is to profile Jint according to your test cases. IMO, since you are targeting Nintendo Switch and need to embed a JS engine, you should first verify if Jint will 100% work on your target device. Then profile and identify performance issues (preferably on-device). See if you can mitigate these perf issues by using event-driven approach instead of polling. (I have no experience developing for consoles, so take my opinion with a grain of salt)
はどはど/HADHAD
Thank you. For the time being, I have decided to conduct operational verification with the minimum environment of Jint and the minimum environment of V1 as soon as the development environment for Switch is obtained. This decision has raised new questions, so I plan to start a new thread as a separate topic.
Want results from more Discord servers?
Add your server