Knife: a collection of micro-modules

Showcase your libraries, tools and other projects that help your fellow love users.
User avatar
airstruck
Party member
Posts: 650
Joined: Thu Jun 04, 2015 7:11 pm
Location: Not being time thief.

Knife: a collection of micro-modules

Post by airstruck »

Knife
A collection of micro-modules for use with Love and similar frameworks.

Image

Overview

In general, Knife's modules seek to solve fairly low-level problems. Knife will never include modules which rely on any specific Love functionality; all modules are framework-agnostic and will run on any recent version of Lua or LuaJit, with no dependencies. Each module is isolated from the others; individual modules may be copied into a project as needed.

Some modules are similiar to existing solutions; for example knife.timer is very similar to hump.timer or (for tweens) flux. Other modules are fairly unique, like knife.convoke and knife.chain. Others occupy a sort of middle ground; knife.test and knife.system solve the same problems as existing solutions, but take a simple and flexible approach that should be refreshing.

All modules strive for a clean, minimal style. Code should be easy to follow and modify if needed. However, all modules are designed for performance, especially under LuaJit. They should perform as well as or better than other existing solutions. In some cases, clarity may be sacrificed for performance, for example when using generated code to optimize for LuaJit.

Modules

The following modules are included. More will likely be added at some point.
  • knife.base - A base class for class-based OOP.
  • knife.behavior - A state machine manager.
  • knife.bind - Bind arguments to functions.
  • knife.chain - Flatten async code with chained functions.
  • knife.convoke - Flatten async code with coroutines.
  • knife.event - Dispatch and handle events.
  • knife.memoize - A memoization function.
  • knife.serialize - Store data structures as strings.
  • knife.system - An entity component system.
  • knife.test - A fixture-free test framework.
  • knife.timer - Create timers and tweens.
Get Knife!

Get the code and read the docs on GitHub at airstruck/knife.
Last edited by airstruck on Sat Sep 19, 2015 7:09 pm, edited 2 times in total.
User avatar
AntonioModer
Party member
Posts: 202
Joined: Fri Jun 15, 2012 5:31 pm
Location: Belarus
Contact:

Re: Knife: a collection of micro-modules

Post by AntonioModer »

Cool, thanks airstruck.
Knife picture from GTA5?
Last edited by AntonioModer on Sat Sep 19, 2015 10:44 pm, edited 1 time in total.
User avatar
Roland_Yonaba
Inner party member
Posts: 1563
Joined: Tue Jun 21, 2011 6:08 pm
Location: Ouagadougou (Burkina Faso)
Contact:

Re: Knife: a collection of micro-modules

Post by Roland_Yonaba »

Nice.
Think of adding something to handle input and gamestates.
User avatar
airstruck
Party member
Posts: 650
Joined: Thu Jun 04, 2015 7:11 pm
Location: Not being time thief.

Re: Knife: a collection of micro-modules

Post by airstruck »

Roland_Yonaba wrote:gamestates
I plan to add another layer on top of Knife to manage gamestates, but it will be a separate project. It will use the base, event, and timer modules and will rely on some Love-specific stuff, so it's out of scope for Knife (no module interdependency, no external dependency).
Roland_Yonaba wrote:input
Have you tried tesselode/tactile? I haven't used it yet, but I've heard good things. I might have done some things differently internally, but the API seems nice.

Anyway, this would also be out of scope for Knife since it would rely on Love (external dependency). I may create something like this down the road depending on how tactile loks at that point, but I haven't had a use for it yet.
User avatar
airstruck
Party member
Posts: 650
Joined: Thu Jun 04, 2015 7:11 pm
Location: Not being time thief.

Re: Knife: a collection of micro-modules

Post by airstruck »

Added knife.bind. This small utility function should be familiar to users of JavaScript or Boost bind.

Especially useful for deferred invocations of variadic functions.
User avatar
airstruck
Party member
Posts: 650
Joined: Thu Jun 04, 2015 7:11 pm
Location: Not being time thief.

Re: Knife: a collection of micro-modules

Post by airstruck »

Added knife.serialize.

Yes, I realize everyone and their grandmother has already written a serialization module. I'm including one here as a convenience for those who are already using Knife and want a quick way to serialize data for savegames, managed config, and so on. Data is serialized as Lua source and can be deserialized with loadstring/require/dofile.

It is not fancy; it has no options and is not particularly concerned about producing tiny output or being extremely fast (although performance is similar to other solutions). It does support circular refs and corner-case numbers. It is consistent with Knife's goal of presenting a clean and simple API -- it is a single function that takes a single value and returns a single result.
User avatar
Inny
Party member
Posts: 652
Joined: Fri Jan 30, 2009 3:41 am
Location: New York

Re: Knife: a collection of micro-modules

Post by Inny »

If I can make an observation, a lot of the useful functionality you're probably looking to implement can probably be cribed from projects like luafun, or moses. In general though you'll probably end up implementing a lot of the primitive you'll see in traditional functional libraries (for instance, javascript has lodash/underscore or ramda). I know this because I'm keeping a gist on github with most of these kinds of functions here. These links should all give you lots of inspiration about what you want to include in your library.
User avatar
airstruck
Party member
Posts: 650
Joined: Thu Jun 04, 2015 7:11 pm
Location: Not being time thief.

Re: Knife: a collection of micro-modules

Post by airstruck »

Inny wrote:luafun, or moses
Thanks for bringing that up. I think those libraries are good if you need a full suite of FP tools. Knife is more of a multi-paradigm suite of modules, FP is not the only concern. There is some OO stuff (base), some classic design pattern stuff (event and system), and some utility stuff (serialize and timer).

The all-in-one FP libraries are good, but in a few cases I feel like they fall a little short. Compare Knife's memoize and bind with other solutions and I think you'll find them to be more complete and better optimized for LuaJit.

Most of the modules in Knife were created because I needed some functionality that wasn't present in existing solutions, or wanted to avoid patterns that cause LuaJit to fall back to the interpreter. In a few cases (timer, system) I wanted a different API, in others (base, serialize) I just wanted something minimal.

FWIW, I think one problem with those all-in-one libraries is the pressure to keep each feature very minimal. If each feature has about 10 lines dedicated to it on average, and everything's all in one file, it doesn't feel right to write 100 lines for one feature to get LuaJit to behave or to handle some corner cases. I think a more modular approach encourages addressing each feature more thoroughly.

TLDR: Knife isn't trying to compete with all-in-one FP libraries, it's taking a more multi-paradigm, modular, feature-oriented approach.
User avatar
airstruck
Party member
Posts: 650
Joined: Thu Jun 04, 2015 7:11 pm
Location: Not being time thief.

Re: Knife: a collection of micro-modules

Post by airstruck »

I've updated knife.system (the ECS module) with some new features to give systems more control over which entities they process. Optional components (may or may not be present), prohibited components (must not be present), and component choices (at least one must be present) are now supported.

Also, entity removal and insertion should be more robust now, and the API for entity removal has changed slightly to better match the API for entity insertion.
User avatar
scissors61
Citizen
Posts: 76
Joined: Fri Jan 08, 2016 10:16 am

Re: Knife: a collection of micro-modules

Post by scissors61 »

Hi, thanks for your library.
I'm experimenting with ecs using your library, which worked pretty well, but I'm having a problem when trying to use knife.system with love.mousepressed because that function requires the arguments "x, y, button, istouch" which I can't find a way to pass them to the entities/system. Is it possible?
Post Reply

Who is online

Users browsing this forum: No registered users and 44 guests