Skip to content

Releases: cuhHub/Noir

Noir 1.14.0

21 Oct 09:45
Compare
Choose a tag to compare

📚 Details

Version: 1.14.0

❔ Installation

Check out the documentation for information on how to install and use Noir in your addon.

💬 Description

A decently large update update, woohoo.

Additions

  • Added OnSit and OnUnsit events to the PlayerService.

  • The project manager tool now adds example services and libraries.

  • Added an OnBodyDamage event to the VehicleService. An OnDamage event has been added to the NoirBody class too. As the name suggests, this event is fired when the body takes damage.

  • Added :SpawnExplosion() method to the ObjectService. This method doesn't return an object, just purely spawns an explosion.

  • RecognizedIDs in PlayerService's g_savedata table is now cleared when players are loaded to prevent g_savedata build-up.

  • Added a task types system to the TaskService. This allows you to create tasks that trigger differently. For example, time tasks are triggered by server.getTimeMillisec(), while tick tasks are triggered by total ticks. This additions comes with new methods: :SecondsToTicks(), :TicksToSeconds(), :AddTimeTask() and :AddTickTask(). Unfortunately, this addition deprecates :AddTask() which will be removed in a future update, please use :AddTimeTask() instead.

    Rule of thumb: For precision, use :AddTickTask(). For time accuracy, use :AddTimeTask().

    It is also important you use the new DeltaTicks attribute of TaskService in calculations in tasks being ran in a task that uses ticks to account for time speeding up (eg: when all players sleep).

local last = Noir.Services.TaskService:GetTimeSeconds()
local time = 0

Noir.Services.TaskService:AddTickTask(function()
    local now = Noir.Services.TaskService:GetTimeSeconds()
    time = time + ((now - last) * Noir.Services.TaskService.DeltaTicks)
    last = now

    print(("%.1f seconds passed"):format(time))
end, 1, nil, true) -- This task is repeating every tick
  • Added Deprecation, a new built-in library. This library allows you to mark functions as deprecated.
---@deprecated <-- for intellisense. recommended to add
function HelloWorld()
    Noir.Libraries.Deprecation:Deprecated("HelloWorld", "AnOptionalReplacementFunction", "An optional note appended to the deprecation message")
    print("Hello World")
end

HelloWorld()
-- [Noir] [Warning] [Deprecated] 'HelloWorld' is deprecated. Please use 'AnOptionalReplacementFunction' instead.
-- [Noir] [Warning] [Deprecated] An optional note appended to the deprecation message
  • Added RawTPS to TPSService. This is simply the TPS divided by the amount of ticks per onTick call.

Changes

  • Notification methods in NotificationService now accept nil for the player parameter
  • The project manager tool now places main.lua into a src folder
  • Players, objects, etc, are now loaded before Noir.Started is fired. This means you can now fetch something like the host player directly in Noir.Started instead of having to wait a tick or wait for an event like PlayerService's OnJoin event.
  • Event argument descriptions are now consistent across Noir. Example: Arguments: player (NoirPlayer), vehicle (NoirVehicle)
  • IDs in classes like NoirPlayer and NoirObject are now converted to integers since g_savedata turns integers into floats.
  • Noir.Libraries.JSON:Decode() no longer errors if the string to decode is invalid JSON. This change was made because HTTP request responses, a commonly JSON-decoded thing, are unpredictable and can sometimes not be JSON-decoded due to invalid JSON, etc. Especially with the lack of a pcall function in SW Lua for error handling, the errors just weren't needed.

Fixes

  • Fixed NoirMessage serialization regarding the recipient.

Removals

  • Removed unnecessary duplicate :_LoadSavedMessages() call in MessageService that may have caused issues.

Noir 1.13.1

17 Aug 14:59
Compare
Choose a tag to compare

📚 Details

Version: 1.13.1

❔ Installation

Check out the documentation for information on how to install and use Noir in your addon.

💬 Description

Quick hotfix for the project manager tool.

Fixes

  • Fixed error during project creation.
  • Fixed combiner tool being placed into a .py file instead of a .exe file.
  • Fixed invalid combiner tool destination created by the project manager.

Noir 1.13.0

17 Aug 14:45
Compare
Choose a tag to compare

📚 Details

Version: 1.13.0

❔ Installation

Check out the documentation for information on how to install and use Noir in your addon.

💬 Description

