Stick Nodes Asset Library

A Rust library for reading, creating, and manipulating Stick Nodes assets.
Currently supports .nodes
(stickfigure) files, with planned support for .stknds
(projects) and .nodemc
(movieclips) in the future.
Version: 2.0.1
Supported Stick Nodes Version: Up to 4.1.0 build 21
Note: This is my first serious Rust library—feedback is welcome!
Features
- 📄 Read and write
.nodes
(stickfigure) files.
- 🛠️ Create and modify stickfigures programmatically.
- 🔜 Future support for
.stknds
(project) and .nodemc
(movieclip) files.
- 🧩 Node management: add, remove, update nodes easily.
- 🧵 Polyfill support.
- 🧹 Automatic handling of node draw indices when modifying stickfigures.
- 🧠 Safe internal handling using
RefCell
and Rc
for node references.
Installation
Add to your Cargo.toml
:
[dependencies]
sticknodes-rs = "2.0.1"
Example Usage
Creating and Modifying a Stickfigure
use sticknodes_rs::{Stickfigure, Node, NodeOptions, DrawOrderIndex, Polyfill, PolyfillOptions, IWillNotAbuseUnlimitedNodes, LibraryError};
use std::rc::Rc;
use std::cell::RefCell;
fn stickfigure_examples() -> Result<(), LibraryError> {
let mut stickfigure = Stickfigure::new();
let node_a_index = stickfigure.add_node(
Node::from_options(NodeOptions::default()),
DrawOrderIndex(0)
)?;
let node_b_index = stickfigure.add_node(
Node::from_options(NodeOptions {
length: 100.0,
local_angle: 90.0,
..Default::default()
}),
node_a_index
)?;
stickfigure.remove_node(node_a_index)?;
if let Some(node) = stickfigure.get_node(DrawOrderIndex(1)) {
node.borrow_mut().is_static = true;
}
let _children = stickfigure.get_children(DrawOrderIndex(0));
let _long_nodes = stickfigure.get_nodes_with_property(|node| node.borrow().length > 100.0);
let polyfill_index = stickfigure.add_polyfill(
Polyfill::from_options(PolyfillOptions {
anchor_node_draw_index: DrawOrderIndex(1),
..Default::default()
}, stickfigure.clone())?
);
if let Some(polyfill) = stickfigure.get_polyfill(polyfill_index) {
polyfill.borrow_mut().set_attached_node_draw_indices(vec![DrawOrderIndex(0)], stickfigure.clone())?;
}
stickfigure.remove_polyfill(polyfill_index)?;
stickfigure.set_is_node_limit_enabled(false, IWillNotAbuseUnlimitedNodes(true));
Ok(())
}
Reading and Writing Stickfigure Files
use sticknodes_rs::{Stickfigure, LibraryError};
use std::fs::File;
use std::io::{Read, Write};
fn read_write_stickfigure_examples() -> Result<(), LibraryError> {
let mut file = File::open("stickfigure_to_read.nodes")
.map_err(|err| LibraryError::AnyString(format!("Error: {err}")))?;
let mut buffer = Vec::new();
file.read_to_end(&mut buffer)
.map_err(|err| LibraryError::AnyString(format!("Error: {err}")))?;
let mut slice = buffer.as_slice();
let stickfigure = Stickfigure::from_bytes(&mut slice)?;
let bytes = stickfigure.to_bytes()?;
let mut output_file = File::create_new("stickfigure_to_write.nodes")
.map_err(|err| LibraryError::AnyString(format!("Error: {err}")))?;
output_file.write_all(&bytes)
.map_err(|err| LibraryError::AnyString(format!("Error: {err}")))?;
Ok(())
}
Planned Features
- ✅ Support .nodes stickfigure files (Done)
- 🔜 Read/write .stknds project files
- 🔜 Read/write .nodemc movieclip files
- 🧹 Further API ergonomics improvements
- 📄 More documentation and examples
Feedback
Since this is my first major Rust project, feedback and suggestions are very much appreciated!
Feel free to open issues, pull requests, or just share thoughts if you have any ideas to improve the library.
License
This project is licensed under the MIT License.