Giter Club home page Giter Club logo

pandora's Introduction

logo

pandora-ci


⚠️ THIS ADDON IS STILL IN ALPHA AND NOT PRODUCTION-READY YET.

Meet Pandora, an addon for the Godot Engine that simplifies the handling of RPG data. Pandora allows you to easily manage RPG elements like items, spells, abilities, characters, monsters, and loot tables. Whether you're building a traditional turn-based RPG or a fast-paced action game, this addon can help.

Features

🪟 Dedicated Editor UI

Manage all your RPG data in one place. Create, edit, and delete items, spells, abilities, characters, monsters, and loot tables easily. Properties will propagate automatically to child categories and entities.

editor-example

🔌 Accessible API

Pandora comes with an accessible API through the Pandora singleton. Access all your data at runtime or even within tool scripts!

class_name MyScene extends Node2D

# Entity can be selected in the editor
@export var entity:PandoraEntity

var instance:PandoraEntity

func _ready():
   # create a new instance of this entity
   self.instance = entity.instantiate()
   instance.set_integer("Current Stack Size", 3)
   var other_entity := Pandora.get_entity(EntityIds.COPPER_ORE)

🧪 Tested

To keep the codebase clean, we cover every feature with unit tests.

📦 Installation

  1. Download Latest Release
    • (optional) access latest build for Godot 4.x
  2. Extract the pandora folder into your /addons folder within the Godot project.
  3. Activate the addon in the Godot settings: Project > Project Settings > Plugins

Getting started

Got questions?

Head to the Discussion Board to ask any question or discuss ideas.

🥰 Credits

pandora's People

Contributors

andy3659 avatar bitbrain avatar eth0net avatar imothee avatar mrawlingst avatar mrfelipemartins avatar naros avatar nemesis-as avatar nkrisc avatar russmatney avatar shomykohai avatar tylercchase avatar vojtastruhar avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pandora's Issues

Propagate moved/deleted files

When files are getting deleted or moved in the file dock, ensure to propagate these changes to relevant entities.

When relevant file gets moved -> update the path automagically inside Pandora
When relevant file gets deleted -> revert to original default value

Call get_editor_interface().get_file_dock().file_moved

🔌 Reference property type

Introduce a new property that allows for referencing an existing entity. This requires #15 to be done first so the category can be selected. Once selected, the property itself will provide a list of all entities under that category (flat-mapped) so even child categories have their entities listed here.

  • what if the selected entity gets deleted?
  • what if the category configured gets deleted?
  • what if either the category or entity gets moved outside of the selected tree?

🖼 Custom entity icons

Currently, entity icons are rather static. Introduce a mechanism to set the entity icon, as well as a custom icon scene (in case users decide to render icons differently from what Pandora does out of the box).

Generate category ids

Currently, only entity ids are being generated. It would be useful to also include the categories to some extend.

🗃️ Propagate file and path changes into Pandora

Pandora can reference things like icons and resources, however, these can be moved, therefore breaking the existing configuration. There are some scenarios that need to be considered:

  • one or more files are moved
  • one or more folders are moved
  • one or more files are deleted
  • one or more folders are deleted
  • one or more files are renamed
  • one or more folders are renamed

🖐️ Change property type on existing property

There is a use case to migrate properties, e.g. change their type without deleting or creating new properties. Reason being is that child categories + entities may have been set up and it is annoying to migrate them to the changed property.

How it works

depends on #15

Inside the advanced property settings, users can change the property type via dropdown. This prompts the user with a popup to confirm (as it may have side effects). Any property would need to be cleared that cannot be migrated (including all values configured on children + overrides) - however, some values should be compatible and migrated:

String

From type to type old value new value notes
string int "3" 3 when value cannot be parsed, default to property default value
string bool "true" true when value cannot be parsed, default to property default value
string float "1.2" 1.2 when value cannot be parsed, default to property default value
string reference "12" PandoraEntity(id=12) when entity cannot be found, default to property default value
string resource "res://icon.svg" res://icon.svg when value cannot be parsed, default to property default value

