Comments (5)
Fixed: Looks like the Spin
symbol is being parsed as a converter, which newEntityWith from polymorph (at least the version installed via the below command) couldn't understand as a type.
nimble install https://github.com/rlipsc/polymorph.git
The fix to make it work with the version of Polymorph installed with that command is simply to make Spin
a more traditional type (float
member named rot
, and update the constructors and system that uses that component accordingly). Works fine with that fix.
Alternatively, installing polymorph as follows:
nimble install https://github.com/rlipsc/polymorph.git@#master
Makes it such that the fix for Spin
is not needed.
In sum, it seems like all the packages simply need to be installed with the @#master
suffix (which is frustrating, because installing them in a particular order will cause the incorrect package version to be installed.
from polymers.
Original error is resolved, partially: installing the glbits
library does not work with the following command:
nimble install https://github.com/rlipsc/glbits.git
Had to be installed as follows:
nimble install https://github.com/rlipsc/glbits.git@#master
Not sure why the master branch had to be specified. Regardless, the following error still emerges:
/home/smt/Code/nim/polymorph_tests/test1.nim(190, 29) template/generic instantiation of `newEntityWith` from here
/home/smt/.nimble/pkgs/Polymorph-0.1.0/polymorph/statechanges.nim(37, 11) Error: FindType: adding components needs an object constructor like MyType(field: value) or an ident such as a variable, cannot process a nnkConv
Conv
Sym "Spin"
Call
Sym "degToRad"
Call
Sym "rand"
Infix
Sym ".."
FloatLit -1.0
FloatLit 1.0
from polymers.
Hi @0xSMT, glad you've managed to solve this already, and thanks for writing out the steps you took solve it!
According to https://github.com/nim-lang/nimble#nimble-install
Nimble always fetches and installs the latest version of a package. Note that latest version is defined as the latest tagged version in the Git (or Mercurial) repository
So your solution makes sense. The tagged release of Polymorph is quite old at this point and this library is expected to run with the latest Polymorph commit, so I've pushed an update to the .nimble
file to use polymorph#head
, instead of defaulting to tagged releases.
I've also pushed a release for glBits so there's a recent tag for nimble to use.
Hopefully these changes mean you don't need to use @#master
but let me know if there's still an issue.
from polymers.
Works great now! Only caveat is installing Polymorph first directly (without @#master
) will still seem to install an older version, so if you install Polymorph first and then Polymers you'll have two versions of Polymorph installed, but otherwise everything works out of the box!
Also would just like to thank you for the amazing work on these projects -- Polymorph has such amazing potential and it's very well-designed, I've been playing with it all weekend. Its use of the macro system for compile-time ECS generation is inspiring, and sets a gold-standard for Nim libraries (especially since so many of them anymore seem to be unmaintained...) The best of luck on this project in the future, I'll continue keeping an eye on it! :)
from polymers.
Only caveat is installing Polymorph first directly (without @#master) will still seem to install an older version
Nimble is downloading from the tag, which is super old. I'm currently working on better documentation for a new tagged release and will push that when the docs are decent, then I'll submit it to nimble so you can do nimble install polymorph
and hopefully it will all work (I'll have a deeper dive into nimble when that happens).
Really cool to hear things work out of the box, though. I'm developing on a Windows machine so it's great to hear graphics and physics works on Linux!
Also would just like to thank you for the amazing work on these projects -- Polymorph has such amazing potential and it's very well-designed, I've been playing with it all weekend. Its use of the macro system for compile-time ECS generation is inspiring, and sets a gold-standard for Nim libraries (especially since so many of them anymore seem to be unmaintained...)
Thank you for the kind words! It's great to hear, and it's nice to hear the design resonates, too! I'm a big believer that ECS is just another way to organise code in the same vein as OOD, and Polymorph is developed with that in mind rather than specifically for game development (though I'm also using it for gamedev).
There's definitely a lot of potential with a code generation approach to ECS. Since there's no run time to speculate on potential features it's truly "pay for what you use", and as data structures are configurable without changing any code, it's extremely adaptable.
Essentially, Polymorph is translating declarative dispatch - "run this code when this data exists" - into simple imperative loops and statically compiled list updates. All the code runs predictably from top to bottom as it's written, and combined with being able to allocate everything on the stack to fixed sizes (pending a few seq
being configurable as array
behind the scenes), it's amenable to embedded and resource constrained devices where stack overflows from complex callbacks are an occupational hazard.
Inline events also let you build imperative code whilst writing in an event driven style, as they're directly included into the generated code output for relevant operations. For example, code added to an event like SomeComponent.onAdd
is output by entity.add SomeComponent()
, and multiple code blocks can be added to individual events. This lets you create libraries with events which can be extended by users whilst maintaining the open/closed principle and linear code flow. System events even let you add and remove components within the event (of course, with great power comes great responsibility)!
Using macros is one of Nim's killer features and I'm really looking forward to seeing what's possible going forward. I feel we're at the beginning of the potential curve of Nim's macros being used in earnest. Even with Polymorph, there's little things like registerComponentsFromFile
which is just three lines of code, but potentially allows fetching the file from a network source, perhaps even as part of the build process, so you can maintain compile time type checking with a remote source.
Of course, the caveat to extensive metaprogramming is that it does add to build times. Thankfully Nim is pretty fast already, but the push for incremental compilation right now shows things could be faster still.
The best of luck on this project in the future, I'll continue keeping an eye on it! :)
Cheers!
As a taste of future work, check out automated threading. This will take advantage of the static analysis Polymorph currently does to determine which components are being written to and read from within systems (you can see this info when compiling with -d:ecsPerformanceHints
) to automatically handle threading for you. As systems are expected to be run in order, there are 'paths' of systems which don't interact with others based on the components they use, so these can be spawned as threads and the appropriate synchronisation primitives can be inserted for you at the points where these 'paths' interact with other systems.
As for Polymers, aside from working demonstrations of how to use Polymorph the goal is to be able to use it as a kind of standard library for data oriented programming.
In that vein many of the components in Polymers are unrelated to game development directly and focus on the kinds of things that programmers need to do as self contained composable components, such as database and console input/output. Originally this was a challenge to see how the ECS pattern fares on these kind of tasks, but as I've written more of these components and systems, I've found that ECS often has advantages over traditional object oriented designs with non-gamedev tasks as well.
For instance the functional isolation of components and systems means you can combine, say, a 3D model rendering component with a component that reads a network stream, add a system that sets the colour of the model based on data in the stream, and you've got the basics of a graphical monitoring tool for remote machines. This could be extended with database components, file access components, or console output components, and so on. As everything is isolated and composable at run time, dramatically pivoting these kind of designs is often just a case of writing a system to bridge component functionality.
Regarding networking, I have a stack of networking components I'm preparing to release for Polymers, including:
- TCP read/write components using IO completion ports.
- HTTP processing and responses.
- JSON RPC.
- Web fetching and RSS feed extraction.
Many languages, Nim included, use async or coroutines for networking code. My hope is that networking with ECS will offer a reduction in run time complexity (and mental complexity), increased operational transparency, and less/no callback context switching.
One of the pros of async is latency, as once you await
something, immediately something else might be processed (although you might not know what). With the ECS networking components, this advantage is captured by using events to begin networking operations. So, entity.add TcpSend(data: "Hello")
will start the operation and then return immediately, much as async does. A dedicated system reads packet completion events and adds 'completion components' (such as TcpSendComplete
and TcpRecvComplete
) so you can create asynchronous systems that build upon one another.
This provides a lot of control and flexibility; systems can be run as batches or stream their operations over time, the order of processing is explicit, operations can be cancelled by removing components or deleting entities (events ensure resources are collected), and statuses can be checked by simply reading the data in the appropriate components.
The other side is that it's a pretty different way of working compared to async, and currently it's missing SSL/TLS support (this will be implemented with OpenSSL).
At the risk of making this reply excessively long, here's how a basic web server looks with these components:
import polymorph, polymers
const
maxEnts = 10_000 # Maximum concurrent connections.
entOpts = fixedSizeEntities(maxEnts)
compOpts = fixedSizeComponents(maxEnts)
sysOpts = fixedSizeSystem(maxEnts)
defineTCPNetworking(compOpts, sysOpts, tllEvents)
defineHttp(compOpts, sysOpts)
registerComponents(compOpts):
type RootPage* = object
makeSystemOpts("servePage", [RootPage], sysOpts):
# Send the response for the root page.
added: item.entity.add HttpResponse(
code: Http200,
body: "Hello!"
)
makeSystemOpts("finishServePage", [RootPage, HttpResponseSent], sysOpts):
# Clean up the connection.
finish: removeEntities()
makeEcs(entOpts)
commitSystems("poll")
let
server =
newEntityWith(
TCPListen(
port: Port(5555),
# When a connection is accepted, the following components are added:
onAccept: cl(
ProcessHttp(),
HttpRouteEntity(
patterns: @[
("/", cl RootPage())
]
)
)
)
)
while true: poll()
However, unfortunately several of the components in Polymers are Windows only.
I really want to include the Linux equivalent for completion ports for the TCP components, and ecs_renderchar
needs to support Linux too. I need to set up a Linux subsystem or VM and start testing stuff out!
from polymers.
Related Issues (1)
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from polymers.