GithubHelp home page GithubHelp logo

evaera / matter Goto Github PK

View Code? Open in Web Editor NEW
146.0 8.0 36.0 3.01 MB

A modern ECS library for Roblox.

Home Page: https://eryn.io/matter/

License: MIT License

Lua 96.00% CSS 1.29% JavaScript 2.71%
roblox ecs

matter's Introduction

Hi, I'm Eryn! I work on a lot of different things, including developer tooling, libraries, websites, and games!

I'm a self-taught engineer with a passion for learning new things. I love going down the rabbit hole of learning the ins and outs of something that's new and exciting, and taking that experience with me onto the next thing. I also love teaching and helping other engineers with any problems they might have!

I've created or contributed to hundreds of projects using a wide breadth of technologies and patterns that I've learned along the way. I've worked on games (in Roblox and other engines), websites (both front end and back end), bots & automation, command line tools, add-ons & mods for various games, and all sorts of miscellaneous adventures. I believe that the best results can be achieved when you take experience and wisdom from many different places into account when creating something new.

If you're interested in seeing some my projects outside of work, check out my portfolio website: eryn.io

matter's People

Contributors

4igz avatar alexasterisk avatar aloroid avatar ambergamefam avatar anaminus avatar benbrimeyer avatar bubshurb avatar dataencoded avatar evaera avatar fizzyhex avatar flamenco687 avatar hatmatty avatar jacktabscode avatar lasttalon avatar memorycode avatar metrowaii avatar nidoxs avatar noahwillcrow avatar overhash avatar rimuy avatar samcparker avatar shouxtech avatar ukendio avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

matter's Issues

mouse highlight incorrectly inferring character when zoomed in

A lot of times it will incorrectly highlight another instance due to the character always overlapping the mouse, this is a consequence of having merged this in #68.

Repro:

  1. Play Attack Of the Killer Roomas
  2. Zoom in
  3. Enable debugger
  4. Try hover over anything.

A simple fix could be checking whether the distance between the camera and the head position is close enough, in the case that it is, add the character for the raycasts filter.

Add additional error on improper component insertion

Currently, it is too easy to make a mistake like this:

world:insert(id, SomeComponent)

where instead the correct code would be:

world:insert(id, SomeComponent())

Currently, the first case silently fails. It would be good to explicitly check for and error invalid components on insert, so that this entire class of bugs is eliminated.

<SystemTable>.after does not accept importing <SystemTable>.system

.after does not accept importing .system

import { system as dayNightCycle } from "./dayNightCycle";

export const after = [dayNightCycle];

Left me with the cannot schedule systems error, it was fixed by having to do

import * as dayNightCycle from "./dayNightCycle";

export const after = [dayNightCycle];

Snapshot should return a "View" Handle

queryResult:snapshot() performs all of the iterator task at once and provides you the results of the query at the moment it is called. Hecs has a similar feature with query().views(), which is meant for repeated random access. It provides you a handle to discern whether it contains a specific entity and to access its data easily at an amortized cost via Views.get() and Views.contains() respectively.

I think providing similar methods will make :snapshot a more meaningful arm to QueryResult. We could even naively implement this by changing the list into a dictionary that maps the entity id to its packed data, and returning it, allowing people to just index it. But this wouldn't preserve the same order of traversal of entities as the query.

Considerations

This is a breaking change as it would most likely change the return type. Alternatively we can look to make a separate method called view.

Side note

Currently, you can't follow the :without() arm with :snapshot(). We may want to make a separate change to address this. #85

For tracking
Partial implementation: #80

Using the hover inspect feature on an entity as it's being despawned causes an error

2023-12-15.15-54-55.mp4
03:58:19.233  ReplicatedStorage.rbxts_include.node_modules.@rbxts.matter.lib.World:89: attempt to index nil with nil
ReplicatedStorage.rbxts_include.node_modules.@rbxts.matter.lib.World:89 function _getEntity
ReplicatedStorage.rbxts_include.node_modules.@rbxts.matter.lib.debugger.widgets.hoverInspect:7
  -  Server
  03:58:19.233  Stack Begin  -  Studio

Put example game files in a single folder

Matter's example game is missing the example.project.json mentioned in it's README. This file isn't created automatically by wally.

EDIT:
The project file is actually in the root of the repository - which is confusing. I'd expect all files for the example game to be located inside the example game folder, specially considering that it has files you'd normally find in a rojo project folder

Should be able to search entities in the debugger

Adding onto #97, it is currently very difficult to find a very specific entity in your game. Sorts mediate this, however fundamentally there needs to be better capabilities to search for them.

I have already laid out the ground work for the search filter's functionality. Not the best implementation yet but it works reasonably well without being intrusive for anyone to call. The function searchFilter can be found in the branch "search-filter". You pass in a world and a query string. E.g. searchFilter(world, "Test, Friend, !Hello, !Goodbye") which will query for entities with Test and Friend while skipping any entities that contain either of Hello or Goodbye

The idea for the implementation would be to grab the input of a textbox and feed that to the searchFilter's params. And then taking the returned entities and display them on the widget.

QueryResult needs rework

Currently if you use any of the methods of QueryResult it is expected to be used immediately. An example of how this behaviour could be a restriction is that you can't create a Snapshot following a query that has the :without() filter. And consequently impedes the implementation of View.