Integer

From type to type old value new value notes
int string 12 "12" -
int bool - - Reset to new type default
int float 3 3.0 -
int reference - PandoraEntity(id=12) when entity cannot be found, default to property default value
int resource - - Reset to new type default

Float

From type to type old value new value notes
float int 2.3 2 Values are rounded
float bool - - Reset to new type default
float string 2.5 "2.5" -
float reference - - Reset to new type default
float resource - - Reset to new type default

Bool

From type to type old value new value notes
bool int - - Reset to new type default
bool string true "true" -
bool float - - Reset to new type default
bool reference - - Reset to new type default
bool resource - - Reset to new type default

Reference

From type to type old value new value notes
reference int PandoraEntity(id=123) 123 when entity cannot be found, default to property default value
reference string PandoraEntity(id=123) "123" when entity cannot be found, default to property default value
reference float PandoraEntity(id=123) 123.0 when entity cannot be found, default to property default value
reference bool - - Reset to new type default
reference resource - - Reset to new type default

Resource

From type to type old value new value notes
resource int - - Reset to new type default
resource string "res://test.png" "res://test.png" -
resource float - - Reset to new type default
resource bool - - Reset to new type default
resource reference - - Reset to new type default

🔧 Advanced property settings

Introduce a sidepane when clicking on a property that is editable (on a category that defines it, not overrides it!) that provides more detailed settings:

  • numbers should have a min/max setting
  • text should have a max length/min length setting
  • references should have a 'category only' option and a 'category filter' option

Those ideally should be encoded into a property validation setup, as setting properties outside of these restrictions should not be allowed. Introduce two new signals on properties:

signal property_updated
signal property_update_failed(reason:String)

Pandora data is leaking memory

Godot version: 4.0+

Describe the bug

PandoraEntity needs to be freed explicitly. Loading/unloading Pandora e.g. x50 times causes a jump in memory:

Screenshot 2023-08-26 104812

To Reproduce
Steps to reproduce the behavior:

  1. go to plugins in the Godot settings
  2. unload/load Pandora 50x times

Expected behavior
Unloading Pandora should free memory accordingly.

🔎 Search functionality

Currently, there us no way to search entities/categories. Introduce a search bar that lets you search by name or alias.

🦾 Resource property type

Sometimes it makes sense to link up Godot Resource as a property. Add a new type to define resource exports.

✈ @export custom entity types

In case I am exporting a variable, e.g.

@export var item:Item

and Item itself extends PandoraEntity, treat it as PandoraEntity by:

  1. search the top-most category that specifies the script path of the type
  2. apply a filter to the results that are within this category

e.g. doing that should only show entities of type Item

Category filter on reference property

Needs to be done after #15

Currently, all entities are always shown as part of a reference property. Have an option to select which category the property should limit to. This is especially useful when trying to reference a specific type of entity.

🎯 Vector property

Refer to the contributor docs to learn how to generally add new properties to Pandora!

A Vector property (which could be Vector2, Vector3 — Vector2i and 3i would be nice but not necessary —) would help a lot.

🧶 Custom class types

By default, Pandora will initialise the following types:

  • PandoraCategory - any category is of this type
  • PandoraEntity - any entity object is of this type, also PandoraCategory is of this type
  • PandoraEntityInstance - any instance is of this type. Instances are being created at runtime and only stored in the user data storage, not in the game storage

