Skip to content

Releases: YetAnotherClown/YetAnotherNet

YetAnotherNet v0.10.0-alpha.2

29 Aug 17:20
Compare
Choose a tag to compare

Version 0.10.0-alpha.2

The changes in this version are important enough to receive an alpha version and its own release.

This version fixes three critical issues in YetAnotherNet, one preventing packets from being queried in some cases, and two others which caused unexpected frame delays due to flaws in the design of the scheduling code. In order to fix these issues, breaking changes have been make to the Hooks API and the Bridge API, a detailed migration guide can be found below.

It is important to note that the Hooks API should be stable, but the Bridge API may at any point change and should be considered unstable. The breaking changes made in this version were necessary in order to address a flaw in the API design.

Migration Guide

Hooks API

If you previously used the YetAnotherNet.createHook() function, it still behaves the same except it now returns two new functions instead of one: beginFrame and endFrame.

These functions will respectively call scheduling code that is meant for the beginning and end of a frame, instead of one function that would call it at the same time.

The following is an example of how to use the updated Hooks API:

local RunService = game:GetService("RunService")

local YetAnotherNet = require("@packages/YetAnotherNet")
local routes = require("@shared/routes")

local myRoute = routes.myRoute

local beginFrame, endFrame = YetAnotherNet.createHook({ Route })
RunService.Heartbeat:Connect(function()
	beginFrame()

	myRoute:send(...)
	for i, player, data in myRoute:query() do
		-- Do something
	end

	endFrame()
end)

Note

The behavior of YetAnotherNet.start() has changed, the API itself has not. This function will now run the respective scheduling code at the beginning AND the end of a frame instead of just at the end of a frame.

Bridge API

The Bridge:step() method has been removed and replaced with new Bridge:beginFrame() and Bridge:endFrame() methods which will run the respective scheduling code at the beginning AND the end of a frame instead of just at the end of a frame.

Warning

The Bridge API is unstable and may change in future versions, it is not guaranteed that any of the API for the Bridge will remain constant.


Installing the New Version

Wally

Add YetAnotherNet to your project with Wally by adding the following to your wally.toml file:

[dependencies]
YetAnotherNet = "yetanotherclown/yetanothernet@0.10.0-alpha.2"

Note

Wally does not export types automatically, if you wish to use Strict Typing with YetAnotherNet, install Wally Package Types with Foreman.

NPM for Roblox Typescript

You can find YetAnotherNet on NPM, or install it with the command line:

npm i @rbxts/yetanothernet@0.10.0-alpha.2

Change Log

Tip

See the CHANGELOG.md for future and past changes.

Changed

  • Bridge:step() has been replaced by Bridge:beginFrame and Bridge:endFrame which separates the logic behind the Incoming and Outgoing queues
  • YetAnotherNet.createHook() now returns two functions, a beginFrame and a endFrame function which separates scheduling logic

Fixed

  • A critical bug that resulted in the unexpected termination of query iterators

YetAnotherNet v0.9.0

11 Jul 12:12
Compare
Choose a tag to compare

Version 0.9.0

This version brings drastic improvements to the maintainer/contributor experience, with String (alias/path) Requires, Darklua, New & Updated Shell Scripts, GitHub Actions, and a all new CONTRIBUTING.md to act as a guide for contributors.

Speaking of contributing, we also have some new open issues which would serve as good first issues for anyone looking to contribute.

This version also have bug and performance fixes for the library, most notably with the serdes library with fixes to Instance serialization and massive improvements to performance.

What's Next?

There are only two remaining features left for YetAnotherNet before moving into the pre-release phase for version 1.0.0. The next task on my agenda is to work on a Debugger which will show useful networking information as well as other information that could prove useful when working with YetAnotherNet.

Besides that, it'll mostly be improvements to documentation, type fixes, bug fixes, and other non-critical changes.


Installing the New Version

Wally

Add YetAnotherNet to your project with Wally by adding the following to your wally.toml file:

[dependencies]
YetAnotherNet = "yetanotherclown/yetanothernet@0.9.0"

Note

Wally does not export types automatically, if you wish to use Strict Typing with YetAnotherNet, install Wally Package Types with Foreman.

NPM for Roblox Typescript

