Thank you for your interest in contributing to Object Builder! This guide will help you get started.
Before opening an issue, please check if a similar issue already exists.
When reporting a bug, include:
- Steps to reproduce — What you did to trigger the bug
- Expected behavior — What you expected to happen
- Actual behavior — What actually happened
- Environment — OS, app version, client version being edited
- Log file — Attach the log file from
Help > Open Log Fileor the Log panel - Screenshots — If the bug is visual, include a screenshot
Open an issue with the enhancement label. Describe:
- The problem you're trying to solve
- Your proposed solution
- Alternatives you've considered
# Fork and clone the repository
git clone https://github.com/<your-username>/object-builder.git
cd object-builder/electron
# Install dependencies
npm install
# Start development mode
npm run devSee DEVELOPMENT.md for architecture details and conventions.
- Strict mode is enabled. Avoid
anyunless absolutely necessary. - Use functional style: pure functions with module-level state instead of classes.
- Export types and interfaces alongside their implementation.
The project uses Prettier with the following settings:
- No semicolons
- Single quotes
- No trailing commas
- 100 character line width
# Format code
npm run format
# Check formatting
npm run format:checkESLint is configured with TypeScript and React Hooks rules.
npm run lint
npm run lint:fix| Element | Convention | Example |
|---|---|---|
| Files | kebab-case | sprite-panel.tsx, dat-reader.ts |
| Components | PascalCase | SpritePanel, ThingListPanel |
| Functions | camelCase | readDat(), buildSpriteSheet() |
| Constants | UPPER_SNAKE_CASE | SPRITE_DEFAULT_SIZE, MENU_FILE_NEW |
| Types/Interfaces | PascalCase | ThingType, ClientFeatures |
| IPC channels | domain:action | file:readBinary, project:load |
- Every
.tsxfile must haveimport React from 'react'at the top (see DEVELOPMENT.md for why) - Use
useTranslation()for all user-visible strings — no hardcoded text - Use semantic color tokens (
bg-bg-primary,text-text-secondary) — no hardcoded hex in styles - Colocate tests in
__tests__/directories next to source files
Write clear, concise commit messages:
feat: add sprite batch export dialog
fix: correct OTB escape character handling for 0xFD bytes
refactor: extract sprite composition into separate module
test: add round-trip tests for OBD v3 format
docs: update DEVELOPMENT.md with worker architecture
Use conventional prefixes:
feat:for new featuresfix:for bug fixesrefactor:for code changes that don't add features or fix bugstest:for test additions or changesdocs:for documentation changeschore:for build, CI, or dependency changes
-
Create a branch from
main:git checkout -b feat/my-feature
-
Write tests for new functionality:
npm run test -
Ensure all checks pass:
npm run typecheck npm run lint npm run format:check npm run test -
Keep commits focused — one logical change per commit.
Include:
- Summary of what the PR does
- Test plan describing how the changes were verified
- Screenshots for UI changes
- PRs require at least one review before merging
- CI must pass (typecheck, lint, tests)
- Keep PRs small and focused when possible
- Add a test that reproduces the bug (should fail before the fix)
- Verify the test passes after the fix
- Add unit tests for new functions and services
- Add component tests for new UI components
- Add E2E tests for new user-facing flows (when applicable)
# Unit and component tests
npm run test
# E2E tests (requires build)
npm run test:e2e:buildWhen adding or modifying user-visible text:
-
Add the translation key to all 3 locale files:
src/renderer/src/i18n/locales/en_US.json(required)src/renderer/src/i18n/locales/es_ES.json(required)src/renderer/src/i18n/locales/pt_BR.json(required)
-
Use the
t()function fromuseTranslation()to reference the key.
If you're not confident in a translation, add the English text and mark it with a comment in the PR — someone else can improve it.
If you're unsure about anything, open a discussion or ask in the PR. We're happy to help!