Crafting immersive worlds, one feature at a time.
Table of Contents
The gurps-companion-app is a comprehensive mobile application supporting GURPS 4th edition, offering character management functionalities such as skill tracking, item management, and character attribute handling. With dynamic internationalization features and intuitive navigation structures, this app provides a seamless experience for users to organize and interact with their in-game characters efficiently. Through its structured layout and real-time data updates, the app enhances gameplay dynamics and fosters engaging role-playing experiences for GURPS enthusiasts.
Stats | Items | Ranged weapons | Information |
---|---|---|---|
Feature | Description | |
---|---|---|
⚙️ | Architecture | Built using React Native with a focus on modularity and code reusability. Utilizes Expo for simplified development and deployment. Storybook is used for component development and testing. |
🔩 | Code Quality | Follows modern JavaScript best practices and code standards. Utilizes Tailwind CSS for consistent styling. Codebase is organized with clear separation of concerns. |
đź“„ | Documentation | Contains detailed documentation for project setup, configuration, and usage. Includes guides for developers on contributing and extending the application. |
🔌 | Integrations | Integrates with various React Native libraries like react-native-tab-view, react-native-slider, and react-navigation for navigation. Also integrates with Expo libraries for features like expo-image-picker. |
🧩 | Modularity | Codebase is structured in a modular way, making it easy to extend and maintain. Components are reusable and well encapsulated. Follows a component-driven development approach. |
🧪 | Testing | Utilizes Storybook for component testing and development. Supports unit testing with Jest for React Native components. |
⚡️ | Performance | Optimized for efficiency, fast rendering, and smooth user experience. Utilizes React Native's performance optimizations and Expo's build optimizations for production. |
🛡️ | Security | Follows best practices for data protection and access control within the application. Integrates Expo's security features for secure app development. |
📦 | Dependencies | Leverages a variety of external libraries and dependencies such as react-native, react-navigation, Expo packages, and Tailwind CSS for styling. |
🚀 | Scalability | Designed with scalability in mind, capable of handling increased traffic and load. Utilizes React Native's scalability features and Expo's resources for app scalability. |
These insights are based on the project's dependencies and repository contents provided.
└── gurps-companion-app/
├── .github
│ └── FUNDING.yml
├── README.md
├── app.config.js
├── assets
│ ├── cljs.png
│ ├── icon.png
│ ├── shadow-cljs.png
│ └── splash.png
├── babel.config.js
├── eas-build-pre-install.sh
├── etc
│ ├── metro-bundler.patch
│ └── toolchain-report
├── externs
│ └── app.txt
├── index.js
├── package-lock.json
├── package.json
├── rn-rf-shadow.png
├── shadow-cljs.edn
├── src
│ ├── css
│ ├── expo
│ ├── gurps
│ └── react_native
├── storybook.js
├── tailwind.config.js
└── translations
└── en.json
.
File | Summary |
---|---|
storybook.js | Registers the Storybook app component using React Natives AppRegistry based on the Expo app name defined in app.config.js. |
shadow-cljs.edn | Defines build configurations for React Native and storybook, specifying dependencies and compiler options, enabling hot-reload and repl for development. Organizes source paths and middleware settings for optimal project structure and performance. |
tailwind.config.js | Defines Tailwind CSS configuration to style components in app/ folder based on specified theme extensions. |
eas-build-pre-install.sh | Ensure successful macOS shadow-cljs build by installing Java via Homebrew JDK 11, creating a symbolic link, and updating PATH in the script for the parent repository architecture. |
app.config.js | Defines configuration settings for the Expo app, including platform support, versioning, and additional features. Controls app name, privacy, icons, and splash screen appearances, while enabling Storybook and specifying bundler for web compatibility. |
index.js | Imports the main index.js file from the app directory, crucial for initializing the apps core functionality within the repositorys architecture. |
babel.config.js | Configures Babel presets for Expo in the projects architecture. Caches and returns preset setup for seamless Expo development. |
package-lock.json | The code file in question plays a crucial role in the Gurps Companion App repository by managing the configuration settings for the application. It helps ensure that the app functions smoothly by defining various essential parameters without delving into technical specifics. This file acts as a central hub for specifying how the app should behave and interact with its environment, ultimately contributing to the overall architecture of the project. |
package.json | Defines project scripts for server, Expo, Storybook, CSS watch, Android, iOS, web, release builds, eject, and EAS build tasks. Lists dependencies like React Native, Expo, and Storybook. Configures development tools for streamlined app development in the repository. |
externs
File | Summary |
---|---|
app.txt | Defines missing type hints for specific React concepts, aiding in building React apps with Fulcro. Abstraction allows seamless integration without processing JavaScript. Crucial for maintaining clarity in app development using Fulcro framework within this repos architecture. |
etc
File | Summary |
---|---|
toolchain-report | Generates version reports for defined toolchain packages. Queries tools for versions using regex patterns. Outputs key-value pairs of tool versions. |
metro-bundler.patch | Improves Metro bundler performance by optimizing plugins. Enhances project build speed by revising plugin usage in the Metro bundler configuration. |
.github
File | Summary |
---|---|
FUNDING.yml | Facilitates funding options for the repository with supported platforms like GitHub and PEZ. Enhances project sustainability and support through various sponsorship models. |
translations
File | Summary |
---|---|
en.json | The translations/en.json file in the gurps-companion-app repository defines key user interface text strings for the GURPS companion apps 4th edition. It includes essential headings and labels related to stats, items, armor, and combat mechanics, ensuring a consistent and localized user experience across the application. This file plays a crucial role in facilitating seamless navigation and comprehension within the GURPS companion app. |
src.css
File | Summary |
---|---|
tailwind.css | Implements Tailwind CSS configuration to provide consistent styling across components in the app. Integrates base styles, components, and utility classes for streamlined and cohesive design system. |
src.gurps
File | Summary |
---|---|
effects.cljs | Integrates asynchronous storage effects and common effects for GURPS, enhancing gameplay experience in the app. |
subs.cljs | Defines re-frame subscriptions for checking if app is initialized and accessing navigation root state in the Gurps Companion app, contributing to a clear separation of concerns within the overarching architecture. |
db.cljs | Defines database schema with character attributes, skills, and initial state. Maintains app state for a role-playing companion app. Focuses on data modeling and structure for character management. |
app.cljs | Defines app setup, language loading, and root rendering. Manages i18n, async storage, events, and effects. Conditionally enables Storybook. Syncs DB, initializes storage, and hides splash screen. Facilitates a seamless start in the Gurps Companion App. |
events.cljs | Implements event handling and database initialization for the gurps companion app, including spec validation and async storage setup. |
root.cljs | Defines navigation structure & visual elements for the GURPS Companion app. Creates a tab layout with icons and titles, linking to character stats, skills, items, and info pages. Implements safe area handling and state persistence for seamless user experience during development. |
src.gurps.setup
File | Summary |
---|---|
hot_reload.cljs | Enables triggering UI and code reloads, handles build status notifications in the app. |
i18n_resources.cljs | Implements internationalization setup for the app, allowing for multiple languages to be loaded dynamically. Loads and manages translations based on users selected language, enhancing user experience and accessibility. |
src.gurps.navigation
File | Summary |
---|---|
view.cljs | Enables dynamic rendering of navigation screens with configurable themes, safe area handling, and optional bottom sheet display. Seamless integration with alert banners and toasts components for a consistent user interface experience. |
effects.cljs | Manages navigation effects to interact with the apps root, stack, and modals. Enables actions like setting root, navigating, dismissing modals, and showing overlays like toasts and bottom sheets. Controls app flow through a structured, user-friendly interface. |
skills_stack.cljs | Implements a stack navigator for navigating between different skill-related screens in the Gurps Companion app. Handles rendering of screens for viewing character skills, adding new skills, and specifying skill specializations. |
items_stack.cljs | Defines a tab navigation stack for items, melee weapons, and ranged weapons within the app. Renders screens based on user selections, enhancing the overall user experience in navigating character items effectively. |
src.gurps.utils
File | Summary |
---|---|
i18n.cljs | Implements internationalization setup and utilities for translations in the app using i18n-js. Manages localization settings, number formatting, and label translations. Provides functions for setting language, formatting numbers, handling pluralization, and retrieving translations. |
debounce.cljs | Implements debounce and throttle functions to manage event dispatching in the app, preventing multiple rapid triggers. Maintains state with atoms and leverages setTimeout for event handling. Key features include clearing timeouts, debouncing dispatches, and throttling event calls. |
helpers.cljs | Implements helper functions for handling default values, integer conversion, keyword and string transformations, and flattening keys in the context of the parent repositorys architecture for the GURPS Companion App project. |
src.gurps.common
File | Summary |
---|---|
effects.cljs | Implements event chain effects for state management using re-frame, logging each effect dispatched for debugging. |
src.gurps.common.async_storage
File | Summary |
---|---|
effects.cljs | Defines re-frame effects for asynchronous storage operations using React Natives async-storage library in gurps-companion-apps architecture. Includes functions for setting single/multiple values and retrieving data. |
src.gurps.events
File | Summary |
---|---|
profile.clj | Generates a profile subscription with specified parameters using Re-Frame in the events namespace of the Gurps Companion App, enhancing state management for profile-related data. |
profile.cljs | Defines re-frame events and subscriptions for managing player profiles in the app. Updates and fetches profile data while utilizing asynchronous storage operations as required. |
src.gurps.pages.character
File | Summary |
---|---|
items.cljs | Defines item components for a characters possessions, including name, location, weight, and damage reduction. Facilitates item management with interactive input fields and dropdowns. Maintains state updates using re-frame for a cohesive user experience in the app. |
stats.cljs | Defines the character stats page layout by incorporating summary, attributes, bases table, and encumbrance table components within a ScrollView, styled with predefined attributes for a visually appealing user interface. |
skills.cljs | Defines UI elements, logic for character skills page. Handles skill display, attributes, levels, and costs dynamically. Registers subs for skills and updates. Manages skill cost changes and async storage. |
info.cljs | Defines character information layout with summary, portrait, tech level dropdown, reaction modifiers, languages, and notes sections in a white-themed view. |
src.gurps.pages.character.utils
File | Summary |
---|---|
damage_table.cljs | Defines damage thresholds for GURPS character combat, simplifying rule lookup. |
skills.cljs | The skills.cljs file within the gurps-companion-app repository's architecture serves a critical role in managing and processing character-related skills in the GURPS Companion application. This file encapsulates essential utility functions and logic necessary for handling skills within character pages. It contributes to the functionality that enables users to interact with and manage skills associated with their in-app characters, enhancing the overall user experience and gameplay dynamics.By leveraging the capabilities defined in skills.cljs , the GURPS Companion app can effectively organize, track, and display character skills, offering users a seamless and intuitive interface to engage with their characters abilities. This component plays a pivotal part in ensuring the application's robust feature set related to character development and progression in the GURPS gaming system. |
src.gurps.pages.character.info.widgets
File | Summary |
---|---|
languages_section.cljs | Implements language selection section with dynamic cost calculation for character profiles in the GURPS Companion App. It uses dropdowns, buttons, and inputs to manage spoken and written skills with corresponding costs. The section updates and displays languages as users interact. |
reaction_modifiers_section.cljs | Defines functions for character appearances, status, and reputation inputs. Registers a reaction modifiers section component. Subscribes to profile data and updates state asynchronously. Organized under gurps/pages/character/info/widgets directory in the React Native app. |
tech_level_dropdown.cljs | Defines dropdown options for technology levels with associated labels and descriptions. Implements selection handling and updates in Re-frame subscription and event effects via asynchronous storage. |
notes.cljs | Implements notes section for character profiles with real-time editing and AsyncStorage updates. |
portrait.cljs | Enables selecting and updating user profile portraits. Requests media library permissions, launches image library, and dispatches selected image URI for profile update. |
src.gurps.pages.character.skills
File | Summary |
---|---|
specialization.cljs | Defines functions to display skill details, including specializations, dependencies, and functionality to add skills with associated costs. Interacts with the user interface for skill management within the GURPS companion app. |
groups.cljs | Displays a categorized list of game skills as interactive buttons. Users can click on skills to view details and add them to a character. Skills are grouped by category, with each button linked to skill information and character customization options. |
src.gurps.pages.character.items
File | Summary |
---|---|
defenses_section.cljs | Implements labeled defense sections with dynamic values for DR, parry, and block calculations. Subscriptions to item data and skill levels govern display values. Achieves coherent UI presentation for character defense details within the apps architecture. |
ranged_weapons_page.cljs | Defines a page for managing ranged weapons in the GURPS Companion app. Displays weapon details like damage and range in a structured layout. Supports editing and updating weapon information, synchronizing changes with app state. |
melee_weapons_page.cljs | Implements a dynamic page for managing melee weapons, displaying essential details and enabling real-time updates. Utilizes structured layouts and interactive components to enhance user experience in the character management section of the application. |
src.gurps.pages.character.widgets
File | Summary |
---|---|
bases_table.cljs | Enhances character attributes functionality with dynamic tables in the GURPS Companion app. Manages attribute costs updates and calculations for basic speed and damage, supporting a seamless user experience. |
summary.cljs | Defines summary widgets for character attributes with styling. Organizes fields in groups for name, player, point totals, physical attributes, and more. Designed for view rendering and easily scalable within the parent repositorys architecture. |
reified_attribute.cljs | Calculates and updates attribute costs in character creation. Utilizes re-frame state management for real-time attribute value changes. Integrated within the GURPS companion apps architecture. |
point_total.cljs | Calculates and displays total character points and unspent points in the GURPS Companion App. Utilizes re-frame for state management, allowing real-time updates without manual intervention. Enhances user experience by presenting vital character information at a glance. |
reified_secondary_attribute.cljs | Implements reified secondary attribute calculation and display for character widgets in the repositorys architecture. Uses point-per-cost mapping and calculates attribute value based on cost and dependency. Subscribe to attribute costs, values, and update on change. |
attribute.cljs | Defines and renders attribute input components for character pages, calculating attribute costs and updating values dynamically in the Gurps Companion app. |
helpers.cljs | Implements attribute updates and keyword generation functions. Defines a mapping for attribute costs to points. Contributes to the character creation feature in the project. |
base_text.cljs | Implements dynamic text display and user input for GURPS character attributes, with cost calculations for updates. |
attributes.cljs | Defines re-frame subs and events to manage character attributes and current values in the Gurps Companion App. Leverages reified attributes and secondary attributes for flexibility and modularity in the character creation process. |
encumbrance_table.cljs | Implements encumbrance calculations for a character in the Gurps Companion App, highlighting weight classes. Subscriptions to attribute changes trigger updates in move and dodge columns, maintaining a responsive user interface for character management. |
summary_field.cljs | Implements a summary field widget for character profiles, supporting editing and displaying data with localization, debouncing, and Re-frame state management. |
src.gurps.widgets
File | Summary |
---|---|
dropdown.cljs | Implements a dropdown widget using React Native elements, Reagent, and Tailwind CSS for styling. Handles data options, placeholder, styling, and disabled state. |
bracketed_numeric_input.cljs | Implements bracketed numeric input widget for the Gurps Companion App, providing editable, numeric input with debouncing. Maintains visual consistency and flexibility within the apps UI components. |
underlined_input.cljs | Implements reusable UI components for input fields with underlined styling, offering single and multiline input options, including labeled variants. Each component allows customization such as text alignment and disabling input, enhancing user interactions within the app interface. |
base.cljs | Constructs React Native UI components and adapters for SectionList and FlatList for dynamic widget rendering in the Gurps Companion mobile app interface. |
button.cljs | Defines customizable button component for React Native app, providing styling options and disabled functionality. Enhances user interaction with bold text, blue background, and customizations for disabled state. Essential for creating interactive UI elements. |
src.expo
File | Summary |
---|---|
root.cljs | Defines and renders the root component for Expo, managing component updates and lifecycle methods. Registers the root component with Expo for initializing the apps UI. |
src.react_native
File | Summary |
---|---|
navigation.cljs | Implements navigation functionality for React Native using react-native-navigation and provides methods for setting roots, pushing, popping, showing modals, and registering listeners to handle navigation events. |
async_storage.cljs | Implements async storage functions for React Native using Transit for data serialization and deserialization. Provides functions to set and get items as well as manage item storage. Handles error logging and debounces item setting for efficiency. |
System Requirements:
- None:
version x.y.z
To facilitate that you can easily try this out without installing anything globally on your machine, this project installs everything it needs locally in node_modules
. Then npx
is used to execute tools like expo-cli
.
To install dependencies, and setup the project, run:
npm i
From there use your favorite editor and/or the prompt.
Assuming you have installed the Calva extension in VS Code:
- Open the project in VS Code. Then:
- Run the Calva command Start a Project REPL and Connect (aka Jack-in)
- Wait for shadow to build the project.
- Then Run Build Task. This will start Expo and the Metro bundler. Wait for expo to show its menu options in the terminal pane.
- In the expo menu press w for open web.
The app now should be running in your web browser and Calva automatically connects to it. Confirm this by evaluating something like this in Calva (from a cljs file or in the REPL window):
(js/alert "Hello world!")
You should see the alert pop up where the app is running.
Of course you should try to fire up the app on all simulators, emulators and phones you have as well. Please note that Calva will only be connected to one of your apps at a time, and it is a bit arbitrary which one. Use (js/alert)
to check this.
Open Emacs and a bash shell:
-
Run
npx shadow-cljs compile :app
to perform an initial build of the app.mobile -
In Emacs open one of the files in the project (
deps.edn
is fine) -
From that buffer, do
cider-jack-in-clojurescript
[C-c M-J] to launch a REPL. Follow the series of interactive prompts in the minibuffer:- select
shadow-cljs
as the command to launch - select
shadow
as the repl type - select
:app
as the build to connectmobile - and optionally answer
y
orn
to the final question about opening theshadow-cljs
UI in a browser. At this pointshadow-cljs
will be watching the project folder and running new builds of the app if any files are changed. You'll also have a REPL prompt, however the REPL doesn't work because it isn't connected to anything. The app isn't running yet.
- select
-
In a shell run
npm run ios
(same asnpx expo start -i
). This starts the Metro bundler, perform the bundling, launch the iPhone simulator, and transmit the bundled app. Be patient at this step as it can take many seconds to complete. When the app is finally running expo will display the message:WebSocket connected! REPL init successful
-
Once you see that the REPL is initalized, you can return to Emacs and confirm the REPL is connected and functional:
cljs.user> (js/alert "hello world!")
Which should pop-up a modal alert in the simulator, confirming the app is running and the REPL is connected end to end.
You will need to disable Fast Refresh provided by the Expo client, which conflicts with shadow-cljs hot reloading. You really want to use Shadow's, because it is way better and way faster than the Expo stuff is.
For the iOS and Android there is a Disable Fast Refresh option in the development menu. NB: Often you need to first enable it and then disable it.
For web there may be some way to disable it via a webpack.config
file as per this example. But failing that, once the app has loaded you can block requests to/from localhost:19006/*
(the Webpack dev server) in devtools like so, for instance by right-clicking on a request in the Network tab, selecting Block request URL
, then editing the pattern. In Chrome this looks something like:
<img src="https://github.com/CarnunMP/rn-"rf-shadow/assets/8897392/4d5d9541-f5e4-4108-a38e-65b3c2da4939) <img src="https://github.com/CarnunMP/rn-"rf-shadow/assets/8897392/27c94aa8-3337-4fde-b7f6-7ce87197a89d)
This workaround is far from ideal, because the block needs to be manually toggled off whenever a full refresh is required (e.g. to load a new file), then back on again. But it seems to do the job.
A production build involves first asking shadow-cljs to build a release, then to ask Expo to work in Production Mode.
- Kill the watch and expo tasks.
- Execute
shadow-cljs release app
- Start the expo task (as per above)
- Enable Production mode.
- Start the app.
expo build
is the classic way of building an Expo app, and eas build
is the new version of expo build
. Using EAS Build currently requires an Expo account with a paid plan subscription.
The steps below provide an example of using EAS Build to build an apk file to run on an Android emulator or device.
- Install the latest EAS CLI by running
npm install -g eas-cli
- Log into your Expo account
- Configure EAS Build in your project with
eas build:configure
. - Make your eas.json file contents look like this:
{ "build": { "production": {}, "development": { "distribution": "internal", "android": { "buildType": "apk" }, "ios": { "simulator": true } } } }
- Commit your changes, run
eas build --profile development
, and follow the prompts. - Navigate to the URL given by the command to monitor the build. When it completes, download the apk and install it on your device or emulator.
See the EAS Build docs for more information.
If you want to use EAS Build with a project not based on this template, see this PR for information about how your project can be set up to avoid an error during the build process.
Note: The eas-build-pre-install.sh
script makes EAS install Java in the MacOS environment when running a build for iOS. This ensures that shadow-cljs can be run in the EAS pipeline to build your ClojureScript code.
Contributions are welcome! Here are several ways you can contribute:
- Report Issues: Submit bugs found or log feature requests for the
gurps-companion-app
project. - Submit Pull Requests: Review open PRs, and submit your own PRs.
- Join the Discussions: Share your insights, provide feedback, or ask questions.
Contributing Guidelines
- Fork the Repository: Start by forking the project repository to your github account.
- Clone Locally: Clone the forked repository to your local machine using a git client.
git clone https://github.com/fmguerreiro/gurps-companion-app
- Create a New Branch: Always work on a new branch, giving it a descriptive name.
git checkout -b new-feature-x
- Make Your Changes: Develop and test your changes locally.
- Commit Your Changes: Commit with a clear message describing your updates.
git commit -m 'Implemented new feature x.'
- Push to github: Push the changes to your forked repository.
git push origin new-feature-x
- Submit a Pull Request: Create a PR against the original project repository. Clearly describe the changes and their motivations.
- Review: Once your PR is reviewed and approved, it will be merged into the main branch. Congratulations on your contribution!
This project is protected under the MIT License. For more details, refer to the LICENSE file.
- The creators of the template for react native + shadow cljs from which this app was built from.