While this is useful, introducing something like an inventory system (https://github.com/bitbrain/pandora/issues/7) is difficult, as someone would need to 'guess' the attributes and properties of an item. It is also a problem when it comes to type-safety: ideally, implementing something like an inventory should only operate on items, but then it would be possible to assign other entities, e.g. NPCs to an inventory which does not really make sense logically. We also cannot guarantee that a PandoraEntityInstance has the required attributes.

Solution

Introduce a new property on any PandoraCategory or PandoraEntity that is the path to the script/type defining that object. By default, it is set to the path of PandoraEntityInstance class but it can be overridden. The caveat is that any script mentioned here needs to be a child of PandoraEntityInstance.

  • where would that config sit? Would it be rather part of the entity itself?
  • how can I easily access the custom types? e.g. currently, we would need to do something like this:
var inventory_item = Pandora.get_entity_by_name("Iron Pickaxe") as InventoryItem

which is not very nice. Unless, we recommend doing something like this:

class_name ItemBackend

static func get_item(name:String) -> InventoryItem:
   return Pandora.get_entity_by_name(name) as InventoryItem

and then doing this instead:

var inventory_item = ItemBackend.get_item("Iron Pickaxe")

Todo

  • resolve script type when loading an entity
  • fallback to PandoraEntity in case the script cannot be found/loaded
  • re-instantiate any PandoraEntity that was created in the editor
  • update inventory example to use ItemInstance rather than PandoraEntityInstance

💾 Save data when saving in Godot

There is a saving hook in Godot that we should connect to save. It is also worth disabling the save button in case changes are up to date.

Store native types in data.pandora

json supports types such as arrays, integers, floats and booleans. Rather than doing string shenanigans, store them in their native types instead!

🎞 auto-migrate changes to instances

Imagine an entity like so with some properties:

property value type
rarity "rare" string
price 500 int

The game then generates a PandoraEntityInstance based of that entity. At runtime even, these values could be overridden like so:

property value type
rarity "rare" string
price 1000 <-- new price int

(without impacting the original PandoraEntity)

Now let us imagine that we are introducing a new concept into the game and we are updating the original entity accordingly:

property value type
rarity "rare" string
price 500 int
weight 100 <-- new concept of item weight int

When loading the game now, the PandoraEntityInstance should ideally be updated with the new version. There are a few approaches:

Approach 1 - maintain a version per entity

If the version of the entity diverges from the one of its instances, the parent has probably changed and the instance is applicable for a full refresh: any new field will be added, any field that does not exist any longer on the original entity will be removed.

Approach 2 - lookup new properties lazily when accessed

In case a property is accessed that does not exist yet on the instance, look it up on the original entity blueprint and create a fresh property in the instance for it.

🗃️ Configurable data storage in project settings

Currently, data storage is hardcoded to be JsonDataStorage, however, the system has been designed from the ground up to use storage in a modular way. For example, someone still may want to use json to store their entity data and ship it with their game, but when a player plays the game, the player data should be stored in e.g. Steam (see #11).

Introduce a mechanism to https://github.com/bitbrain/pandora/blob/godot-4.x/addons/pandora/settings/settings.gd so both the object and instance storage can be re-configured to a new data storage. In order to do that, there also needs to be a mechanism to register/add custom data storage in the project settings. Let us assume someone were to use a Steam integration (not part of this ticket):

  1. user e.g. adds pandora-steam as an additional plugin/addon to their addons folder
  2. addon auto-configures itself as a data storage by telling Pandora about it (API required)
  3. navigating to the project settings shows a new Steam option available to pick as a data storage
  4. selecting the data storage persists in the project settings

Notes

  • what happens if a data storage was selected but is no longer available?
  • support for multiple data storages as a 'fallback' mechanism?

Avoid duplicate property names

It is currently possible to create scenarios where property names can exist multiple times within an entity, leading to undesired behavior. Any property name should be unique per entity.

  • a parent entity cannot define a property that already exists on a child
  • a child entity cannot define a property that got inherited from a parent
  • an entity should not have the same property twice, meaning renaming one property to an already existing name should not be possible

🔗 add addon links into editor

On the top right of the addon add the following links:

  • Contribute (Github link)
  • Learn (Pandora wiki)
  • Tutorial (Youtube video)

Also show the current version number (parsed from the config file)

📐 Group properties by inherited parents

Having lots of different properties is useful but can become quickly overwhelming:

pandora-progress

Rather than listing all properties in a single table, group these properties by their parents it got originally inherited from.

Quests

Is your feature request related to a problem? Please describe.
Handling quests is a difficult task. Handling quests in a realizable and extensible way is impossible.

Describe the solution you'd like
A quest editor, similar to one with items, where each quest is an item in a list. Also, a graph view for seeing which quest depends on which. Codegen would generate quest ids, which can be referenced in the code to trigger or finish them.

Describe alternatives you've considered
There's no reliable solution for this in the Godot ecosystem yet.

Additional context
Having items and quests in one place would help developers maintain a clear and understandable project with a simple structure.

Cannot set reference field value

Godot version: v4.1.stable.official [970459615]

Describe the bug
When setting a reference property value, error is printed and the change doesn't happen.

To Reproduce
Steps to reproduce the behavior:

  1. Go to Pandora panel with the example dataset (inventory)
  2. Under Items/Ores select CopperOre
  3. Change the CopperOre's rarity from currently Legendary to any other
  4. Error gets printed and the change doesn't go through

Error: Pandora error: value <Resource#-9223369595769779648> is incompatible with type reference

This happens even if I create a brand new category with new reference fields and items.

Expected behavior
The rarity of CopperOre should change and no error should be printed.

Desktop

  • OS: MacOS 13.4.1

📙 Document addon functionality

Update both the README.md as well as the docs with documentation about:

  • what is Pandora (short version) and why not just use Godot resources instead?
  • how to install
  • UI overview (how to access Pandora)
  • Categories vs. Entities vs. Entity Instances
  • Property types
  • Property inheritance
  • Property overriding
  • Deleting properties
  • Deleting entities
  • using Pandora entities in your nodes (export variables)
  • accessing Pandora data in your game
  • Data Store concepts (user data vs. project data)
  • Pandora examples (e.g. Inventory system)
  • Custom data stores
  • Addon loading order (lifecycle)
  • Contribution guidelines

Printable entities

Is your feature request related to a problem? Please describe.
When debugging, all entities are printed in the default Resource format - something like <Resource#-9223368908105259524>, which is not very readable.

Describe the solution you'd like
Define a custom string formats for different data classes with _to_string method.

Describe alternatives you've considered
I think this is a good solution natively supported by Godot with minimal overhead.

Additional context
Currently if I try to change for example the rarity of CopperOre from Legendary to any other, following message is printed. I believe this is a bug too 🐛 :)

Pandora error: value <Resource#-9223368908105259524> is incompatible with type reference

I think something like this would be more informative:

Pandora error: value <PandoraReference<PandoraEntity 'Epic'>> is incompatible with type reference

Migrating existing resources to Pandora breaks Godot

Godot version: 4.0.1
Pandora version: 1.0alpha1

Describe the bug

When trying to migrate a game over to Pandora, one would usually go and change the extends Resource to extends PandoraEntity. However, any existing .tres file that is based on said resource fails to load and it produces a set of errors in Godot. This due to the fact that .tres files are initialised with a default constructor _init() while Pandora resources come with a custom constructor (which breaks things).

To solve this, the _init() on entities could be moved into a lazy init function, but makes it more risky to work with, as a PandoraEntity may be forgotten to be initialised correctly.

☄ Move categories & entities via drag&drop

Introduce a mechanism that allows for drag&dropping categories & entities in the tree in order to move them around and effectively re-assigning parent categories to them. As a result, some of its properties change, so doing so should prompt a popup to ask the user if this is really something they want to do (only if properties actually would change).

This should also allow for reorganising your entities & categories, as well as selecting multiple entities/categories at once that can be dragged and dropped.

Unable to access int properties from file

Godot version: 4.1.2

Describe the bug

Due to the behavior described here godotengine/godot#81035, saving an int to disk and then loading it changes its type to float, however, Pandora currently has validation in place, making it impossible to access int values after they have been saved & loaded back from disk.

💽 Import data functionality

Add the ability to select an existing .pandora file and merge it into the existing data set.

In case there is a conflict, the entity will be skipped. This import applies to: entities, categories and properties.

🧬 Generate entity id constants

Let us say I want to get an entity of a specific type via code. There could be multiple ways:

var entity = Pandora.get_entity("some-id-that-is-just-guessed-but-could-have-a-typo")
var entity2 = Pandora.find_entity_by_name("Iron Ore") # name may change?

So generally, a very cumbersome way to access entity data. Given, that we may want to access entities rather frequently in code I propose a better way:

var entity = Pandora.get_entity(EntityIds.IRON_ORE)

whereas EntityIds is a generated gdscript file looking like this:

## Auto-generated file for Pandora
class_name EntityIds

const IRON_ORE := "9712871298729982"
  • how would the user control the file name of this? e.g. EntityIds might be a name the user wants to change
  • does it make sense to always auto-generate this? An option to disable the generation of this file in the project settings might be good

🔌 Generate property names

It is currently cumbersome to access properties from within GDScript. One basically has to guess what the name is.

Data loss can occur

It appears that sometimes it can happen that a bad save would remove all entities (but not categories). Only resetting to a previous version solves this issue at the moment.

Addressed Cases

  • custom entity script does not exist or got moved #74
  • custom entity script is not of type PandoraEntity any longer #87
  • custom entity script has compilation errors #87
  • custom entity script has an invalid constructor #87
  • lock Pandora and prevent saving in case entity data cannot be instantiated (see comment) #101
  • lock save mechanism and prevent saving until entity data is able to be parsed correctly for saving (see comment) #101

📕 Write code docs

Document the code architecture inside GDScript so contributors have a better way of finding their way around.

📃 Property array support

Refer to the contributor docs to learn how to generally add new properties to Pandora!

Similar to #95, we require a way to provide a "list" of entries - especially for recipes this is crucial.

Support any existing type, and via a + button additional elements can be added.

Example use cases

  • list of ingredients
  • list of minerals to spawn
  • factions that an NPC may be friendly with

📐 Custom property sections

Allow users to specify their own property sections. Ensure to inherit these sections down after #46 is done.

Developer Notes

  • layout data should be stored separately from entity data inside the data.pandora file.

Handle deletion+renaming of entities/categories

Within the Pandora editor, entities can be deleted/edited freely. However, when referencing properties via PandoraEntityInstance there needs to be a case for entity instances still to be working or flagged as "deleted"

This also applies to places in the editor where an entity is referenced.

🏗 Initial Architecture setup

Backend Core

  • core entity architecture (categories, entities, entity instances, properties, property instances)
  • core unit tests
  • support color type

Data Storage

  • write data storage unit tests

UI

  • create Inspector addon for PandoraEntity
  • create left pane tree component (shows object data only, no instances!)
  • create details pane
  • create top bar to add properties
  • option to delete property
  • option to rename property key (only on original category)
  • option to reset property to default
  • option to delete entity (not category) - requires popup!
  • option to delete category and all its children - requires popup!
  • #30

Bugs

  • data does not load correctly in tree component
  • categories do not load correctly
  • #32
  • scrolling the entities list goes out of bounds of the content
  • #31
  • inherited properties do not persist after saving
  • overriding properties does not propagate to children properly (add tests for this!)
  • renaming property name clears child overrides

Notes after meeting with Nathan

  • Localization in the editor -> PortableObjects file: checkout dialogue manager for reference
  • use stretch ratio for UI scaling: pass EditorPlugin down to access editor scale
  • pull out colours into editor settings
  • make rarity its own concept and do NOT hardcore colours!
  • use tree view to visualise
  • TitleFilter in Dialogue manager filters correctly
  • Consider multiple categories within a category
  • rename Set Boni to Set
  • property definitions should be on categories -> items only define them
  • rename Inventory -> Collections (consolidate loot tables into this?) and also consider generating the collection with the creature on spawn
  • do PoC on character composer
  • consider weighted random
  • consider re-generating the random stats when the seed changed
  • create Inspector addon to reference items
  • apply changes hook for saving. MainView in godot_dialogue_addon
  • consider custom file extensions => build export plugin to consider custom file extension

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.