You can find YetAnotherNet on NPM, or install it with the command line:

npm i @rbxts/yetanothernet@0.9.0

Change Log

Tip

See the CHANGELOG.md for future and past changes.

Added

  • Documentation for using Squash 2.0.0
  • Setup Darklua and rules
  • Add .vscode settings for luau-lsp
  • Add Lint script
  • Add GitHub CI Workflow
  • Mention roblox-project-template in README.md
  • Add release scripts for Wally and NPM
  • Added a CONTRIBUTING.md guide

Changed

  • All files have been migrated to .luau and GitHub Linguist to Luau
  • Updated note on Ratelimiting in Documentation
  • SendRequest:to() no longer calls RunService:IsClient() and RunService:IsRunning() every invocation
  • BrickColor, EnumItem, and boolean serde is now cached
  • Changed order and added issue links to the Setup section in Documentation
  • Renamed shell scripts
  • Switched to String (alias/path) Requires
  • Update Stylua configuration and apply changes
  • Set exclusions in selene.toml
  • Exclude docs in tsconfig.json
  • Changed what is included in Wally and NPM package releases
  • Luau types for Middleware are no longer strict due to inaccuracy of the type system
  • Typescript types for Middleware have been improved to allow for more use cases

Fixed

  • Instance Changes when sent over the network would turn into a Mixed Table, resulting in incorrect Instances being deserialized
  • ./examples directly was named incorrectly as ./example which resulted in broken links
  • Documentation for Configuration now specifies what is optional
  • Links to BridgeNet2 were outdated and resulted in 404 pages
  • getSerDes function is no longer a bottleneck for serialization and now runs roughly 2x more efficiently
  • EnumItem serde no longer iterates through all Enums and EnumItems, resulting in it running roughly 4.5x more efficiently
  • deserializeBuffer function did not utilize Native Code Generation
  • Fixed a type error with incoming middleware in internal code

New Contributors

YetAnotherNet v0.8.0

03 May 01:29
Compare
Choose a tag to compare

Effortless Buffer Compression

One of the key focuses for this version is the addition of Buffer Support and an internal Ser/Des library which will automatically compress the data sent into Buffers with minimal to no work required by the developer.

The library will now pack the data and compress it into a format that will be compressed even further by Roblox when sent over the network. The only limitation is that it doesn't work for all datatypes, the most common datatypes are supported already, so be sure to avoid any Unsupported Datatypes when using the library to ensure you get the most out of the compression.

Stability for the Public API

With this version, the core-functionality under the Net Namespace consisting of Route, createHook, and start will be considered complete. I am satisfied with the current state of the API and I am ready to commit to stability and backwards compatibility.

The new Unit Tests should remain the same for the Public API, requiring little to no changes, but more extensive tests will be added with time to ensure stability.

Unit Testing with Jest Lua

The Focus for v0.8.0

A focus of this version is on stability. This includes both API Stability as mentioned in the last section, and ensuring that the library is stable in production. To achieve this, my goal is to extensively test all parts of the library and any edge cases where it could fail.

The current tests will serve as a base to work off of and to ensure general functionality during development. I will be working on more tests with time and when I add new features or make changes to the library.

I encourage anyone willing to contribute to point out any errors with the library, or to suggest/write new tests that could improve on what we have. Create an Issue or PR to submit an idea for a test and do not be afraid to reach out to discuss it.

Why Jest?

It has been a goal to provide unit tests for the library, this was shown in v0.2.0 when I had a branch to implement Unit Tests using TestEZ.
Needless to say this branch was never merged into main, and it was eventually deleted in favor for the new tests using Jest Lua.

When I first used TestEZ, it wasn't that nice of an experience, so when I tried Jest Lua, I was pleasantly surprised by how nice the developer experience was and what I could achieve with it. There were lots of nice new features and great additions to developer experience such as Mocking, Strict Typing, and Auto-completion right out of the box.

I've used the Mocking feature to tackle some of the issues I had while trying to write unit tests with TestEZ, which has allowed me to mock the use of RemoteEvents to allow some simple and robust unit tests.

I look forward to continuing the use of Jest Lua with YetAnotherNet and in my other projects and games.


Installing the New Version

Wally