This update comes with more services, notably the VehicleService. All of these services internally persist across reloads so you don't need to worry about saving vehicles, etc.

Additions

  • Added a new VehicleService. Along with this, two new classes have been added: NoirBody and NoirVehicle.
    • NoirVehicle represents a Stormworks vehicle group, while NoirBody represents a vehicle in a vehicle group.
    • Vehicle data persists in the service across reloads and world exits. The service handles all the hard bits for you. :-)
---@param body NoirBody
Noir.Services.VehicleService.OnBodyLoad:Connect(function(body)
    -- Set tooltip
    body:SetTooltip("#"..body.ID)
    
    -- Empty all tanks
    local tanks = body:GetComponents().components.tanks

    for _, tank in pairs(tanks) do
        body:SetTankByVoxel(tank.pos.x, tank.pos.y, tank.pos.z, 0, tank.fluid_type)
    end

    -- Send notification when the vehicle body despawns
    body.OnDespawn:Once(function()
        Noir.Services.NotificationService:Error("Body Despawned", "A vehicle body belonging to you despawned!", body.Owner)
    end)
end)
  • Added a new service, MessageService. This service keeps tracks of messages sent by your addon or players. Messages persist across reloads and world exits.
---@param message NoirMessage
Noir.Services.MessageService.OnMessage:Connect(function(message)
    Noir.Libraries.Logging:Info("Message", "(%s) > %s (%s)", message.Title, message.Content, message.IsAddon and "Sent by addon" or "Sent by player")
end)

Noir.Services.MessageService:SendMessage(nil, "[Server]", "Hello world!")
  • Added Noir.Libraries.Events.DismissAction. Returning this in a callback to an event will disconnect the callback from the event. Thanks to Avril112113 for the suggestion!
local MyEvent = Noir.Libraries.Events:Create()

MyEvent:Connect(function()
    print("Fired")
    return Noir.Libraries.Events.DismissAction
end)

MyEvent:Fire()
-- "Fired"
MyEvent:Fire()
-- N/A
  • Added :IterateOverTicks() to TaskService. This method allows you to iterate through a table in chunks of x over how ever many needed.
local tbl = {}

for value = 1, 100 do
    table.insert(tbl, value)
end

Noir.Services.TaskService:IterateOverTicks(tbl, 10, function(value, currentTick, completed) -- iterate over the table in chunks of 10
    print(("%s @ tick %d"):format(value, currentTick))

    if completed then
        print("Completed!")
    end
end)
  • Added :GetTasks() to TaskService. This returns all active tasks in the TaskService.
  • Added :GetAITarget() to the NoirObject class. This returns a NoirAITarget class object containing the vehicle, character, and/or position the character AI is targeting.
  • Added :SetAIPositionTarget() to the NoirObject class.
  • Added :StartsWith() and :EndsWith() to the built-in string library.
  • Added :GetPlayerByCharacter() to the PlayerService. This allows you to retrieve a player by their character (duh).
  • Added a new project manager tool for easily creating addons with Noir. See the documentation for more info.

Fixes

  • Fixed "Invalid key to 'next'" error with nested tasks in TaskService.

Changes

  • API reference automation now updates SUMMARY.md meaning the API reference docs will actually be shown. Doubles as a fix.
  • Renamed all libraries to [LibraryName]Library, eg: NoirHTTP --> HTTPLibrary

Removals

  • Removed Noir.Services.ObjectClass:SetAIVehicleTarget(). It has been replaced by :SetAIBodyTarget() instead.

Noir 1.12.0

11 Aug 01:03
Compare
Choose a tag to compare

📚 Details

Version: 1.12.0

❔ Installation

Check out the documentation for information on how to install and use Noir in your addon.

💬 Description

More features!! 🥳

Additions

  • Added an :EnsuredLoad() method to the NoirService class. This method is similar to NoirService:Load(), but if the value retrieved doesn't exist, the default value passed to the method is saved and then returned.
-- Instead of:
function Service:ServiceInit()
    local value = self:Load("MyValue", 0)
    self:Save("MyValue", value)
end

-- You can do:
function Service:ServiceInit()
    local value = self:EnsuredLoad("MyValue", 0)

    -- And to show the value is 100% saved:
    value = self:Load("MyValue")
    print(value) -- 0
end
  • Added a new service, HTTPService. As the name suggests, this service allows you to send HTTP requests the Noir way. 😎
