A C++ library for manipulating .poly and .ptmd files.
It's fast. But it definitely wasn't the right language choice. C# would have been better, but I don't know how to code in it.
PolytoriaEnums.h- Contains a list of all enums.PolytoriaTypes.h- Contains all custom Polytoria types.PolytoriaClasses.h- Required for all operations with Instances.PolytoriaPlace.h- Required for serialization/deserialization of places, alongside creating the default place structure.
Here is an example of most of the usages of this library:
#include "PolytoriaTypes.h"
#include "PolytoriaClasses.h"
#include "PolytoriaPlace.h"
#include <iostream>
using namespace Polytoria;
int main() {
Game& game = Place::FromFile("examples\\officeTemplate.poly");
// Both Instance::New constructors can take in an optional parent.
// If it is not specified, it will be parented to nothing.
// In addition, the name will be set to the ClassName when calling all Instance::New methods.
Part& spawnOne = Instance::New<Part>(game["Environment"]);
std::cout << spawnOne.Name << std::endl; // "Part"
// You can also define instances like this. It, however, may return a null pointer.
Instance* spawnTwo = Instance::New("Part", game["Environment"]);
// There's a third way you can make instances, but the default name will be Instance unless set.
// In addition, it will be on the stack, and will cause problems if you leave the function it was defined in.
Part spawnThree = Part();
std::cout << spawnThree.Name << std::endl; // "Instance"
// You can get the parent and set the parent with the SetParent() and GetParent() methods.
// Do note that these functions take in or output pointers.
std::cout << spawnOne.GetParent()->Name << std::endl; // "Environment"
// You can also use template bracketing as a sort of type annotation.
// It will be nothing if the Instance isn't derived from that type.
Environment* environment = spawnOne.GetParent<Environment>();
// The ClassName property is special.
// It's actually a function. If it wasn't, you could edit it, and cause shenanigans.
// A couple of other read-only properties are like this for Polytoria types.
std::cout << game["Environment"].ClassName() << std::endl; // "Environment"
// Setting and getting properties can be done just like in Lua.
spawnOne.Position = Vector3::New(0, 1, 0); // Polytoria types can be constructed with ::New
spawnOne.IsSpawn = true;
spawnOne.Name = "Spawn1";
spawnTwo->Name = "Spawn2";
spawnThree.Position = Vector3(34.5, 1, 4); // You can do T() and it's probably fine, minus the constructors that only exist under ::New
spawnThree.IsSpawn = true;
spawnThree.Name = "Spawn3";
spawnThree.SetParent(&game["Environment"]);
// You can also set properties this way.
// This is useful if you're trying to set a DynamicInstance property on an Instance.
spawnTwo->SetProperty("Position", Vector3::New(-38.5, 1, -48.5));
spawnTwo->SetProperty("IsSpawn", true);
// It will not throw any errors if the property name doesn't exist.
// It, however, will throw errors if you specify the type wrongly.
spawnTwo->SetProperty("AAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAAAAAA");
// Properties can also be gotten this way.
// This version will never throw, but will return an empty std::any if the property doesn't exist.
std::any nameAny = spawnTwo->GetProperty("Name");
// You can also cast it to a normal type with template brackets.
// Do note that this will throw if you specify the name or the type wrong.
std::string name = spawnTwo->GetProperty<std::string>("Name");
// You can iterate through all properties of an object like this.
for (Property property : game.GetProperties()) {
std::cout << property.type << " " << property.name << std::endl; // String Name
// Since there is no property.value, if you wish to get or set a property, you must do this:
if (property.type == "String") {
game.SetProperty<std::string>(property.name, "AAAA");
std::cout << game.GetProperty<std::string>(property.name) << std::endl; // AAAA
}
}
// You can also get the type of an individual property.
std::cout << convertTypeName(nameAny.type()) << std::endl; // String
// You can also just feed in an std::any value directly.
std::cout << convertTypeName(nameAny) << std::endl; // String
// Accessing children can also be done just like in Lua, but with two major caveats.
// - It will throw if an Instance doesn't exist with that name.
// - The type will ALWAYS be Instance. If you wish to access properties with the . operator, that's not great.
Instance& backpack = game["PlayerDefaults"]["Backpack"];
// FindChild is similar, but can be used to solve these problems.
// - It will return a null pointer if an Instance doesn't exist with that name.
// - Type can be specified with templates.
Instance* backpackPointer = game["PlayerDefaults"].FindChild("Backpack"); // This is fine, it will automatically assume Instance.
// This templated hybrid of FindChild and FindChildOfClass solves that issue.
// However, it will only return anything if any children with that name derive from the specified class.
Backpack* backpackBackpack = game["PlayerDefaults"].FindChild<Backpack>("Backpack");
// This issue does't exist with FindChildOfClass, which has to be templated.
// This will return anything that derives from the specified type.
backpackBackpack = game["PlayerDefaults"].FindChildByClass<Backpack>();
// All templated class type checks are based on inheritance, unlike in Polytoria.
std::cout << (backpack.IsA<Instance>() ? "true" : "false") << std::endl; // true
// Looping through children can be done similarly to Lua.
for (Instance& child : game["Lighting"].GetChildren()) {
std::cout << child.Name << std::endl;
}
// Unlike in Polytoria, this checks with inheritance, instead of just checking if the ClassName is equal to a specific string.
for (DynamicInstance& child : game["Lighting"].GetChildrenOfClass<DynamicInstance>()) {
std::cout << child.Name << std::endl; // "SunLight"
}
// You can destroy objects. This frees up their memory and deparents them.
// If you want to temporarily deparent an object, use SetParent(nullptr). Don't reparent these objects.
backpack.Delete();
backpack.Destroy(); // This does the same thing. I have no idea what the Polytoria distinction is.
// When you're done making changes, you can save the place like so.
Place::SaveFile(game, "examples\\officeTemplateModifed.poly");
// You can also save instances as a model file. (Note, the file type distinction is arbitrary, the actual Polytoria Creator doesn't care.)
Place::SaveFile(game["Environment"]["Spawn1"], "examples\\spawn1.ptmd");
}