Add YetAnotherNet to your project with Wally by adding the following to your wally.toml file:

[dependencies]
Net = "yetanotherclown/yetanothernet@0.8.0"

Note

Wally does not export types automatically, if you wish to use Strict Typing with YetAnotherNet, install Wally Package Types with Foreman.

NPM for Roblox Typescript

You can find YetAnotherNet on NPM, or install it with the command line:

npm i @rbxts/yetanothernet@0.8.0

Change Log

Tip

See the new CHANGELOG.md for future and past changes.

Added

  • Unit tests with Jest
    • For Identifier
    • For SendRequest
    • For QueryResult
    • For Route
    • For Bridge
  • Bridge, Route, Player, and RemoteEvent Mocking
  • Script for Installing Wally and Exporting Wally Types
  • Script for running Jest tests using run-in-roblox
  • Warning for attempting to send an invalid string as a recipient
  • An Internal Ser/Des Library
  • Automatic Compression for the Bridge
  • Documentation for the Bridge

Changed

  • Updated Rojo to v7.4.0
  • Updated Jest-Lua to v0.6.1-rc.2
  • Migrate from Aftman to Foreman
  • SendRequest:to() no longer returns if called on the Client
  • Refactored Bridge to better allow for unit tests
  • Reduced the average call time of Route:send() by 50-60%
  • Documentation no longer references Compression with Middleware
  • Rewrote the Bridge to support Buffers
  • Refactored the Bridge to better support Mocking
  • Identifiers are now represented as Buffers instead of packed strings
  • Bridge:snapshot() now returns a frozen table instead of a cloned table

Fixed

  • QueryResult does not filter senders
  • Incorrect types for Incoming Middleware
  • Incorrect and inconsistent Roblox-TS Types
  • Default Channel is never applied when no configuration parameter was supplied
  • Outdated use of Net.start in Documentation
  • SendRequest:to() will show a client warning when using run-in-roblox
  • Incorrect Unit Test for Outgoing Middleware

Net v0.7.0

03 Jan 01:26
Compare
Choose a tag to compare

Net v0.7.0

Roblox Typescript

Net v0.7.0 brings official Typescript Support for Net, with Type Definitions and Documentation in both Luau and Typescript.

You can install Net on NPM like so,

"@rbxts/yetanothernet": "0.7.0-beta.3"

Or checkout the Package on NPM here.
And if you find any issues with the Type Definitions for Net, please be sure to file an issue.

Breaking API Changes

The Net Namespace

The Library's main module now returns a Namespace instead of an Object, in this namespace you can find the all the Public API in this Namespace now. You can access Net.Route, Net.createHook() and Net.start() through this namespace.

Updates to Middleware

Middleware is no longer added through the Route's configuration, you can now use Route:addIncomingMiddleware() and Route:addOutgoingMiddleware() which are now both fully type-checked to ensure you're using Middleware correctly.

You can see the new documentation here.

Other Changes

  • Refactored internals
  • Improved implementation of a default channel

Fixed

  • Channel Validation fails when Channel is Unreliable
  • QueryResult returns the incorrect position

Net v0.6.0

14 Dec 17:31
Compare
Choose a tag to compare

Net v0.6.0

Net v0.6.0 is here with a new powerful feature called Middleware, and new and improved Documentation.

Updated Documentation

The Documentation for Net has been fully overhauled, with an exception of the API docs. This overhaul contains new and more detailed guides as well as a new homepage.

You can checkout the documentation here.

Middleware

Middleware allows you to validate types and serialize/deserialize data before it is processed when sending and receiving data.

To create Middleware, you can specify a function in your Route's Configuration with a parameter for the event "send" | "receive" and the data that is to be processed U....

local Net = require("Net.luau")
type Net<U...> = Net.Net<U...>

local Route: Net<number, string, boolean> = Net.new({
    Middleware = function(event, num, str, bool)
        -- Do something

        return num, str, bool
    end
})

To validate your types, you can return the values in order to allow it to be processed, or you can drop the packet by returning nil. Dropped packets will never reach your code, meaning you can ensure that the types your code receives are always the types you expect.

You can also serialize/deserialize data in Middleware, to see a full example read Getting Started with Middleware

Fixed

  • Incoming packets do not respect their channel

