Ynet.dev
This is a framework for HTML5 network apps; especially games and graphics applications.
Ynet internally handles dynamic loading of code modules (aka. JavaScript streaming), which also allows live code updates (aka. runtime code injection), speculative module fetching and seamless resuming after re-connection (without reloading any code, aka. lazy execution). Some syntactic sugar is also included (see below).
Ynet handles website elements (similar to jQuery), plays music and sound effects (including pitch variations), supports easy authentication (by password, FIDO2 token, e-mail code, or by device), provides math functions (like geometry functions, curves, vectors and matrix operations), accepts all input methods (keyboard, mouse, touch, gamepad) offers a wide range of helper classes (such as various buffers/heaps, mathematical curves/slopes/splines, HTML drag & drop, image utils, path finding, color converters and even a QR scanner and generator) and peaks in full 2D/Canvas and 3D/WebGL shader rendering (covering pixels, sprites, polygons and voxels).
Topics
Screenshots
Here are some random screenshots from various projects:
JS syntactic sugar
The delay( ms ) structure is a shortcut for setTimeout() calls:
delay(
The benchmark( num ) structure is a shortcut to bench(); for( num ) { ... } mark();
benchmark(
After 1000 iterations, the execution duration in ms will be printed to the Ynet console.
Ynet supports multi-line strings in code:
var list = "/*
Easily check arguments for their data type and range:
function printText( id, name, message, opacity )
{
///
In this example id can be any positive integer, name must be a string of exactly 16 lowercase letters, message is a UTF8 string up to 2000 characters length and opacity can be any number from 0 to 100. Failing a test throws an error, providing name, data type, value and expected range of the argument.
Quickly print out debug information:
function start()
{
//>
The text Now starting will be printed to the console.
Iterating through array values:
var list = [ "The", "answer", "is", "42" ];
for( list
Prints: The answer is 42
Iterating through array indices and values / also works on Map and map-like objects:
var list = [ "Ynet", ".", "dev" ];
for( list as
Prints: 0 = Ynet 1 = . 2 = dev
HTML elements
Easily create HTML interfaces:
html( "/*
There are multiple ways to define the id, class and content (eg. p#intro and p id="intro" is equivalent). Some special attributes (such as assign) will be recognized and assigned to the corresponding Ynet UI events. The final append() call adds this structure to the body.
Other namespaces (ie. svg and ynet) can be accessed through the colon sign.
The following code creates a SVG line element:
html( "
The ynet namespace simplifies the creation of everyday complex HTML elements.
html( "
This creates your typical "on/off" switch button with a sliding bullet.
Similar to the knob switch, radio buttons can be assembled as follows:
html( "
Interacting with the radio buttons will trigger the selectAction event to handle this.value().
CSS syntactic sugar
body { color:#000; }
CSS only allows /* block comments */ but Ynet fixes this stupid decision.
div {
Allow scrolling in x, y or xy direction. Translates to a overflow and touch-action setup.
if(
Included if the screen width is less than 200 px.
if(
Included if the screen height is at least 10 em.
if(
Included if the screen is in landscape mode (width > height).
if(
Included if the screen is in portrait mode (height > width).
if(
Included if the primary input is the mouse cursor.
if(
Included if the primary input is the touch screen.
button
Ynet automatically applies :hover styles only for mouse cursors.
button
The custom :ui selector applies to both, :focus and :hover. This allows easily setting up the same styles for mouse and keyboard interaction.
CSS variables made simple.
Ynet modules
client | Ynet core (client only). | 54 KB |
core | Ynet core (server and client). | 125 KB |
html | HTML creation and manipulation. | 64 KB |
image | Image drawing (creation, manipulation, color effects). | 22 KB |
login | Account manager (FIDO2, password, e-mail, device). | 6 KB |
map | Multi-functional map class for 2D games. | 24 KB |
math | Math functions and utils (randomize, vector, matrix). | 45 KB |
webgl | WebGL 1+2 rendering (shaders, textures, polygons, voxels). | 138 KB |
+ | Everything else (audio, buffers, color, database, drawing, hashing, inputs, interpolation, resources, etc.) | 108 KB |
Example: Basic chat
The following code is a complete example running a simple console-based chat. Users can enter a name, get a list of all connected users, get notified when someone joins or leaves, and can broadcast plain text messages.
Note that the print event is built-in and text coloring is done through color tags (eg. <lr> means light red). The application is started by running node main.js on the server.
main.js
// Ynet starter
require( "../core.js" ).start({ port:8000 });
chat.js
// Chat module
// Create the server/client/both scopes ($s, $c, $b)
core.createScopes( exports );
$s.module.init()
{
// Setup webserver
core.serve( "/", "client.html" );
core.serve( "/ynet.js", "client.js" );
// Start listener
core.listen( core.port );
}
$s.core.onConnection( con )
{
// Send the client module (this file)
con.transmit( "chat" );
// Now wait for the username
con.username = null;
}
$c.module.create( initial )
{
// Client ready
if( initial )
{
print( "<w>Welcome to the chat!" );
print( "<w>Enter your username first:" );
}
}
$c.core.onConsoleInput( data )
{
// Send input to server
if( data.length > 0 ) core.send( "input", data );
}
$s.events.input( data )
{
// Check username present
if( !this.username )
{
// Sanitize input
var name = data.replace( /[^a-zA-Z0-9_-]/g, "" );
if( name.length < 1 ) return;
// Set client username
this.username = name;
// Login notification
for( core.connections as con )
{
con.send( "print", "<lg>Joined: " + name );
}
// Collect user names
var list = []; for( core.connections as con )
{
if( con.username ) list.push( con.username );
}
// Send user list
return this.send( "print", "<lb>Users: " + list.join( ", " ) );
}
// Sanitize input
data = data.trim().hss(); if( data.length < 1 ) return;
// Colorize name and message
var name = this.username;
var text = "<y>" +name+ ": <e>" +data;
// Broadcast message
for( core.connections as con )
{
if( con.username != name ) con.send( "print", text );
}
}
$s.core.onDisconnect( con )
{
// Connection lost
var name = con.username; if( !name ) return;
// Notify others
for( core.connections as con )
{
con.send( "print", "<lr>Left: " + name );
}
}
Download
Not (yet) available to the public, sorry. This is a private project.
History
Ynet is the HTML5-based successor of the YDK framework, which was created around 2005 as a Visual Basic 6.0 convenience API. Large parts of the original YDK were DirectX wrappers, so one could easily render graphics (shapes, 2D images and later even 3D models), play sounds (variing pitch and volume), setup music (fading and looping automatically), handle input devices (including rumble effects) and many things more (networking, path finding, data encryption, scripting, etc.).
Unfortunately Microsoft decided to discontinue the DirectX extension for VB6 (the last version was DirectX 8.1) and even VB6 itself, in order to push their dotNet framework. After some roaming through the realms of early HTML5 (before WebGL was available), Java and even Flash, the final decision was to use HTML5 and a node.js server respectively. Finally, in the summer of 2020, the Ynet.dev project was born and here we are.
The lesson of this journey is to stick with standards, not companies.
Although I'm very disappointed that WebGL will be discontinued in favour of the upcoming WebGPU. I was strongly hoping to see geometry shaders in WebGL one day...