Skip to content

Commit

Permalink
Added Funding and comments.
Browse files Browse the repository at this point in the history
  • Loading branch information
DrRetro2033 committed Aug 15, 2024
1 parent d6f7464 commit 9264866
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 18 deletions.
3 changes: 3 additions & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# These are supported funding model platforms

github: [DrRetro2033]
32 changes: 19 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,45 +1,51 @@
# Arceus

## The modern save manager and editor.
### The modern save manager and editor.

### NOTICE: This is still in alpha.

![Arceus](https://archives.bulbagarden.net/media/upload/thumb/9/9e/0493Arceus.png/900px-0493Arceus.png)

## What is Arceus?
# What is Arceus?

Arceus is a brand new CLI (Command Line Interface) save manager and editor designed to make it easy to manage your saves all in one place.

## Features
# Features

### Branch Off Into Different Universes 🌌
## Branch Off Into Different Universes 🌌

With Arceus, you can branch saves into new universes, so multiple versions of one save can exist at the same time.

### Rollback to Older Saves 🕔
## Rollback to Older Saves 🕔

Arceus can rollback saves to older versions, so if you make any mistakes, your original savefile is still intact.

### Human Readable 👓
## Human Readable 👓

With file patterns, you can make binary and hexadecimals readable and modify them with ease (In development.)
With file patterns, you can make binary and hexadecimals readable and modify them with ease.

## Use Cases
# Use Cases

### For Save Editors 📝
## For Save Editors 📝

The main use case for Arceus is for developers can use Arceus in their save editor to make it easier to focus on what actually matters, the user experience. If you want an example of what you can do with Arceus, check out my other project [MudkiPC](https://github.com/Pokemon-Manager/MudkiPC).

### For Game Development 💻
## For Game Development 💻

Be able to rollback to any point in your game for testing, without having to write debug menus.

### For Multiple Players 🫂
## For Multiple Players 🫂

No matter if a game supports multiple saves or not, Arceus can make it easier to have multiple players have their own experience.

### For Achievement Hunting 🏆
## For Achievement Hunting 🏆

Jump from point to point, so you can easily collect every achievement in a game.

### Why is it called Arceus?
# Why is it called Arceus?

The reason I called this program is called Arceus is because Arceus is the literal god of Pokémon, and they have the ability to effect time and space. It is also because this is a large compontent of my other project [MudkiPC](https://github.com/Pokemon-Manager/MudkiPC), which is Pokémon related.

# Consider Sponsoring ❤️

I would love to continue working on this for the foreseeable future, however, I am currently in school and this project is a lot of work. Consider sponsoring me on GitHub so I can continue working on this project! If you can't, no worries, you can spread the word about this project instead. Thanks!
20 changes: 18 additions & 2 deletions bin/file_pattern.dart
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ class FilePattern {
for (String key in bitfield.keys) {
int size = 0; // Size of the range of bits.
bool isPadding = false; // Whether the range of bits is padding.
// If it is padding, it just adds the preceding number in the pad command and offsets by it.
// If it is padding, it just adds the preceding number in the pad command and skips the if else chain below.
if (bitfield[key] is int) {
// Is the key-value pair a number?
size = bitfield[key] as int;
Expand All @@ -120,12 +120,16 @@ class FilePattern {
throw Exception(
"Unsupported bitfield type: ${bitfield[key]}. Not continuing as every subsequent value will be out of alignment.");
}

// This is where the data is fetched from the bitfield.
if (!isPadding) {
parsedData[key] = _getValueInBitfield(
combinedNumber, offset, size); // The value of the bit range.
// print(((BigInt.one << size) - BigInt.one).toRadixString(2));
// print("$key: ${(parsedData[key] as int).toRadixString(2)}");
}

// Move the offset by the size of the range of bits.
offset += size;
}
}
Expand All @@ -135,15 +139,22 @@ class FilePattern {
return parsedData;
}

/// # `int` _getSizeOfCharArray(`String sizeString`)
/// ## Returns the size of the char array in bytes.
/// The string you should pass must end with a hex or dec number in square brackets. e.g. `char16[16]` or `char16[0x10]`.
int _getSizeOfCharArray(String sizeString) {
String x = sizeString.split("[")[1];
String x = sizeString.split("[")[1]; // Decides the size of the char array.
//TODO: Replace with a regular expression for typed arrays, not just char16.
x = x.split("]")[0];
if (x.startsWith("0x")) {
return int.parse(x.substring(2), radix: 16);
}
return int.parse(x);
}

/// # `dynamic` _getValueInBitfield(`BigInt combinedNumber`, `int offset`, `int size`)
/// ## Returns the value of the bitfield in the combined number.
/// TODO: Add support for signed numbers.
dynamic _getValueInBitfield(BigInt combinedNumber, int offset, int size) {
BigInt value =
((combinedNumber >> offset) & ((BigInt.one << size) - BigInt.one));
Expand All @@ -156,6 +167,8 @@ class FilePattern {
}
}

/// # `int` _getSizeOfBitField(`YamlMap item`)
/// ## Returns the size of the bitfield in bytes.
int _getSizeOfBitField(YamlMap item) {
int size = 0;
for (String key in item.keys) {
Expand All @@ -169,6 +182,9 @@ class FilePattern {
return (size / 8).ceil();
}

/// # `YamlMap` _getPattern(`String path`)
/// ## Returns the parsed pattern.
/// This is internal and should not be called directly.
YamlMap _getPattern(String path) {
if (!(_parsedPatterns.containsKey(path))) {
File file = File("${Directory.current.path}/assets/patterns/$path");
Expand Down
14 changes: 11 additions & 3 deletions bin/game.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ class Game {
String hash = "";

/// # DO NOT CALL DIRECTLY
/// ## Call `Game.init()` instead and await.
/// ## Call `Game.init()` instead and await the result.
Game(this.name, this.path, this.hash);

/// # `Future<Game>` init(String name, String path, String hash) async
static Future<Game> init(name, path, hash) async {
final game = Game(name, path, hash);
if (!Directory("$path/.arceus").existsSync()) {
Expand Down Expand Up @@ -121,7 +122,7 @@ class Game {
}

Future<void> printIndex() async {
AnsiX.printTreeView((await getNodeTree()).toJson(),
AnsiX.printTreeView((await _getNodeTree()).toJson(),
theme: AnsiTreeViewTheme(
showListItemIndex: false,
headerTheme: AnsiTreeHeaderTheme(hideHeader: true),
Expand All @@ -131,7 +132,10 @@ class Game {
));
}

Future<Node> getNodeTree() async {
/// # `Future<Node>` _getNodeTree() async
/// ## Get the node tree from the index.
/// Returns the root node of the tree in the form of a `Node` object.
Future<Node> _getNodeTree() async {
String hash = _index?.get("initialNode");
final firstNodeInTree = Node(hash, _index?.get(hash)["name"]);
Map<String, Node> nodes = {hash: firstNodeInTree};
Expand Down Expand Up @@ -170,6 +174,10 @@ class Game {
// }
}

/// # `class` `Node`
/// ## A node in the game tree.
/// Contains a list of the next nodes and the name and hash of the node.
/// TODO: Move code from inside of `Game` that modifies the tree, and move it here.
class Node {
List<Node>? next;
String? name;
Expand Down
3 changes: 3 additions & 0 deletions bin/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@ class JumpToUniverseCommand extends Command {
final description = "Jump to a specific point in time.";
}

/// # `class` ListUniversesCommand extends Command
/// ## List all universes.
/// Uses AnsiX for printing tree views.
class ListUniversesCommand extends Command {
@override
final name = "list";
Expand Down

0 comments on commit 9264866

Please sign in to comment.