🚀 Overview
Nebble v1.1.0 brings significant architectural improvements and new features focused on developer experience and code safety. This release introduces managed sprite handles with automatic memory management, migrates examples to separate repositories, includes CLI integration directly into the main package, and adds full support for Pebble SDK 4.9.127 including the new Pebble Round 2 (Gabbro) platform. High-level API improvements make Pebble development in Nim more idiomatic and pointer-free.
✨ New Features
1. Sprite Sheet Support with Managed Handles
Zero-copy sprite management with two API options to suit different needs:
Managed API (Safe - Recommended)
Automatic memory management via ARC. No manual cleanup needed.
import nebble/graphics/graphics
# Create managed handle - bitmap owned automatically
var sheet = newSpriteSheetHandle(RESOURCE_ID_SPRITES, 32, 32)
var player = newAnimatedSpriteHandle(sheet, numFrames=8, frameDelay=100)
# Use in your app
if player.update(elapsedMs):
layer.markDirty()
player.draw(ctx, playerPos)
# Both destroyed automatically when out of scope - no leaks!Features:
SpriteSheetHandle: ARC-managed sprite sheets with automatic bitmap lifecycleAnimatedSpriteHandle: Safe animation state managementAnimationMode: Loop, Once, and Ping-Pong playback modes- Zero-copy drawing using sub-bitmaps
- Elapsed-time based animation (no
getTime()dependency)
Raw API (Advanced - Zero Overhead)
For maximum performance when you need control.
# User owns and manages all lifetimes
var bitmap = newBitmap(RESOURCE_ID_SPRITES)
var sheet = newSpriteSheet(bitmap, 32, 32) # Stack value
var player = newAnimatedSprite(sheet.addr, 8, 100)
// Manual cleanup required
destroy(bitmap)2. CLI Integration in Main Package
The nebble CLI tool is now built from the main package rather than being a separate component. This simplifies installation and ensures version consistency.
Changes:
- CLI source moved to
tools/nebble.nim - Built automatically with
nimble build - Binary output:
bin/tools/nebble
3. FixedString API Improvements
Enhanced FixedString type for heap-free string operations:
- Better API consistency
- Improved error handling
- Zero heap fragmentation guarantee
3.5. High-Level API Improvements
Simplified pointer-free APIs for common operations:
Time API:
getLocalTime()- Returnsptr tmwithout pointer handling. Replaces the patternvar now = time(nil); let t = localtime(addr now).
Graphics API:
DrawCommandImageHandle- ARC-managed handle for PDC vector images. Eliminates manualdestroy()calls and pointer management.
Accelerometer API:
accel.peek()- Value-returning overload returningtuple[data: AccelData; ok: bool]. Provides alternative to pointer-based API without breaking existing code.
Scroll Layer API:
setClickConfigOntoWindow(window: WindowHandle)- Overload accepting managedWindowHandledirectly instead of requiring.toPtrconversion.
These improvements follow the design principle: only remove ptr requirements if it doesn't add burden to the user or reduce safety. All changes are backward-compatible; pointer-based APIs remain available.
4. Examples Repository Migration
All 13 examples have been moved to a separate repository to reduce package size and installation times.
Migration Guide:
# Old (v1.0.0):
cd nebble/examples/hello_world
# New (v1.1.0):
git clone https://github.com/Brokezawa/nebble-examples
cd nebble-examples/hello_worldWhy this change?
- Reduces nebble package size by ~60%
- Faster nimble installation
- Examples can evolve independently
- Better organization
5. Pebble SDK 4.9.127 Support
Updated FFI bindings to support Pebble SDK 4.9.127 with the following improvements:
New Platform Support:
- Gabbro - Pebble Round 2 (260x260 color round display)
- Full platform parity: aplite, basalt, chalk, diorite, emery, flint, gabbro
SDK Improvements:
- Updated to GCC 14 toolchain
- Python 3 support for SDK scripts
- WAF build system 2.1.4
- BDF and PBF font support
- 1% battery reporting granularity on new platforms
- Increased
MAX_FONT_GLYPH_SIZEto 512 for Emery and Gabbro
📦 Installation
nimble install nebble@1.1.0🔄 Breaking Changes
-
CLI Path Change: The CLI binary is now at
bin/tools/nebbleinstead ofbin/nebble -
Examples Removed: The
examples/directory is no longer included in the package. Clone the separatenebble-examplesrepository for sample projects. -
Test Updates:
nimble testnow uses CLI templates (hello_world,simple_watchface) instead of example projects. -
Sprite API: The original sprite API (if you were using it from a pre-release) has been restructured with managed handles as the primary interface.
🧪 Testing
This release includes comprehensive testing:
- Unit Tests: 41 tests for macro utilities
- Sprite Tests: Tests for both managed and raw APIs
- Integration Tests: All 14 platform builds verified (7 platforms × 2 templates)
- CI Matrix: Ubuntu, macOS, and Windows
Supported Platforms:
- aplite - Pebble Classic (B&W, 144×168)
- basalt - Pebble Time (color, 144×168)
- chalk - Pebble Time Round (color, 180×180, round)
- diorite - Pebble 2 (B&W, 144×168)
- emery - Pebble Time 2 (color, 200×228)
- flint - Pebble 2 Duo (B&W, 144×168)
- gabbro - Pebble Round 2 (color, 260×260, round)
Run tests locally:
nimble test # Full test suite
nimble testUnit # Unit tests only
nimble testExample # Integration tests
nimble testSize # Binary size checks📋 Full Changelog
Added
src/nebble/graphics/sprite.nim- Sprite sheet module with dual API (managed + raw)SpriteSheetHandle- ARC-managed sprite sheet handleAnimatedSpriteHandle- ARC-managed animation handlesrc/nebble/ui/content_indicator.nim- Content Indicator API for scroll arrowsContentIndicatorHandle- ARC-managed handle for scroll indicators- High-level helpers:
setupConfig(),configure(),showUp/Down(),hideUp/Down() ScrollLayer.addChild()- Properly add children to scroll contentScrollLayer.getContentIndicator()- Get indicator for scroll layertests/test_sprite.nim- Comprehensive tests for sprite functionality- Cross-platform temp directory support using
getTempDir() - Multi-OS CI testing matrix (Ubuntu, macOS, Windows)
- Pebble SDK 4.9.127 Support - Updated FFI bindings for latest SDK
- Gabbro Platform Support - Pebble Round 2 (260×260 round display)
- Flint Platform Support - Pebble 2 Duo (completes all 7 platforms)
- Platform detection templates:
isGabbro,isHighResRound,pblIfRoundOrHighResElse - Updated
ActionBarWidthandStatusBarLayerHeightconstants for all platforms - High-Level API Improvements:
getLocalTime()- Value-returning time function (pointer-free alternative)DrawCommandImageHandle- ARC-managed PDC image handle with automatic cleanupaccel.peek()overload - Value-returning accelerometer data (returnstuple[data: AccelData; ok: bool])setClickConfigOntoWindow(window: WindowHandle)- Overload accepting managed handles (alternative to.toPtrpattern)
Changed
- CLI Integration: Merged CLI into main package (
tools/nebble.nim) - FixedString API: Improved heap-free string operations
- Version: Bumped to 1.1.0
- Test Infrastructure: Uses CLI templates instead of example projects
- CI Workflow: Tests on multiple operating systems
- Documentation: Updated ROADMAP with clear release schedule
Removed
examples/directory (moved to separate repository)- Hardcoded
/tmp/paths (now usesgetTempDir())
Fixed
- Declarative DSL Parent Validation: Fixed
isParentValidlogic to properly handle parent layer validation - textAlignment Property: Fixed DSL support for text layer alignment property
- ScrollLayer.addChild(): Fixed to properly set parent tracking to prevent double-free
- ContentIndicator.timesOut: Fixed default from
falsetotrueto match Pebble SDK standard - Cross-platform compatibility for test temp directories
- Windows support improvements
- Path handling in nimble tasks
- package.json Restoration: Restore
package.jsonon build failure to prevent configuration loss (13b35d0) - Action Bar Icon Bitmap Ownership: Action bar DSL now manages icon bitmaps to prevent memory leaks (
e9a1c55) - Code Quality: Fixed lifetime safety issues, removed unused imports, and corrected tests (
be09b2b) - Buffer Overflow & Platform Normalization: Fixed UUID
toStringbuffer overflow (assertion) and CLI platformtoLowerAsciinormalization (dfe744e) - AUDIT.md Findings A-01–A-06: Fixed PNG bitmap size parameter, AppSync zero-buffer guard,
sendChecked*templates, test stub ownership tracking, and renamednebbleExit(e51da75)
🔒 Stability & Security Fixes
The following post-release fixes have been applied to v1.1.0:
- package.json Restoration (
13b35d0): Restorepackage.jsonon build failure to prevent configuration loss when a build error occurs mid-run. - Action Bar Icon Bitmap Ownership (
e9a1c55): The action bar DSL now manages the lifecycle of icon bitmaps, preventing memory leaks when icons are set declaratively. - Code Quality (
be09b2b): Fixed lifetime safety issues, removed unused imports, and corrected test stubs for correct behaviour under ARC. - Buffer Overflow & Platform Normalization (
dfe744e): Fixed a buffer overflow in UUIDtoString(now guarded by assertion) and corrected CLI platform name normalization to usetoLowerAscii. - AUDIT.md Findings A-01–A-06 (
e51da75): Resolved all six outstanding audit findings — PNG bitmap size parameter, AppSync zero-buffer guard,sendChecked*template safety, test stub ownership tracking, and thenebbleExitrename.
🗺️ Roadmap
v1.2.0 - Developer Experience (Planned)
2.1 Menu DSL
Goal: Declarative macro-based menu definition hiding pointer arithmetic.
Highlights:
- Declarative menu definition (nebbleApp-style consistency)
- Automatic static array generation with correct sizes
- Icon support for each menu item and section headers
- Callback binding without manual
addroperations
API sketch:
nebbleApp:
menu:
section "Main Menu":
item "Start", icon = ICON_PLAY, callback = onStart
item "Settings", icon = ICON_SETTINGS, callback = onSettings2.2 AppMessage Serialization
Goal: Macro-driven object mapping with automatic versioning for AppMessage payloads.
Highlights:
- Compile-time generation of serialize/deserialize code
- Support primitives, FixedString, and nested objects
- Automatic schema versioning (backward compatibility)
- Zero runtime overhead (all code generated at compile time)
API sketch:
type
MyMessage* {.version: 1.} = object
command*: uint8
value*: int32
name*: FixedString[32]2.3 Worker Binary Support
Goal: Enable background worker binaries for persistent background tasks.
Highlights:
- Worker binary scaffolding (
nebbleWorkermacro) - Worker-specific event loop and message passing APIs
- Tick timer service and persistent storage access from worker context
- CLI integration for creating/building worker binaries
CLI:
nebble new my_worker --worker
nebble build --workerv1.3.0 - Advanced Features (Planned)
3.1 Framebuffer Access
Goal: Safe iterator for direct pixel manipulation.
Highlights:
- Safe wrapper around framebuffer pointer
- Bounds-checked pixel access and iterator for region operations
- Automatic context lock/unlock
3.2 Animation DSL
Goal: Fluent builders and declarative sequences for complex animations.
Highlights:
- Sequential and parallel composition, easing, callbacks
- Compile-time parsing and generated PropertyAnimation setup
Known Limitations
- No Garbage Collection: Cycle collection is disabled; manual management of reference cycles is required.
- Callbacks: All handlers must be
{.cdecl.}global procedures. - Stdlib: Only non-syscall modules are supported in device code.
📝 Commit History
This release includes the following commits:
24588de- fix: add PBL_DISPLAY_WIDTH/HEIGHT constants for Gabbro platform78eaa4e- ci: install dev dependencies in CI before install46822cc- chore: move dev deps to dev: (unittest2, futhark)b38af60- Fix: center templates & platform font adjustmentsf01fac1- docs: Updated READMEcf5fe91- Remove tracked build artifact src/nebble.out and ignore itab85a2b- docs: Fix documentation issues and remove tracked binary001e421- docs: Add GitHub Pages deployment with guide conversion3e96f55- fix: Skip testSize on macOS when ARM toolchain unavailable5ccc00f- fix: Make arm-none-eabi-size verification optionalef74806- fix: Make ARM toolchain detection more robust for macOSfe59991- fix: Explicitly set PATH in pebble SDK steps for macOS10454ec- fix: Use explicit Python 3.13 path for macOS pebble-toolb356996- fix: Add macOS Python bin path to CI PATH for pebble-toolb45356c- chore: Remove futhark from runtime dependencies and update Nim CI versione7a130a- chore: Remove audit document and untrack release notesaa57763- perf: Cache sub-bitmap in SpriteSheetHandle to reduce per-frame allocations73c2d32- docs: Update CHANGELOG and release notes with post-release stability fixese51da75- Fix AUDIT.md findings (A-01 through A-06)dfe744e- Fix buffer overflow and platform normalization issuesbe09b2b- Fix code quality issues: lifetime safety, unused imports, and testse9a1c55- fix: Action bar DSL manages icon bitmaps to prevent memory leaks13b35d0- fix: Restore package.json on build failure to prevent config loss9097c30- docs: Add comprehensive CHANGELOG.md8debb98- build: Rebuild CLI binary and test artifactscb52209- ffi: Regenerate FFI bindings for Pebble SDK 4.9.12734aed08- build: Update build configuration and utilities for v1.1.02c6a535- docs: Update documentation for v1.1.0 release8203e98- refactor: Update CLI to use package.json instead of nebble.json03df498- feat: Add high-level API improvements for v1.1.0f87fa85- feat: Add Gabbro (Pebble Round 2) platform supportb3cc8d9- docs: Update configuration references from nebble.json to package.jsond77ff49- feat: add font resource scanning; UI improvements and lifetime fixes3c93508- docs: Add new commits to release notesc813578- docs: Update release notes with ContentIndicator API changes2faf385- feat: Add ContentIndicator API and fix DSL parent validation8a2d88b- Release v1.1.0: Sprite Sheets with Managed Handles and Examples Migration9e39532- feat: migrate examples to separate repository (v1.1.0)006460c- refactor: merge CLI into main package and improve FixedString APIa63ef70- Merge pull request #2 from clach04/patch-117c0fa2- Add 'Nim Everywhere' feature to README
👏 Contributors
Thanks to everyone who contributed to this release!
- Brokezawa (maintainer)
- Community contributors
📄 License
MIT License - See LICENSE file for details.