diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2b9aaac --- /dev/null +++ b/.gitignore @@ -0,0 +1,24 @@ +### Unity +# Unity generated directories +/[Ll]ibrary/ +/[Tt]emp/ +/[Oo]bj/ +/[Bb]uild/ +/[Bb]uilds/ +/[Ll]ogs/ +/[Uu]ser[Ss]ettings/ +/[Mm]emory[Cc]aptures/ + +# Asset meta data should only be ignored when the corresponding asset is also ignored +!/[Aa]ssets/**/*.meta + +# Build output +*.apk +*.aab +*.unitypackage + +# Autogenerated solution and project files +*.csproj +*.unityproj +*.sln +*.suo \ No newline at end of file diff --git a/Documentation~/index.html b/Documentation~/index.html new file mode 100644 index 0000000..cbf01fc --- /dev/null +++ b/Documentation~/index.html @@ -0,0 +1,538 @@ + + +
+ + +A polygon-based zone system for defining map regions with encounter difficulty, modifiers, and safe areas.
+ +The Zone System lets you paint polygon regions on your map and assign encounter rules to each region. At runtime, you query a world position and get back a fully resolved ZoneContext with the encounter table, difficulty tier, and chance.
ZonesObjectHolder component.| Map Plane | Use Case | Axes | Ignored |
|---|---|---|---|
XY | Flat sprite map, UI map | X, Y | Z |
XZ | 3D world map (standard Unity 3D) | X, Z | Y |
YZ | Side-on map | Y, Z | X |
The Zone Editor window (Window → Zone System → Zone Editor) is the primary tool for managing zones.
+ +Shows all ZoneInstance objects in the current scene. Each row displays:
📋): Creates an independent copy with a new asset✕): Removes the zone and its assetZones with missing ZoneData show a warning icon with options to add data or delete the zone.
Click Create New Zone to open the creation dropdown:
+The zone is created in-memory and enters edit mode immediately. You must click Save to persist the asset.
+ +When editing a zone, all ZoneData fields are available inline:
On save, the editor checks for:
+zoneIdIf a conflict is found, an error is displayed and saving is blocked.
+ +At the bottom of the editor window, expand Export Zones to JSON to export all scene zones to a JSON file for runtime loading.
+When a zone is in edit mode, yellow handles appear in the Scene view for each polygon vertex.
+ +| Action | Input | Description |
|---|---|---|
| Move vertex | Drag handle | Drag any yellow handle to reposition a vertex |
| Insert vertex | Ctrl + Click edge | Adds a new vertex on the closest edge (cyan highlight shows target) |
| Delete vertex | Shift + Click vertex | Removes the vertex (minimum 3 vertices). Handles turn red while Shift is held. |
| Stop editing | Esc | Exits shape edit mode |
| Shape | Default | Notes |
|---|---|---|
Square | 4 vertices, 2-unit half-size | Can be reshaped into any quad |
Circle | 24-segment approximation, radius 2 | Drag the radius handle to resize. Regenerates vertices on radius change. |
Polygon | 12 vertices, radius 3 | Fully freeform — add, remove, and drag vertices freely |
ZoneData asset| Role | Purpose | Fields |
|---|---|---|
| Base | +Defines the encounter table and baseline difficulty | +Encounter Table ID, Difficulty Tier, Encounter Chance | +
| Modifier | +Stacks multiplicatively on top of a Base zone | +Chance Multiplier, Difficulty Tier Bonus | +
| Override | +Replaces everything — towns, story events, safe areas | +Is Safe Zone, Encounter Table ID, Encounter Chance, Difficulty Tier | +
When querying a world position, the ZoneResolver follows this order:
ZoneContextModifiers are multiplicative, so each one is independent:
+Base chance 0.30 x Cursed Road 1.8 x Night Modifier 1.2 = 0.648
+
+ Higher priority values take precedence. When multiple zones of the same role overlap, the highest-priority one wins (for Base and Override) or all are stacked (for Modifier).
+Access via Window → Zone System → Settings. If no settings asset exists, one is created automatically.
+ +| Field | Description | Default |
|---|---|---|
mapPlane | Which two world axes your map lies on | XZ |
zoneDataFolder | Folder path where new ZoneData assets are saved | Assets/ZoneData |
roleColors | Debug color for each zone role (used in scene rendering) | Blue (Base), Yellow (Modifier), Green (Override) |
Each ZoneRole has a configurable color in the settings. When you change a zone’s role in the editor, its debug color is automatically updated to match. Colors are used for:
ZoneRole enum, call SyncRoleEntries() on the settings asset or click the settings menu item — missing roles will be added with a default gray color.
+ The main entry point for runtime zone queries.
+ +// Create the API with a reference to the ZonesObjectHolder
+ZoneSystemApi api = new ZoneSystemApi(zonesObjectHolder);
+
+// Full zone resolution at a world position
+ZoneContext ctx = api.QueryZone(partyWorldPosition);
+
+if(!ctx.isSafe && Random.value < ctx.finalEncounterChance)
+ TriggerEncounter(ctx.encounterTableId, ctx.finalDifficultyTier);
+
+ | Method | Returns | Description |
|---|---|---|
QueryZone(Vector3) | ZoneContext | Full resolution: finds overlapping zones, applies modifiers, returns final context |
GetOverlappingZones(Vector3) | List<ZoneData> | Raw list of all zones containing the position, sorted by descending priority |
IsInSafeZone(Vector3) | bool | Quick check — true if any Override zone with isSafeZone contains the position |
Register(ZoneInstance) | void | Register a dynamically spawned zone |
Unregister(ZoneInstance) | void | Unregister a zone before destroying it |
| Field | Type | Description |
|---|---|---|
encounterTableId | string | ID of the encounter table to use |
finalEncounterChance | float | Final encounter probability (0–1), after modifier stacking |
finalDifficultyTier | DifficultyTier | Final difficulty tier, after modifier bonuses |
isSafe | bool | True if in a safe zone (no encounters) |
resolvedZoneName | string | Name of the zone that “won” resolution (for debug/UI) |
// After instantiating a zone at runtime:
+api.Register(zoneInstance);
+
+// Before destroying:
+api.Unregister(zoneInstance);
+| Value | Description |
|---|---|
Base | Provides the encounter table and baseline difficulty |
Modifier | Mutates difficulty/chance on top of a Base zone |
Override | Completely replaces everything (safe towns, story events) |
| Value | Description |
|---|---|
Square | 4-vertex quadrilateral |
Circle | 24-segment circular approximation with adjustable radius |
Polygon | Freeform polygon with 12 default vertices |
| Value | Int |
|---|---|
Safe | 0 |
Mild | 1 |
Moderate | 2 |
Dangerous | 3 |
Deadly | 4 |
| Value | Axes | Depth |
|---|---|---|
XY | X, Y | Z |
XZ | X, Z | Y |
YZ | Y, Z | X |
Per-zone configuration asset. Created via the Zone Editor or Create → ZoneSystem → Zone Data.
| Field | Type | Description |
|---|---|---|
zoneId | string | Unique identifier |
zoneName | string | Display name |
role | ZoneRole | Base, Modifier, or Override |
priority | int | Higher wins in same-role conflicts |
debugColor | Color | Scene visualization color (auto-set from role) |
shape | ZoneShape | Shape type |
circleRadius | float | Radius (Circle shape only) |
polygon | List<Vector2> | Vertex positions (local to transform) |
Placed on a scene GameObject. References a ZoneData asset and provides spatial queries.
| Field / Method | Description |
|---|---|
data | Reference to the ZoneData asset |
Contains(Vector3, MapPlane) | Returns true if the world position is inside this zone |
RebuildBoundsCache() | Recalculates the AABB cache (call after modifying polygon) |
Scene manager that holds the map plane setting and provides access to all zones.
+| Field / Property | Description |
|---|---|
mapPlane | Which plane the map lies on (XY, XZ, or YZ) |
AllZones | Read-only list of all ZoneInstance objects in the scene |
Static math utilities for polygon operations.
+| Method | Description |
|---|---|
PointInPolygon(Vector2, List<Vector2>) | Ray-casting point-in-polygon test (Jordan curve theorem) |
PointInPolygon(Vector3, List<Vector2>, MapPlane) | Projects world position to plane, then tests |
Centroid(List<Vector2>) | Average center of polygon vertices |
Bounds(List<Vector2>) | Axis-aligned bounding box (min, max) |
PointInBounds(Vector2, Vector2, Vector2) | Fast AABB pre-check |
Triangulate(List<Vector2>) | Ear-clipping triangulation for concave polygon rendering |
Converts between 3D world positions and 2D plane coordinates.
+| Method | Description |
|---|---|
ProjectToPlane(Vector3, MapPlane) | 3D world → 2D plane coordinates |
UnprojectFromPlane(Vector2, MapPlane, float) | 2D plane coordinates → 3D world |
Generates default polygon vertices for each shape type.
+| Method | Description |
|---|---|
CreateDefault(ZoneShape) | Returns default vertices for the given shape |
CreateSquare(float) | 4-vertex square with given half-size |
CreateCircle(float, int) | N-segment circle approximation |
CreatePolygon(float, int) | Regular polygon with N vertices |
RegenerateCircle(ZoneData) | Rebuilds circle vertices from current radius |
Pure logic for resolving overlapping zones into a single ZoneContext.
| Method | Description |
|---|---|
Resolve(List<ZoneData>) | Takes overlapping zone data, applies role priority and modifier stacking, returns ZoneContext |
Serializes scene zones to a JSON structure for runtime loading.
+| Method | Description |
|---|---|
BuildExport(ZoneInstance[], MapPlane) | Builds the export data structure from scene instances |
ToJson(ZoneExportRoot, bool) | Converts to JSON string (optionally pretty-printed) |
In the Zone Editor window, expand Export Zones to JSON, set the output path, and click Export Now.
+ +string json = File.ReadAllText(Application.streamingAssetsPath + "/zones.json");
+ZoneExportRoot root = JsonUtility.FromJson<ZoneExportRoot>(json);
+
+ Each zone is exported as a ZoneExportEntry containing all zone data fields plus the world-space polygon coordinates and transform position.
| Key | Context | Action |
|---|---|---|
| Esc | Scene view, shape editing active | Stop editing the zone shape |
| Ctrl + Click | Scene view, shape editing active | Insert a vertex on the nearest edge |
| Shift + Click | Scene view, shape editing active | Delete the clicked vertex (min 3) |
| Menu Path | Description |
|---|---|
| Window → Zone System → Zone Editor | Opens the main Zone Editor window |
| Window → Zone System → Settings | Selects (or creates) the ZoneEditorSettings asset |
| Window → Zone System → Documentation | Opens this documentation in your default browser |
| Jovian → ZoneSystem → Zone Editor Settings | Create menu for new ZoneEditorSettings asset |
| ZoneSystem → Zone Data | Create menu for new ZoneData asset |
+ Jovian Zone System v0.1.0 — com.jovian.zonesystem +
+ +