Noir.Services.HTTPService:GET("/items/5", 8000, function(response)
    if not response:IsOk() then
        return
    end

    local item = response:JSON()
    Noir.Libraries.Logging:Info("Item", item.Name)
end)
  • The API reference in the documentation is now fully automated. This means the API reference will get updated at the exact same time as new releases.

Fixes

  • Fixed the :Warning() method of the built-in NotificationService sending a notification that would more fit an error notification (way too red). The new color now fits a warning color.

Changes

  • The combiner tool has been completely remade. The CLI arguments remain the same, so updating should no longer be a biggie. Code matches the standard of Noir's code.
  • Services are now initialized and started before Noir.Started is fire. Previously, services were only initialized before Noir.Started being fired then started after.
    • ⚠️ | This may affect some people who aren't making services correctly. Please ensure that anything that needs to be accessed by the addon is set up in :ServiceInit(). Things like game event connections or actual service logic can be placed in :ServiceStart().
  • Changed _LastTimeSec to _Last in the built-in TPSService.

Removals

  • Removed a log message that was displayed when a g_savedata table for a service was missing. This always happens when an addon using Noir is loaded for the first time hence the log message removal.

Noir 1.11.0

06 Aug 13:33
Compare
Choose a tag to compare

📚 Details

Version: 1.11.0

❔ Installation

Check out the documentation for information on how to install and use Noir in your addon.

💬 Description

A bunch of things have been added in this release. All of these additions should not impact your addon whatsoever if you was to update Noir.

Additions

  • Added a new library called Dataclasses. This library allows you to easily create classes that represent things but don't need any methods and such. This is inspired by Python's built-in dataclasses module.
local InventoryItem = Noir.Libraries.Dataclasses:New("InventoryItem", {
    Noir.Libraries.Dataclasses:Field("Name", "String"),
    Noir.Libraries.Dataclasses:Field("Weight", "Number"),
    Noir.Libraries.Dataclasses:Field("Stackable", "Boolean")
})

local item = InventoryItem:New("Sword", 5, true)
print(item.Name, item.Weight, item.Stackable)
  • Added a :Remove() method to the NoirTask class. This method simply removes the task from the built-in Task Service if the task is registered.
  • Added Noir.Libraries.Number:Average(). This method returns the average of the given numbers.
local numbers = {1, 5, 7}
print(Noir.Libraries.Number:Average(numbers)) -- 4.333...
  • Added a new service, NotificationService. This is a minimal service that allows you to send customizable notifications to players.
local everyone = Noir.Services.PlayerService:GetPlayers() -- table of players. note that the NotificationService methods accept a player as an argument instead of a table of players
Noir.Services.NotificationService:Info("Title", "Hello, %s!", everyone, "world") -- due to string formatting, the message becomes: "Hello, world!"
  • Added a new service, TPSService. This service allows your addon to get the TPS of the server, including the average TPS. The service also has support for slowing the game down until a specified TPS is achieved.
local TPS = Noir.Services.TPSService:GetTPS() -- 62.0
local AvgTPS = Noir.Services.TPSService:GetAverageTPS() -- 62.0

Noir.Services.TPSService:SetTPS(30) -- Slows the game down to 30 TPS
  • Added an usePeerIDsAsIndex argument to Noir.Services.PlayerService:GetPlayers(). This argument is optional and defaults to false. Setting it as true is very slightly faster however.
print(Noir.Services.PlayerService:GetPlayers(false)) -- false by default, you can leave the argument out. it is optional
{
    [1] = NoirPlayer(ID = 5, ...),
    ...
}
print(Noir.Services.PlayerService:GetPlayers(true))
{
    [5] = NoirPlayer(ID = 5, ...),
    ...
}

Fixes

  • Fixed class inheritance not bringing down methods from the parent (if any).
  • Fixed incorrect if statements within the internal class method :_Descend().
  • Fixed incorrect title for an error message in the logging library.

Changes

  • Connections to game events in services are now prefixed by _ to indicate it is used internally.
  • Renamed OnCustomCommand to _OnCustomCommandConnection in the built-in CommandService to stay consistent with other services.
  • Renamed OnLoadConnection to _OnObjectLoadConnection in the built-in ObjectService. The same was done for OnUnloadConnection.

Noir 1.10.0

08 Jul 07:50
Compare
Choose a tag to compare

📚 Details

Version: 1.10.0

❔ Installation

Check out the documentation for information on how to install and use Noir in your addon.