Net v0.5.0

01 Dec 00:01
Compare
Choose a tag to compare

Net v0.5.0

Net v0.5.0 is here with some big changes and improvements. This version introduces a new concept called Routes, adds complete Strict-typing and Auto-completion to the library, and introduces some new features.

Routes

Routes completely replace Identifiers, which are now internally handled by Net. You can create a Route the same way you used to create your single Net object, except this time you're encouraged to create as many as you need instead of one. The concept of Identifiers are completely abstracted away and all you need to do is create Routes for name-spacing.

Routes can be Reliable or Unreliable. Reliable events are never dropped and are always in order per frame. Unreliable events might be dropped on bad connections, but they are always received in order per frame.

You can also strictly type Routes to get auto-completion and type-checking when Sending and Querying packets.

local Net = require("Net.luau")
type Net<U...> = Net.Net<U...>

local PlayerLoaded: Net<boolean> = Net.new({
    Channel = "Reliable"
})

In this example, we create a new Route that will send a boolean over the Reliable Channel. It's identical to how you would create a Net object in previous versions, it is however encouraged to store them in an routes.luau Module like how you would with Identifiers.

You will need to migrate your existing Net code to use Routes. The Introduction to Net is fully updated, it's a great resource to learn how to use Routes.

Strict-typing + Auto-completion

This version was made with the goal to introduce full Strict-typing and Auto-completion into Net for a better developer experience.

You can Strictly type and get full Auto-completion for your Routes by adding a type annotation to it when creating it. The type can be any number of any types that you want and it will work for type-checking and auto-completion.

For example,

local Net = require("Net.luau")
type Net<U...> = Net.Net<U...>

local defaultConfiguration = {
  Channel = "Reliable",
  Event = "default",
}

-- Payload for replicating Entities
type EntityPayload = {
    [string]: { -- EntityId
        [string]: { -- Component name
            data: ComponentInstance<T>
        }
    }
}

-- Replicate Matter Components
local MatterReplication: Net<EntityPayload> = Net.new(defaultConfiguration)

-- Signal that the Player has loaded
local PlayerLoaded: Net<boolean> = Net.new(defaultConfiguration)

return {
  MatterReplication = MatterReplication,
  PlayerLoaded = PlayerLoaded,
}

In this example, we create two Routes that are strictly typed. In our first one, we annotate it with the EntityPayload type which will type-check our MatterReplication Route when we send Matter Entities and Components over our Net. In the second one, we provide a boolean to signal when the Player has loaded to the server.

You're not limited on what you can annotate here, you can specify multiple types like Net<number, boolean, string, any> and it will work.

Type-checking and Auto-completion work when using Route:send() or Route:query() in the arguments and returned values. Type-checking will not work during runtime, you'll have to do your own checks in your code to ensure the correct type of data was sent over the Net, we are working on a feature to allow you to do this easily in the future called Middle-ware.

Unreliable Routes

This release also contains support for the all new UnreliableRemoteEvents. These new UnreliableRemoteEvents allow for you to send unreliable data across Net, for more information see the DevForum Post.

You can create an Unreliable Route using the Configuration,

local Net = require("Net.luau")
type Net<U...> = Net.Net<U...>

local ExampleRoute: Net<any> = Net.new({
    Channel = "Unreliable"
})

Hooks

Net had always provided a utility function for integrating itself into your Matter ECS, Net:start(). While this was helpful to some, Net lacked proper support for other code structures. While there was the ability to use net._bridge:step() it was only a workaround for proper support.

Introducing.... Hooks! Hooks are a new way to integrate your Routes' scheduling into your code. These hooks will allow you to properly run scheduling on any event, making it accessible and versatile to any setup you may have. Hooks are simply functions, a function which you can call in accordance to any event.

To make a hook, you can use the new Net.createHook({ Route }) function and passing in a table of your Routes, after you call this function it will return another function that you can use anywhere to step your Routes' scheduling.

local RunService = game:GetService("RunService")

local Net = require("Net.luau")
local routes = require("routes.luau")

local hook = Net.createHook(routes)
RunService.Heartbeat:Connect(hook)

