Code Monkey home page Code Monkey logo

backbone's Introduction

backbone

What is backbone?

Lightweight, ECS-like package for Flame and Flutter. Backbone doesn't seek to replace the component system in Flame, it extends it by ECS patterns and a unified multi-platform input system.

Is it ready for production?

No, we are still working on this package, currently we are using it in a not yet announced project.

What does backbone do for me?

It helps you to organize and structure features of your game and still use the many great features Flame ships. With backbone you can also increase the reusability of code. Backbone comes with a some build in features to support you.

  • Multiplatform input system for:
    • Taps
    • Drags
    • Long press
    • Keyboard events
    • All pointer types are supported (touch, mouse, stylus)
  • Message system to decouple game elements from each other
  • Fast queries for your nodes (game elements)

Can I use backbone beside the existing component system?

Yes! Backbone doesn't try to replace the component system at all. You can see it as an addition/upgrade to it.

Is it only something for new projects?

No! You can add backbone to any Flame game and use it alongside the existing components.

Do you have an example?

Yes, there is simple example application that showcases all basic uses-cases of backbone. The code for the app can be found in example, a live demo can be found here.

Check out the docs

Check out our documentation here in the repository or directly in the code.

backbone's People

Contributors

dev-owl avatar idea-christian avatar skyne98 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

Watchers

 avatar  avatar  avatar  avatar

Forkers

gtgalone

backbone's Issues

Exception on input handling

Holla :)

I get an exception when I release the mouse button outside the screen area.

Video
exception_2.mov
Logs:
Restarted application in 208ms.

โ•โ•โ•โ•โ•โ•โ•โ• Exception caught by gesture library โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
The following StateError was thrown while routing a pointer event:
Bad state: No element

When the exception was thrown, this was the stack
#0      ListMixin.firstWhere (dart:collection/list.dart:167:5)
#1      Input.onPointerRemoved
#2      _BackboneGameWidgetState._handleEvent
#3      PointerRouter._dispatch
#4      PointerRouter._dispatchEventToRoutes.<anonymous closure>
#5      _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:625:13)
#6      PointerRouter._dispatchEventToRoutes
#7      PointerRouter.route
#8      GestureBinding.dispatchEvent
#9      RendererBinding.dispatchEvent
#10     GestureBinding._handlePointerEventImmediately
#11     GestureBinding.handlePointerEvent
#12     GestureBinding._flushPointerEventQueue
#13     GestureBinding._handlePointerDataPacket
#14     _invoke1 (dart:ui/hooks.dart:164:13)
#15     PlatformDispatcher._dispatchPointerDataPacket (dart:ui/platform_dispatcher.dart:361:7)
#16     _dispatchPointerDataPacket (dart:ui/hooks.dart:91:31)
โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

Stacktrace leads to this place:

final leavingPointer = _pointers.firstWhere((pointer) =>

Starting a drag event and finishing it outside the window still results in a crash

ListMixin.firstWhere (dart:collection/list.dart:167)
Input.onPointerRemoved (/Users/christian/Development/backbone/lib/prelude/input/mod.dart:97)
_BackboneGameWidgetState._handleEvent (/Users/christian/Development/backbone/lib/widget.dart:88)
PointerRouter._dispatch (/Users/christian/Development/flutter/packages/flutter/lib/src/gestures/pointer_router.dart:98)
PointerRouter._dispatchEventToRoutes.<anonymous closure> (/Users/christian/Development/flutter/packages/flutter/lib/src/gestures/pointer_router.dart:143)
_LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:617)
PointerRouter._dispatchEventToRoutes (/Users/christian/Development/flutter/packages/flutter/lib/src/gestures/pointer_router.dart:141)
PointerRouter.route (/Users/christian/Development/flutter/packages/flutter/lib/src/gestures/pointer_router.dart:133)
GestureBinding.dispatchEvent (/Users/christian/Development/flutter/packages/flutter/lib/src/gestures/binding.dart:423)
RendererBinding.dispatchEvent (/Users/christian/Development/flutter/packages/flutter/lib/src/rendering/binding.dart:337)
GestureBinding._handlePointerEventImmediately (/Users/christian/Development/flutter/packages/flutter/lib/src/gestures/binding.dart:395)
GestureBinding.handlePointerEvent (/Users/christian/Development/flutter/packages/flutter/lib/src/gestures/binding.dart:357)
GestureBinding._flushPointerEventQueue (/Users/christian/Development/flutter/packages/flutter/lib/src/gestures/binding.dart:314)
GestureBinding._handlePointerDataPacket (/Users/christian/Development/flutter/packages/flutter/lib/src/gestures/binding.dart:295)
_invoke1 (dart:ui/hooks.dart:167)
PlatformDispatcher._dispatchPointerDataPacket (dart:ui/platform_dispatcher.dart:341)
_dispatchPointerDataPacket (dart:ui/hooks.dart:94)

Notes of Entities

Entity

Entity is a lightweight object that contains traits, gets selected by queries and gets processed by systems. An entity has to be associated with a specific Realm, but can be created and initialized before it is added to one.

An entity can have an optional parent. By itself, it doesn't do much, but systems can use it to infer certain behaviors, such as TransformTraits becoming relative when parent is set.

Trait

Traits are lightweight data objects, which serve as both a piece of data storage and/or a marker for behavior. They are "components" from the "Entity-Component-System".

Bundle

Bundle is an abstract class, that contains a static list of initializable traits. They can be used to add or remove a whole chunk of related traits at once, enabling a whole set of functionality at once. Traits themselves should automatically implement Bundles, so the user can pass a Trait as a single-trait bundle.

EntityComponent