There are a few potential solutions:

  1. Make the query lazily loaded, and have the user chain on .build() (or analogous) -This is not very ergonomic at all.
  2. Let without modify the expand and next methods on QueryResult and return a new iterator - It is not clear how we would approach this and what issues it would create.
  3. We add query modifiers and allow that to mark the set of components for which to include and exclude. For example for _ in world:query(With(...), Without(....)). - This is completely changing of the api surface and very unrealistic for us to implement.

Add QueryResult:toList()

Currently iterating over queries and inserting new components silently fails. It'd be good if there was an easy way to convert a QueryResult into an immutable list, so that you can iterate and also update the world.

UseThrottle don't work

i just use throttle with 30 seconds and entity discriminator but the useThrottle don't wait 30 seconds and it execute the following lines of code...

Use __iter [in addition to?] __call

Our implementation of __iter (RFC) currently respects __call and treats it as a sign that we should not iterate through key/value pairs of the table to preserve backwards compatibility. __iter is currently in Studio beta (https://developer.roblox.com/en-us/resources/release-note/Release-Notes-for-526).

Long term it would be nice if we could clean this up and remove the special casing of __call during iteration. This requires that all code that currently uses __call in iterators to migrate to __iter. Matter is one of very few (two for now based on our analytics) libraries that does that.

Would it be possible to specify __iter on iteratable objects? You should be able to do this in a way that doesn't break when __iter is not implemented by simply declaring it as a forwarding method, something like

function Iterator.__iter(self)
  return self
end

(which will still call __call on every iteration after that, __iter is only called once before the iteration begins)

Alternatively you can return an actual iteration function from __iter which will be faster since __call calls are slower than regular function calls, but I haven't looked closely at Matter source to see if this would be easy to do. In either case the change would be backwards compatible if you don't touch __call so it can be implemented before __iter goes out of beta I believe.

FPS Unlocker breaks debugger

Unsure if I should put this here or plasma, but if you have an FPS unlocker on, then it sometimes doubles the ui. This only happens on the client, not on the server.
image

Systems with undefined dependencies cause crash

A system that should run after an undefined system causes a crash.

Minimum repro;

local loop = Loop.new()
local order = {}
local systemA = {system = function() end)
local systemB = {system = function() end, after = {systemA})

loop:scheduleSystems({})
loop:scheduleSystem(systemB)
loop:scheduleSystem(systemA)

In this example systemB has a dependency on systemA, but is scheduled before systemA which results in the crash

Issue originally reported by @benbrimeyer

ChangeRecord behavior right after deletion

Remark: record is of type ChangeRecord.

Current behavior:
record.new might be nil even though record.old is nil too.
This will happen if you spawn and then despawn entity right away in the same frame.

Presumable behavior:
record.new will be populated, record.old will be populated.
Maybe even better to run for once queryChanged with new, and then with old data.

My thoughts:
I'm not sure whether it's intended, but from my P.O.V it's not intuitive behavior.
However I do understand that it might become even more confusing if you change current behavior, but at least documentation of current behavior would be great.

Slider debugger widget returns 0 when panel is closed

Assuming the following code in a system...

const value = widgets.slider({
	initial: 50,
	min: 1,
	max: 100
})

...value will read 0 if the panel is not open. Once the panel is opened, the widget will return the initial value. I expect the widget to return the initial value if the panel is not open.

I'm assuming this has to do with the panel using dummy handles when the panel is closed.

Toggle state window in debugger

In the debugger, clicking the list item for a system with an open window closes that system's window. Clicking the button for a state table that's already open currently does nothing, it should work the same as systems and close the window.

Allow components to be constructed with default values

Often my systems will expect certain fields to exist within components.

It'd be great to have a built-in way to support default values for components when they're assigned to entities.

I'm thinking it could work something like:

local component = Matter.component(name, { foo = "bar", xyz = nil })
world:spawn(component({ xyz = "abc" })) -- an entity is created with component data as { foo = "bar", xyz = "abc" }

Add namespace to worlds

It would be nice to add an optional namespace to World. This would make it easier to isolate behavior between two worlds (for example during tests) when interacting with the DOM (e.g. namespacing instance attributes).

Expose Topo cleanup routine

Consider the following events:

  1. you have a list of systems
  2. you schedule said systems in a loop, and begin the loop
  3. you cancel the loop by disconnecting the events
  4. you restart the loop with a new set of systems

Currently, hook state for systems which are not included in step (4) lingers around, since the cleanup routine was never called for them. It'd be nice if there was a way to clean up all remaining hooks after a loop is terminated. This is useful for hot reloading.

Without should narrow archetypes

Currently, using :without(Components.B) in a query is similar to querying normally, using world:get(Components.B) to check if the component is present, and using continue to skip the iteration (though faster.) This is intended behavior and is documented.

for id, a in world:get(Components.A):without(Components.B) do
    -- Do something
end

for id, a in world:get(Components.A) do
    if world:get(id, Components.B) do
        continue
    end
    
    -- Do something
end

However, this approach comes with a few downsides:

  • The cost of iteration on entities with excluded components is hidden.
  • The archetype is broader than required.

Giving :without the ability to narrow the archetype would resolve these issues, though the potential downsides outside of implementation complexity are unclear.

Debugger should have the ability to sort components

Within the matter debugger, under the World Inspect window, we list all components seen in the World. Currently this list is always alphabetically sorted ascending. It would be great if we could sort descending as well as by number of occurrences.

Debugger: Query UI Bug

In my system, it queries after a useThrottle of 35ms:
The debugger API flickers, and seems to respect this a bit too much...

matter-debugger-issue.mov

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.