amethyst / amethyst Goto Github PK
View Code? Open in Web Editor NEWData-oriented and data-driven game engine written in Rust
Home Page: https://amethyst.rs/
License: Other
Data-oriented and data-driven game engine written in Rust
Home Page: https://amethyst.rs/
License: Other
We need a way to handle events in a generic way. This also has to be expandable, meaning users can add their own events as they see fit without having to recompile the base of the engine.
The expandable requirement means we can't just have a Vec<Event>
where Event
is an enum. This is because the enum has to be defined somewhere in amethyst
which means the users can't define their own types.
This will also have to work with specs
meaning that system can write events for other systems to pick up. This needs to be sequenced correctly so that downstream systems get the all the events they are expected.
A good example is that button presses could be abstracted away from the intent. Think of it like a RTS ui, there is always shortcuts on the keyboard and GUI elements for the beginners. This also allows for mobile development, as most devices have zero buttons and it is all just figure taps.
Now that the state machine has been stabilized, unit tests need to be written to ensure the interface works correctly.
As mentioned in the Pull Requests section of the CONTRIBUTING.md file in checklist item 4, unit tests are at the bottom of the same source file under a module called test
with the comment // Unit tests
right above it.
For a conforming example, see the unit tests in src/engine/src/timing.rs.
/book/intro.html on amethyst.rs links to /doc/amethyst/ (404) when it should probably link to /doc/master/amethyst/ in this sentence:
Read the crate-level API documentation for more details.
With the newly introduced concept of RFCs (requests for comments), we should add it as a tag type under the "Submitting Issues" section of CONTRIBUTING.md.
Under item 3, we should add in the following description (if you have a more satisfactory one-liner description for RFCs, please post it below):
Another thing we need to discuss is whether the "RFC", "feature", and "improvement" tags overlap.
This should be part of the engine. Probably just a way to configure glutin
from a config file. This ties in the renderer and the event system.
Hi, I am concerned about the usage of mutex's and Arc's throughout the framework. There are also a lot of allocations (Box) that I can't remove (as a library user, I can since I'm also interested in submitting PR's to this project). Building a good framework that's easy to use is great, but can this data processing be done without explicit locks and mutexes?
https://github.com/amethyst/amethyst/search?utf8=%E2%9C%93&q=mutex
https://github.com/amethyst/amethyst/search?utf8=%E2%9C%93&q=arc
https://github.com/amethyst/amethyst/search?utf8=%E2%9C%93&q=box
I'm new to rust, and from a C++ background this surprises me. Game developers in general have avoided the STL for years for it's "slowness" (can't control allocations) so I doubt they wouldn't think twice about avoiding a framework that does allocations and locking out of their control.
I'm wondering about the future direction of amethyst, specifically if removing these arcs, mutexes, and Box allocations will ever be a priority. I understand why they are used (or, atleast I think I do) and it's to allow communicating between threads, the shared data. It's a tradeoff that favors data parallelism over single-threaded performance. My point here is there are other trade-offs a developer can make when making a game or library.
One example would be ordering the processors manually so that none of the data is modified, but instead state changes are collected at the end of the frame, and processed all at once by a single thread. That strategy has different trade-offs than the current design of amethyst follows.
So my question is this, is amethyst going to consider this a serious issue in the future? I would love to help in this area, but the design seems to be growing in so many directions at the moment, that pinning these details down (you'll notice a general trend in issues I have been filing.. #88) seems intimidating.
Some reinforcement from the community on whether or not these issues make sense to tackle, and HOW to appropriately tackle them, would be greatly motivating. I really like the design of amethyst, I just don't want to see it ignored by those who want absolute control over the performance (I would really like to be able to do this).
Anyway, thanks for reading.
Though the main priority right now is to stabilize the entity-component-system API first (issue #10), we can finish designing the parallel renderer, with the internal restructuring of the engine into modular crates (issue #13).
As described on the relevant design document on the wiki, our aims are high throughput, data-driven design, optimization for next-gen APIs, demo recording and real-time playback, and network transparency, i.e. for tool slaving).
Please take a look at the drafted renderer design for reference. Feedback is welcome!
Progress will be worked on in the renderer branch.
I'd love to explore the Pong guide, but the chapter appears to be missing. 😄
With PR #67, there is no way to access the world, which would have made it possible to add resources, Systems
and the native functions of a World
. This needs to be fixed in some way.
Currently, Broadcaster
only provides some sugar for World
.
The CHANGELOG.md file in this repository is not very well organized nor properly maintained. We should adopt a style similar to Keep A Changelog, which seems much cleaner.
This issue is a dependency of the tools repository restructuring effort (issue #13), and a counterpart to amethyst/tools#5.
Progress is still being done on the reorg branch.
Now that I own an HTC Vive, I've been looking for a suitable open source engine to hack some demos in. I explored Rust quite a bit a year ago, and then fell off. Now that I see everything really maturing more, I'd like to dive back in. I saw this project and love the inspiration. I was hacking my own engine, but would perhaps like to start contributing to this instead. Know all of this, I know it is still very early to start thinking about such a feature, but it would be great to add in support for OpenVR.
I'd be willing to hack on that when the time is right, if that's even in the scope of this engine.
Thoughts?
Proposed specs:
YAML || values || default
---
logging:
file_path: "new_project.log" || string; || "log.log"
output_level: warn || [no, error, warn, info, debug, trace] || debug
logging_level: debug || [no, error, warn, info, debug, trace] || debug
display:
brightness: 1.0 || 0.0 to 1.0 || 1.0
fullscreen: false || bool || false
size: [1024, 768] || array of two ints || [1024; 768]
title: "My coolest game" || string || "Amethyst game"
Main config.yml
may not include certain configuration secions if they are being mantained separatedly, for example being mantained by a shard.
If a section of a config is missing like display
in this example:
logging:
file_path: "new_project.log"
output_level: warn
logging_level: debug
title: "My coolest game"
Amethyst will look for display.yml
to evaluate missing properties.
If the file display.yaml does not exist, default properties are added to config.yaml.
If display.yaml exists, but properties are missing, missing properties are added to display.yaml.
A file should not contain a name of a section, as it is taken from a filename.
For display.yml
:
brightness: 1.0
fullscreen: false
size: [1024, 768]
Each Amethyst game project can contain several 'shards', which are essentialy Amethyst fucnctionality packages with code and/or resources.
Examples of such shards can be:
Shards can be connected together in the core amethyst_engine
crate to have additional functionality such as
Following tasks are considered completed when discussed and implemented. If the team comes to a conclussion on a task, it is marked in a certain way:
Part 1: Features
Technically, adding shards to projects will be done through 'features' -
conditional compilation supported by Rust and Cargo. Thus, adding, for example 'ecs' shard will result in adding 'ecs' feature to Cargo.toml of a project. Feature ecs
will enable ecs crate in amethyst_engine
.
Some features, as mentioned above, can be glued together in amethyst_engine
crate using combinned features (i.e. cfg(all(ecs, renderer))
).
Some shards may not be included in base amethyst_engine
crate and CLI will need to inject an additional dependency, when ading such a shard.
amethyst add <name>
amethyst remove <name>
Alternatives:
amethyst shard add <name>
amethyst shard remove <name>
tools
crate Part 2: Shards' resources
Each shard may bring its own resources, and/or configuration files, and/or modify existing. I have no idea of this part. It should be thouroughfully discussed and, maybe, even separated to its own RFC.
Hi
I am getting exceptions on installing Amethetyst on Windows 10 Anneversary edition
PS C:\WINDOWS\system32> cargo install amethyst_tools
Updating registry `https://github.com/rust-lang/crates.io-index`
Compiling strsim v0.4.1
Compiling winapi v0.2.8
Compiling ansi_term v0.7.5
Compiling libc v0.2.16
Compiling vec_map v0.4.0
Compiling bitflags v0.3.3
Compiling podio v0.1.5
Compiling gcc v0.3.35
Compiling winapi-build v0.1.1
Compiling clap v1.5.5
Compiling kernel32-sys v0.2.2
Compiling miniz-sys v0.1.7
Build failed, waiting for other jobs to finish...
error: failed to compile `amethyst_tools v0.4.0`, intermediate artifacts can be found at `C:\Users\rsharan\AppData\Local
\Temp\cargo-install.K6JLIFDEBzsc`
Caused by:
failed to run custom build command for `miniz-sys v0.1.7`
process didn't exit successfully: `C:\Users\rsharan\AppData\Local\Temp\cargo-install.K6JLIFDEBzsc\release\build\miniz-sy
s-60c8d67696f63a43\build-script-build` (exit code: 101)
--- stdout
TARGET = Some("x86_64-pc-windows-gnu")
OPT_LEVEL = Some("3")
PROFILE = Some("release")
TARGET = Some("x86_64-pc-windows-gnu")
debug=false opt-level=3
HOST = Some("x86_64-pc-windows-gnu")
TARGET = Some("x86_64-pc-windows-gnu")
TARGET = Some("x86_64-pc-windows-gnu")
HOST = Some("x86_64-pc-windows-gnu")
CC_x86_64-pc-windows-gnu = None
CC_x86_64_pc_windows_gnu = None
HOST_CC = None
CC = None
TARGET = Some("x86_64-pc-windows-gnu")
HOST = Some("x86_64-pc-windows-gnu")
CFLAGS_x86_64-pc-windows-gnu = None
CFLAGS_x86_64_pc_windows_gnu = None
HOST_CFLAGS = None
CFLAGS = None
running: "gcc.exe" "-O3" "-ffunction-sections" "-fdata-sections" "-m64" "-o" "C:\\Users\\rsharan\\AppData\\Local\\Temp\\
cargo-install.K6JLIFDEBzsc\\release\\build\\miniz-sys-60c8d67696f63a43\\out\\miniz.o" "-c" "miniz.c"
cargo:warning=miniz.c:2936:29: fatal error: sys/utime.h: No such file or directory
cargo:warning= #include <sys/utime.h>
cargo:warning= ^
cargo:warning=compilation terminated.
ExitStatus(ExitStatus(1))
command did not execute successfully, got: exit code: 1
--- stderr
thread 'main' panicked at 'explicit panic', C:\Users\rsharan\.cargo\registry\src\github.com-1ecc6299db9ec823\gcc-0.3.35\
src\lib.rs:897
note: Run with `RUST_BACKTRACE=1` for a backtrace.
gcc is in the path and I am using Rust 1.12
PS C:\WINDOWS\system32> gcc
gcc.exe: fatal error: no input files
compilation terminated.
PS C:\WINDOWS\system32> rustc -vV
rustc 1.12.0 (3191fbae9 2016-09-23)
binary: rustc
commit-hash: 3191fbae9da539442351f883bdabcad0d72efcb6
commit-date: 2016-09-23
host: x86_64-pc-windows-gnu
release: 1.12.0
This is a big step, but I think I'm ready to migrate the Amethyst repositories away from my personal account to a GitHub organization. Before I do this, I need to confirm the following matters:
Here's the current status of these questions, as gathered from our collective discussion both on this issue and on Gitter:
master
on this repo to "future-proof" these links before taking down https://ebkalderon.github.io/amethyst.general
channel + 1 channel for each repository. I personally want documentation to be a separate room since it crosses repository boundaries. How does this room layout look to you guys?
I believe that in CONTRIBUTING.md, we should add under Pull Requests some conditions that make sure people's pull requests also update CHANGELOG.md to some degree so it doesn't have to be done manually.
What those conditions should be is up for discussion. Personally, I believe that we should look towards Semantic Versioning for ideas: if you fix a known bug, introduce new functionality, overhaul an existing feature, or produce a breaking change, you should document it appropriately in the change log.
See issue #17 from a while back for more information about the CHANGELOG.md format we use.
as you may know rust libraries are mostly dual-licensed in apache-MIT
The Apache license has protections from patent trolls and an explicit contribution licensing clause.
And the MIT is for GPLv2 compatibility (because Apache is not compatible with GPLv2)
here a message from a crate.io bot for explanation of how to set dual-license in your project.
feel free to close it if your intension is to keep MIT alone.
Anyway great project, keep going :-)
As a new Rust user, this is the first time I ran into an unstable feature. This lead me to reading about the feature-gating system, distribution channels, and multirust, which was enlightening, but sidetracked me from the tutorial.
Anyway, I think it would be helpful to new users like myself to add a note about distribution channels in the tutorial in case they encounter an error in hello_world like I did:
error: use of unstable library feature 'drain': recently added, matches RFC (see issue #27711)
I see in #3 that this problem might go away by itself, but this is still worth considering in the meantime.
There is a need for a logging system, to uniformly handle errors/provide meaningful debug messages for the user. Currently errors are reported using println!
s and panic!
s.
Probably an instance of Logger
should be inside of the Context
struct (or it should be a resource in the World
as suggested in #125), so it is available globally.
Due to recent changes in how extern crate
visibility works (rust-lang/rust#26775), it looks like master
no longer compiles successfully on rustc >1.11. I can package up a hotfix release to remedy this issue. What do you all think?
EDIT: I was wrong, Amethyst no longer builds on beta and nightly versions of rustc, not stable. I've updated the issue to reflect this.
We should be able to construct prefabs from YAML files (*.yml) stored in the resources/prefabs
directory. Files can be nested arbitrarily in subfolders for organizational purposes, if the user wants. The markup format should be identical to that of entities:
---
component1:
field1: true
field2: 'value'
field3: [1.0, 2.1]
component2:
field1:
- thing1
- thing2
- thing3
The string name of the prefab is the filename minus the .yml
extension. The user should be able to create entities deriving from such prefabs in Rust code. However, this should also be doable from within YAML as well, following the format below:
extends: name_of_prefab
---
component3:
field1: [0.1, 2.6]
This is a pretty important but complicated feature. We need a way for some Pass
to build list of new targets that are needed. The use-case that comes to mind is support for shadow passes. This involves looking at the list of lights, checking which ones request a shadow buffer be generated and which ones are visible. The Renderer
should then create shadow buffer targets for each light that passed this test and render the scene as required into them before the Pass
is run.
This is a pretty complex feature and I doubt we are ready to tackle it yet with the current Renderer
it's far to simple. But understanding how to build this solution should highlight all the missing blocks and driver the Renderer
in the correct direction.
This issue is to keep track of all the systems that will need to be implemented for amethyst engine.
Feel free to leave a comment and/or create a PR. Let us know if you are working on one by leaving a comment.
Navigating directly into the src/renderer/
directory and calling cargo test
works fine, but for whatever reason, staying in the top-level directory of the repository and calling cargo test -p amethyst_renderer
or cargo local-pkgs test
fails from Cargo not finding the genmesh
crate.
The following APIs need to be stabilized for Amethyst to build properly in stable Rust:
Also, Amethyst uses the unstable benchmark tests feature. A possible solution could be to switch them off when compiling with stable.
A transform system is a pretty common way to handle the scene graph. Basically it takes a Local Transform
and a Parent
entity and calculates the Global Transform
. This allows objects that are attacked to the parent entity to follow
it around. An object without a parent global transform is it's local transform, but it is stored as a separate value.
The Parent systems might be ok to handle separately as they can be used to do neat things like handle deletes in a clean way. Deleting the parent entity should delete all child entities.
Creating a game engine is a huge effort. Your goals for rendering seem to perfectly match GFX domain:
Renderer optimized for modern graphics APIs, e.g. Vulkan, Direct3D 12+, Metal.
I suppose, if you go this way and succeed, you will end up with your own cross-API rendering library. But then - why not put a fraction of this effort into GFX itself, so that we can benefit greatly from cooperation?
If you continue doing your own thing, this issue may at least contain the reasoning (or a discussion) for such a decision, and this kind of feedback is much appreciated.
Currently in order to access renderer user has to write code like this:
let mut context = self.context.borrow_mut();
match context.video_context {
VideoContext::OpenGL { ref window,
ref mut renderer,
ref frame,
ref mut device,
.. } => {
renderer.submit(frame, device);
window.swap_buffers().unwrap();
}
#[cfg(windows)]
VideoContext::Direct3D { } => {
// Direct3D code
},
VideoContext::Null => (),
}
It would make sense to add a renderer frontend, that would own VideoContext
and deal with all this boilerplate internally.
Also platform independent amethyst_renderer::Fragment
and amethyst_renderer::Scene
would be required, since they take gfx::Resource
type parameter, related to #52.
It should simplify implementation of the rendering system.
As of version 0.3.12 of the rand
crate no longer compiles properly on nightly Rust 1.7.0. This prevents mdbook
from compiling, meaning that Travis CI does not generate the book pages when it pushes to the gh-pages branch.
This leaves the Amethyst book website empty when the user visits https://ebkalderon.github.io/amethyst/. The crate API reference is unaffected.
This appears to be a known regression on rust-random/rand#91.
Need a simple 3d rendering example, like a cube or sphere, nothing fancy. Deferred or Forward defined in yaml file.
I enjoy reading through the Rust standard library documentation, and I want our documentation experience to be of similarly high quality. Some things to think about:
If you have more ideas on how to make Amethyst's generated documentation great, leave your thoughts below and I'll update this list later on.
A simple pass that renders the scene into a depth buffer leaving the other frame attachments unaffected. This can improve performance in some pipelines so it is worth having it as an optional pass.
The renderer needs to have a more robust resource handle design for it to be maintainable. The current situation with state_static
, state_dynamic
, and types
is untenable in the long term. Perhaps a trait-based system for resources (a la gfx-rs) would help here.
This issue will track the progress of this feature's development. It must be completed before 0.2.0 "Explosive Cleric" reaches Crates.io!
With game state management mostly stable, the next step is to implement an entity-component-system framework in the engine. This framework must follow the pure ECS model, in which entities are just IDs and components are POD structs.
Though the ECS model is extremely flexible and easy to data-drive, it has its shortcomings:
In a useful Reddit post, tomaka describes an alternative model similar to MVC with some parallelism. I propose a combination of the two designs resulting in a thread-safe ECS.
(Quoted from the other announcements section in TWIA Issue 1)
Clearly, the World struct containing our entities and components is analogous to the model in MVC. But systems typically require mutable state even for strictly read-only operations, so they don’t fit into either views or controllers, nor are they easy to parallelize.
However, there are two possible ways to remedy this issue.
Experiments are ongoing on the ecs branch.
I was wondering whether restructuring the file hierarchy of our crates to be flat rather than nested might be of any benefit. That is, transitioning from our current setup of:
* book/
* examples/
* src/
* config/
* src/
* Cargo.toml
* context/
* src/
* Cargo.toml
* ecs/
* src/
* Cargo.toml
* engine/
* processors/
* renderer/
* src/
* Cargo.toml
* Cargo.toml
over to something like:
* amethyst/
* examples/
* src/
* Cargo.toml
* amethyst_config/
* examples/
* src/
* Cargo.toml
* amethyst_context/
* examples/
* src/
* Cargo.toml
* amethyst_ecs/
* examples/
* src/
* Cargo.toml
* amethyst_renderer/
* examples/
* src/
* Cargo.toml
* book/
cargo build
at the top level is enough to build the whole thing.amethyst/
directory?the Processor
has this only function in the interface:
pub trait Processor {
fn process(&mut self, planner: &mut Planner<()>, dt: Duration);
}
specs
has this trait instead:
pub trait System<C>: Send {
fn run(&mut self, RunArg, C);
}
The benefit of the System
trait is that it's moved around to the target thread, so any data that belongs to an object that implement it doesn't have to be wrapped into Arc<Mutex<T>>
and such.
There are some major changes coming to our core infrastructure. Currently, the overall Amethyst project consists of three repositories: amethyst, amethyst_cli, and amethyst_opengl.
Amethyst is set for future expansion, and the current approach to organizing our code is not maintainable. I propose the following:
This might cause some breakage, but this must be minimized as much as possible, especially in other branches like ecs and gpures. Let's use Piston's approach for managing multiple crates under one repository as prior art.
Progress has begun on the reorg branch.
This is the engine-side counterpart of Amethyst Tools issue #4.
Implementing a function for different back-ends all inline within the function body becomes unmaintainable over time.
Example:
https://github.com/amethyst/amethyst/blob/develop/src/context/src/asset_manager.rs#L118-L139
The different backend implementations should be moved to their own separate module.
Hi,
I've stumbled upon this interesting project(Gamma at https://github.com/kovasb/gamma) that uses datasctructures to represent and compose Shaders, and functions to compose/compile them. There's a StrangeLoop presentation that explains the premise better.
I wonder if amethyst can benefit from a simple graphics model on top of OpenGL.
Thanks
First reported by @Oflor on the Gitter chat on 2016-02-04 @ 12:20PM EST regarding the ecs branch. Reposted here for long-term records:
There's a strange behaviour with Entities struct.
This may be undesired.
Once the engine stabilizes, a new code name will be needed for the 1.0 release. The format is as follows:
Some examples:
Currently, the 0.1.x series is "Uncanny Snow" and 0.2.x is "Explosive Cleric". All development versions before 1.0 will henceforth remain under the code name "Explosive Cleric" to better adhere to the semantic versioning standard (see the Releases page). Each major release will be assigned a code name which will persist until the next breaking API change.
This code name must be determined before the 1.0 release. Suggestions can be posted in the comments below. Get cracking!
There has been a few "sync with latest develop" commits lately. (b17b86e (in open pr #99), 266819c, 266819c, 3da54cd, cac16ba, and probably more)
The main problem here is if one should merge or rebase a pull request. Should we come to a agreement on how to handle "rebasable" upstream changes to a pr, or should we let the coder choose for themselves, i.e merge (aka sync with branch) or rebase (rewind, play changes, fastforward, fix possible conflicts)?
The current event system allows handling of the input events from the window.
It's often more interesting to check the current state of the key pressed/released
for games requiring manual tracking atm (e.g. pong example https://github.com/amethyst/amethyst/blob/develop/examples/04_pong/main.rs#L132-L144).
On the latest master, there is no clean way to shut down the engine's state machine besides std::process::exit()
. There are ideas for proper state management that are only just materializing (TODO: needs more design coverage on the wiki). Update: There is a new article on the wiki covering possible game state machine designs.
This must be fixed and stabilized before version 1.0 is pushed to crates.io! See the rustc
warning message below.
warning: unreachable statement, #[warn(unreachable_code)] on by default
src/engine/app.rs:41 self.shutdown();
^~~~~~~~~~~~~~~~
We should be able to construct entities from YAML files (*.yml) stored in the resources/entities
directory. Files can be nested arbitrarily in subfolders for organizational purposes, if the user wants. The markup format should be as follows:
---
component1:
field1: true
field2: 'value'
field3: [1.0, 2.1]
component2:
field1:
- thing1
- thing2
- thing3
The string name of the entity is the filename minus the .yml
extension. The user should be able to create an instance of such an entity in Rust code.
Currently, the crate dependency map of Amethyst looks like this:
+----------------------------------------------------+
| amethyst |
+----------------------------------------------------+
^ ^ ^
| | |
+--------+--------+ | |
| amethyst_engine | | |
+-----------------+ | |
^ ^ | |
| | | |
| +------------------------+ |
| | | |
| +----------+---+ +---+---+-----------+
+----------| amethyst_ecs | | amethyst_renderer |
+--------------+ +-------------------+
Is there any reason to have the amethyst_engine
crate at all? Can we not push its functionality upward to the amethyst
crate? Doing so would simplify things quite a bit with no difference in functionality (see below).
+------------------------------------+
| amethyst |
+------------------------------------+
^ ^
| |
+-------+------+ +---------+---------+
| amethyst_ecs | | amethyst_renderer |
+--------------+ +-------------------+
It would be nice if we could abstract away the Textures/Vertex Buffers so that the ECS does not need to retain direct links to the data. The asset manager would be responsible to for loading and unloading assets and provide handles to said assets. That way user code never has to touch gfx-rs
unless they are directly working on extending the renderer for their game.
As agreed in #27, we will follow a variation of the Git Flow branching model, essentially what GFX does for releases. To adopt this, we really need to do some housekeeping first. When this issue is resolved, we can also close #27.
ecs
and renderer
branches.develop
based on the newest working master
. This will be our main development branch that we make pull requests against.release-0.3
from master
, sign off new release and push to Crates.io. Hotfixes should be applied on top of here.What should we do about the existing branches? Are we okay with merging them as-is, cherry-picking for breakage?
Looking up resources by a string is convenient but slow thanks to dynamic allocation. I believe this is why OpenGL uses integer handles, even if it they are less convenient to work with.
These string should be replaced with type-safe integer wrappers, or some other design to improve the performance of the asset manager.
https://github.com/amethyst/amethyst/blob/develop/src/context/src/asset_manager.rs#L41-L42
Consideration must be given to the current convenience though, especially if it is removed.
Maybe offering both versions make sense? What does everyone think?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.