Skip to content

Repository files navigation

A real-time interactive simulation of the solar system.

Code coverage Build status Version

Development

Quick start
  1. Clone this repo:
git clone https://github.com/jshor/tycho.git
  1. Use the right node version:
nvm use
  1. Install dependencies (via Yarn):
yarn
  1. Start:
yarn start
Framework and libraries

This app is written in TypeScript and built using React.js, THREE.js, and zustand for state. It uses react-three-fiber for THREE-based React components, along with its drei helpers. It's bundled using Vite.

Styling

Each DOM component contains a corresponding Sass stylesheet and employs the BEM CSS design pattern. Vite compiles the Sass as part of the build.

Application Architecture

The overall architecture follows a container pattern, split between src/modules and src/components. In a nutshell, modules in this app leverage tasks such as handling state and minor front-end logic, while components simply handle the presentation. Physics calculations and business logic is delegated to services, and some critical components, such as the Camera, have dedicated services.

State management

All shared-state data is stored in the zustand store, which lives in src/store. This includes the 2D and 3D positions of objects and the current time. Modules subscribe to the slices they need and the store is written to through its actions, which keeps the data flowing in one direction. In rare cases, some components will use the local state for things internal to that component, when appropriate.

File structure

This project utilizes a typical React app flat directory structure. Tests for each item typically live in __tests__. Components have corresponding tests and Sass in the same directory. __tests__ folders may contain __fixtures__.

The source is laid out as follows:

Path Contents
src/modules Logical components that hold state and front-end logic
src/components Presentational components with styling
src/utils Functional utilities and helpers, including for math and physics
src/store The Zustand store shared across the app
src/shaders GL fragment and vertex shaders for the scene
src/elements Scene aids, such as the clock, camera controls, and ambience audio
src/constants Tunable values for the scene, the UI, and the tour
src/test Test setup and utilities

Note that 3D React components and DOMElement ones coexist in the same general paths.

Static assets, such as textures, media, and data are stored in the public folder. Some JSON file contents are generated by build scripts.

Running the project

In the project directory, you can run the following commands:

yarn start

Runs the app in the development mode.
Open http://localhost:3000 to view it in the browser.

The page will hot reload if you make edits.

Unit testing

Tests use Vitest and Testing Library, running against jsdom. Shared setup lives in src/test, which stubs the browser APIs jsdom lacks and stands in for react-three-fiber, so that scene code can be rendered and asserted on without a WebGL context.

yarn test

Runs the whole test suite once, as CI does.

yarn test:watch

Launches the test runner in the interactive watch mode.

yarn test:coverage

Runs all tests and prints out code covfefe.

Linting and formatting

yarn lint

Runs the linter using ESLint, configured in flat format in eslint.config.cjs.

Note that the project compiles with TypeScript 7, while typescript-eslint still requires the TypeScript 6 API. Both are installed side by side for that reason: typescript is the compiler, and the typescript-6 alias exists only so the linter can parse. The config seeds the former with the latter, and both it and the extra dependency can go once typescript-eslint supports TypeScript 7.

yarn lint:fix

Fixes any linting errors discovered by the linter and reports any issues that could not be addressed automatically.

yarn typecheck

Type checks the project without emitting anything.

yarn format

Formats the project using Prettier. Use yarn format:check to report on formatting without writing any changes.

Building

yarn build

Type checks the project and builds the app for production to the dist folder.
It correctly bundles React in production mode and optimizes the build for the best performance.
The build is minified and the filenames include the hashes.

yarn preview

Serves the built dist folder locally, to check a production build before it ships.

Maintaining ephemerides

Ephemerides

Ephemerides are all of the orbital characteristic data points used to aid in the computation of celestial positions of orbital bodies.

For information on the file structure for these JSON files, please see the Wiki.

The maintainable versions of all orbital data (including their ephemerides) are stored in public/static/data/orbitals/{heliocentric-system}/{satellite-or-barycentric-orbital}.json.

Example folder structure

  • public/static/data/orbitals/
    • earth/
      • earth.json
      • moon.json

Updating ephemerides

yarn ephemerides

Takes all orbital JSONs, probes the JPL Horizons database for ephemerides, and updates each JSON accordingly. For more information on this script, and on the prerequisite data format, please see this wiki page.

Building the main orbitals file

The main orbitals.json file in public/static/data is a compilation of all the orbital JSONs. It is a flat array of all the orbitals in the Solar System scene, including all planets and satellites.

yarn ephemerides:build

Compiles the orbitals.json file. This is also run as part of yarn build.

Deployment

Deployment

Deployment is handled by GitHub Actions, defined in .github/workflows/merge.yml. On every push to main, the workflow lints the project, runs the tests with coverage, reports that coverage to Codecov, and builds the app. The resulting dist folder is then published to the gh-pages branch, along with a CNAME pointing at tycho.io.

Credits

About

🪐 A real-time interactive simulation of the solar system.

Topics

Resources

Stars

113 stars

Watchers

3 watching

Forks

Releases

Packages

Used by

Contributors

Languages