In addition to this, the net:start(loop) method has been replaced with a similar Net.start(loop, { Route } function that internally behaves similarly to the Net.createHook({ Route }) function, except it does not return a function because that's all handled for you!

Net v0.4.0

27 Nov 09:08
Compare
Choose a tag to compare

Net v0.4.0

API Changes

  • Rewrote Net:query() to use the new QueryResult type
  • Rewrote Net:send() to use the new SendRequest type

You will need to migrate your existing Net code to use the new behavior of this API. The Documentation for Querying and Sending data on the Docs Site is fully updated, that would be a good place to reference how to use the new behavior.

QueryResult and SendRequest offer a better user experience and allow for better type-checking, they are also less prone to bugs compared to their counterparts.

Changed

  • Exported and internal types are now more strict and are just generally improved

A complete revamp of the types has been done. For Object-Oriented Objects in Net, the new types follow the standard from Luau for implementing types for faux object oriented programs.

Fixed

  • Priority artifacts in documentation
  • Matter example game has outdated paths
  • Matter example game Replication & Formatting (#3)
  • Rojo deletes Remotes when live-syncing (#4)

New Contributors

  • @ATK422 made their first contribution in #3

Net v0.3.0

20 Sep 10:50
Compare
Choose a tag to compare

Net v0.3.0

Added

  • Matter Example Game AttackOfTheKillerRoombas, adapted from the official Matter Example Game.

API Changes

  • Removed the ReliableOrdered and ReliableUnordered Channels in favor for the new Reliable Channel. ReliableUnordered already sent and received packets in order, rendering ReliableOrdered useless and wasteful.

Current State

With the release of v0.3.0, Net should now have a relatively stable API. Most of the API is now Unit Tested and I've been using Net personally in some of my other projects for a while now.

With stability no longer being an issue for Net, I'll be working towards adding the remainder of the features on the To-Do List such as Ratelimits, Middleware, and the Debugger. I will also be working to improve the Documentation and the overall on-boarding experience for Net.

Unit Testing

The Unit Tests for Net are almost complete, the progress on them are shown below, all bugs found while writing these tests have been merged into the main branch.

  • Initial Setup
  • Player & Remote Mocking
  • Test Scheduling
  • Public API Tests
  • Internal Tests

Since v0.2.0

Added

  • Matter Example Game AttackOfTheKillerRoombas, adapted from the official Matter Example Game.

Changed

  • Net:start() now utilizes middleware in Matter to schedule networking code.
  • Internal Naming of Functions for support for Roblox Debugging tools such as ScriptProfiler.
  • Updated the Getting Started page in Documentation to highlight the need to setup on both the Server and Client with the same configuration.

Fixed

  • Minor issues in the Documentation.
  • The iterator always defaulting to sending all packet information regardless if an returnFilter was provided.
  • Net:query() returning the Sender on Clients despite the Sender always being known on the Client as Net.Server.
  • The internal filter of Net:query() never returning the Sender when type { Player } is provided as a QueryParam and only one Player has sent packets.
  • The internal filter of Net:query() filtering out Server Packets on the Client.
  • The internal QueryParams Parser mistaking the Net.Server Recipient as an Identifier.
  • The typecheck in Bridge when processing the outgoing queue always fails when the recipient is of type Player.
  • Middleware in the start method runs only once every two frames
  • Iterator filter fails to properly filter key-value pairs by @IntegralsGetYouArea in #1
  • Iterator filter should also take a key with it's value
  • Identifiers always have the same position when the pos parameter is not given
  • Query never filters Players, typecheck would always fail because typeof(Player) returns Instance
  • Query filtering all Players on the server when no Player was given in the QueryParams

New Contributors

Net v0.2.5

12 Sep 23:23
Compare
Choose a tag to compare

Changelog

Fixed

  • Query never filters Players, typecheck would always fail because typeof(Player) returns Instance
  • Query filtering all Players on the server when no Player was given in the QueryParams

Net v0.2.4

28 Aug 23:44
Compare
Choose a tag to compare

Changelog

Fixed

  • Middleware in the start method runs only once every two frames
  • Iterator filter fails to properly filter key-value pairs by @IntegralsGetYouArea in #1
  • Iterator filter should also take a key with it's value
  • Identifiers always have the same position when the pos parameter is not given

New Contributors