💬 Description

A bunch of things have been added in this release. All of these additions should not impact your addon whatsoever if you was to update Noir.

Additions

  • Added LongDescription, ShortDescription, and Authors attributes to the NoirService class. You can optionally fill out these attributes by passing new arguments to Noir.Services:CreateService().
  • Added descriptions and credit to every built-in service and library.
  • Added Noir.Services:RemoveService().
  • Added :GetSaveData() method to the NoirService class. Now you can directly modify the table instead of using :Save(), :Remove() and :Load().
  • Added a command example to the comment description of Noir.Services.CommandService:CreateCommand().
  • Added a :Notify() method to the player class. This allows you to easily send notifications to players.
  • Added Noir.IsDedicatedServer. Noir's bootstrapper automatically sets this upon Noir starting. As a result, do not modify this yourself. Treat it as a read-only variable.
  • Added a basic type checking module to Noir accessible via Noir.TypeChecking.
  • Added type checking to every Noir function and method. This took a while.
  • Added Noir.Services:FormatService(). This is used in the bootstrapper to display the authors of services that are being initialized/started. It is also used to show whether or not a service is built-in.
  • Added :GiveItem() to the NoirObject class. This method allows you to give SW characters items, including players.

Fixes

  • Fixed Noir.Services.PlayerService.OnLeave event being fired for all players when onDestroy was called for an addon reload. Unfortunately, OnLeave doesn't get called at all if players leave because the save was exited, or because players left while your addon errored. This will have to stay the case for now unfortunately.

Changes

  • When an object gets unloaded and removed from the game, it is removed from g_savedata. This is to prevent memory leaks.
  • Libraries are now classes instead of raw tables. The above attributes have also been added to the class and can simiarly be filled out by passing new arguments to Noir.Libraries:Create()
  • The :ServiceInit() method is no longer mandatory for services. Likewise, warnings will no longer appear if a service doesn't have the :ServiceStart() method.
  • If the addon is being ran in a dedicated server, the built-in PlayerService will no longer count the server itself as a player. This is another Stormworks quirk that Noir now builds around. :-)

Removals

  • Removed unnecessary logging when Noir starts (eg: when an object is loaded from service save data, when a player is loaded from server.getPlayers(), etc).

Noir 1.9.0

04 Jul 15:25
Compare
Choose a tag to compare

📚 Details

Version: 1.9.0

❔ Installation

Check out the documentation for information on how to install and use Noir in your addon.

💬 Description

This release comes with a few new additions.

Additions

  • Added two new libraries, Noir.Libraries.JSON and Noir.Libraries.Base64.
    • The JSON library allows you to encode Lua objects into JSON strings and vice versa.
    • The Base64 allows you to encode strings in Base64 format, and decode Base64 strings into regular strings.
  • Added :IsInteger() method to Noir.Libraries.Number. As the name shows, the method returns whether or not the provided number is an integer.
  • Added return annotation to Noir.Class.

Fixes

  • Fixed a description typo with a method in Noir.Services.
  • Fixed a description typo with the NoirService class.

Noir 1.8.5

24 Jun 01:42
Compare
Choose a tag to compare

📚 Details

Version: 1.8.5

❔ Installation

Check out the documentation for information on how to install and use Noir in your addon.

💬 Description

This release comes with a few minor additions, changes, and fixes.

Additions

  • Noir:GetVersion(): This has been added that returns the MAJOR, MINOR, and PATCH from the current Noir version as separate values.

  • Noir.Services.GameSettingsService:GetSettings(): This is simply a method that returns the result of server.getGameSettings(). Exists to keep everything settings-related within the service.

Changes

  • A few minor changes have been made to method descriptions to clarify things.

Fixes

  • Noir.Services.GameSettingsService:GetSetting(): Fixed this method returning nil if the setting retrieved was false.

  • Noir.Services.GameSettingsService:SetSetting(): Fixed this method returning nil and logging an error if the setting name provided was valid but the setting was false.

Noir 1.8.4

17 Jun 16:57
Compare
Choose a tag to compare

📚 Details

Version: 1.8.4

❔ Installation

Check out the documentation for information on how to install and use Noir in your addon.

Noir 1.8.3

17 Jun 16:48
Compare
Choose a tag to compare

📚 Details

Version: 1.8.3

❔ Installation

Check out the documentation for information on how to install and use Noir in your addon.