EntityComponents are Flame components, that serve as a bridge between the ECS architecture of backbone and a component-tree architecture of Flame. Each EntityComponent includes an entity and automatically searching for the nearest Realm parent to register itself onMount. There are BaseEntityComponent and PositionEntityComponent are available as alternatives to Component and PositionComponent. Access entity via entity.

Development Mode debugging

By abstracting most properties and calculations away from the underlying library, the developer should be able to press a key in game and go into the developer mode.

Developer mode will feel much like an integrated editor in a fully-fledged game engine. This might pave the road to an actual editor some time in the future.

This mode should allow developers to:

  1. Freely fly around with a virtual "developer" camera, controlling it with WASD / touch
  2. Have the game continue to run as if nothing happened, but view the game through the virtual "developer" camera / block input events
  3. See a node tree, being able to click and select / zoom to specific nodes
  4. See node details
  5. See message queue
  6. See performance metrics (FPS, tick time, system times)
  7. Send debug commands to the nodes (open their debug console and input commands that are processed by something like an optional onDebugCommand override)
  8. Send input events or enable specific input interactions temporarily

Selectable trait and system

  1. Add Result resources for different input systems
  2. Add a Selectable trait
  3. Add a Selection resource
  4. Hook into input results to decide what should be selected

Notes on the Asset System

Sources of inspiration:
Architecture of Bevy

Handle<T>

Handles are lightweight pointers to assets, such as textures, sounds or any other kind of heavy resource you need in your game. Handles can point to resources not yet loaded. This allows you to pass it, for example, to a sprite and have it "pop in" as soon as it is ready.

Assets

A resource, which represents the global asset server. The server manages asset providers and keeps track of the cache of loaded resources.

AssetProvider

An abstract class that represents a potential source of assets. You might implement, or use providers, which, for example, load resources from the file system, from the network server or get processed from a raw file. When you request an asset from the Assets resource, it sequentially requests that resource from each of the providers, until one returns a success. Optionally, you can provide a specific type of the provider you want to get that resource from.

Reduce delays in the input system

Whenever possible, for performance-sensetive situations like hovering, tapping and selection, prefer to forward and process events directly, without waiting for the system to run?

This means that tappables, selectables and hoverables will get their callbacks fired right away, when events arrive.

Large archetypeBuckets[archetype] list makes frame too low

In this code
if (bucket.contains(entity) == false) {
This line is not working.
It makes large list and frame too low.

/// Push an entity into an existing archetype
  void putIntoBucket(Entity entity) {
    // Add the trait to the new archetype storage
    final archetype = entity.archetype;
    if (archetype.length > 0) {
      if (archetypeBuckets.containsKey(archetype) == false) {
        throw Exception('Archetype $archetype is not registered');
      }

      // Add only if it's not already in the bucket
      final bucket = archetypeBuckets[archetype]!;
      if (bucket.contains(entity) == false) {
        bucket.add(entity);
      }

      // if necessary add to the non-empty bucket cache
      final index = nonEmptyBucketKeys.indexOf(archetype);
      if (index == -1) {
        nonEmptyBucketKeys.add(archetype);
        nonEmptyBucketValues.add(bucket);
      }
    }
  }

[TBD] Add current node to callbacks for input

Adding the current node/owner of the trait would allow traits to be more generic and could be added from any point and react based on the inputs without the need of knowing the exact content.

Allow defining a stage for system's execution

Like in bevy here.

Some systems might want to run before, or after, all other normal systems. Currently, it's impossible to do, unless you make this system manually require the execution of all those systems.

Stages to support at first:

  • PreSetup, Setup
  • First, PreUpdate, Update, PostUpdate, Last

By default, systems are added to the Update stage and are executed in the order of being added, unless manually requiring to execute, breaking the order.
Also, requiring execution of a system from a different stage should result in an error, as it moves the system execution out of the desired stage and might break things.

Cannot pass custom game type

Thank you for the nice package.

I am trying to use it.

But now in my game, I am using custom game type HasGameRef<MyCustomGame>

With backbone, actually I need to PositionNode<MyCustomGame> for HasGameRef in this node.

is it possible entire package to pass custom game type?

If you are agree, I can make pull request for this.

Sample-based performance measuring with `prefmon`

Switch from time calculation and aggregation to sampling in prefmon. This means moving from calculating time spent in a function or block of code and reporting it to reporting a place in code where execution currently happens whenever the external monitoring tool requires it. It should resolve the issue of too much overhead from aggregating data and allow for nearly infinite (and configurable) granularity in measurements.

Source of inspiration: .NET, JS and Dart debugging tools.

Acceptance criteria:

  1. There is an isolate (or any other agent running in parallel to the program) that keeps track of the current block of code in execution, based on the program itself reporting it (without some specific rate, real-time)
  2. prefmon, having a TCP (WS) connection to it, requests or receives a current executing scope at a specified rate
  3. Over a specific timeframe, prefmon should receive a specific number of samples (for example 1 000 000 over 1000 ms or 1000 per 1 ms) so that it can make an educated guess about the % of time that was spent in a specific part of code
  4. Either come up with an automatic way of reporting the current place of execution, or make a performanceEnter(<function or block name>) and performanceLeave() functions that directly report to the isolate with as little overhead as possible
  5. Performance measuring functions get stripped in release mode, so that they don't influence performance
  6. Old performance measuring code goes away completely

Some notes:
On the isolate side, the current place of execution is probably not a single name, but a stack, which represents the current call stack. Otherwise, the performanceLeave() will have nothing to reset and "prefmon" will not be able to decide in which exact "child" function it is.

Add example use case documentation

Add example use case documentation, this can be based on the example project but should also cover:

  • Important things to know
  • - Register all traits
  • - Why is the realm null for some nodes?
  • What default resource are included in backbone
  • How to use the input system with multiple realms
  • How to use just part's of the input system

Please extend the list with further points.

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.