oh no she got squish ;0;

This commit is contained in:
Rowan 2024-12-01 01:09:56 -06:00
parent ac32193001
commit 881dd2d453
8 changed files with 194 additions and 220 deletions

View file

@ -0,0 +1,87 @@
{% extends "../../../layouts/post.html" %}
{% block article %}
# A Query about Game State
## Preface
I'm an indie game dev that has an interest in making tools that I think would improve my life as a game developer in the hopes that it can help others. I'm not an expert in any of the topics that this article covers. I have no formal education in game engine development or architecture, systems programming, or anything else. I went to university for Computer Science with a specialization in game design & development when I was in my early 20s and the only thing I learned is that there are better ways to spend tens of thousands of dollars.
Everything in this article is drawn directly from my experiences working in tech and game development.
## Theseus' Shield
In the context of game design and development, object oriented data modeling can feel intuitive. Players, NPCs, and Enemies can all derive from a common "Creature" class which handle things like health and damage. Weapons, armor, and consumables can derive from a common Item class which handle inventory management.
Thinking exclusively in terms of hierarchal, nested patterns can come at a cost: software brittleness and inflexible design. Let's use our base `Item` class as an example.
```cs
abstract class Item {
public string Name { get; protected set; }
}
abstract class Weapon: Item {
public float Damage { get; protected set; }
public float Range { get; protected set; }
}
abstract class Armor: Item {
public float Defense { get; protected set; }
}
class Sword: Weapon {}
class Bow: Weapon {}
class Helmet: Armor {}
class Shield: Armor {}
```
In the above scenario, we have [three layers of inheritance](https://wiki.c2.com/?MaxThreeLayersOfInheritance). We can imagine that `Item` handles behaviors like item management such as being added or removed from an inventory and highly generic item behavior. `Weapon` would then be responsible for an item which is capable of dealing damage at any range. We can expect that the specifics of its attack behavior would be implemented by a subclass. Similarly for `Armor`, this would handle generic damage interactions such as common mitigation or avoidance calculations while leaving specific implementation details to its subclasses.
Seasoned game devs, disciplined object-oriented programmers, and existing ECS developers can likely already see what comes next. A new requirement.
How do we add a Spiked Shield item -- one which derives the behaviors of `Weapon` and `Armor`? If we were using a language which supports multiple inheritance this could potentially be a nonissue: except that multiple inheritance is often [purposefully missing](https://en.wikipedia.org/wiki/Multiple_inheritance#The_diamond_problem) in many languages. We could decide that the item belongs more to one class than the other and just duplicate the missing behavior but these types of decisions often introduce unforeseen complexity: will the damage algorithm need to do a specific type check for `SpikedShield`? What about the equipment screen? And of course, what happens when we need to implement a damaging potion?
Perhaps the most appropriate solution this case would be to forego the inheritance pattern in favor of [composition](https://en.wikipedia.org/wiki/Composition_over_inheritance). In C#, this could be achieved with `interfaces` and default implementations.
```cs
interface ICollectable {
void Take();
void Remove();
}
interface IDamaging {
void ApplyDamage(float value) {
// ...
}
}
interface IDamageable {
void ReceiveDamage(float value) {
// ...
}
}
class SpikedShield: ICollectable, IDamaging, IDamageable {}
```
We can use this approach to refactor our existing items and systems to derive/override only the behaviors they use. The respective systems for these interfaces now only need to check for the existence of these interfaces in order to act on them.
Engines like Unity and Godot use variations of the [Entity-Component (EC)](https://gameprogrammingpatterns.com/component.html) pattern (similar to but distinct from Entity-Component-System (ECS)). These patterns favor composition over inheritance by allowing developers to isolate behaviors into discrete components that can be applied to entities. In the Spiked Shield example, a developer could make a "Damage Source" and "Damage Target" component and add both to the item. In essence, this is the same as the interface-based approach.
Unfortunately, these patterns suffer a much bigger issue that is much more difficult to solve.
## In search of loot
Managing game state is difficult. As a game grows, so too does the amount of amount of objects active at any given time. Dozens, hundreds, or even thousands of entities each with their own behaviors, goals, and concerns that interact with each other in different ways. This explosion in complexity can be exceedingly hard to manage even in games that are small in scope. Games, even at their simplest, tend to be *highly* complex.
## Enter ECS
ECS solves many of the problems presented by object oriented programming patterns but it's still in its infancy.
## Issues with ECS
Mental modeling is hard. Complex queries are hard. ECS is hard.
## A Solution?
## Going forward
## What I'm looking for
{% endblock article %}

View file

@ -0,0 +1,3 @@
title = "A Query about Game State"
created_date = "2024-11-30"

14
dev Executable file
View file

@ -0,0 +1,14 @@
#!/usr/bin/env sh
if [ -z "$(which inotifywait)" ]; then
echo "inotifywait not installed."
echo "In most distros, it is available in the inotify-tools package."
exit 1
fi
inotifywait --recursive --monitor --format "%e %w%f" \
--event modify,move,create,delete ./content ./layouts \
| while read changed; do
echo $changed
eval "roxy_cli content dist"
done

298
package-lock.json generated
View file

@ -9,7 +9,7 @@
"version": "1.0.0",
"license": "ISC",
"devDependencies": {
"wrangler": "^3.81.0"
"wrangler": "^3.91.0"
}
},
"node_modules/@cloudflare/kv-asset-handler": {
@ -26,9 +26,9 @@
}
},
"node_modules/@cloudflare/workerd-darwin-64": {
"version": "1.20241011.1",
"resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20241011.1.tgz",
"integrity": "sha512-gZ2PrMCQ4WdDCB+V6vsB2U2SyYcmgaGMEa3GGjcUfC79L/8so3Vp/bO0eCoLmvttRs39wascZ+JiWL0HpcZUgA==",
"version": "1.20241106.1",
"resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20241106.1.tgz",
"integrity": "sha512-zxvaToi1m0qzAScrxFt7UvFVqU8DxrCO2CinM1yQkv5no7pA1HolpIrwZ0xOhR3ny64Is2s/J6BrRjpO5dM9Zw==",
"cpu": [
"x64"
],
@ -43,9 +43,9 @@
}
},
"node_modules/@cloudflare/workerd-darwin-arm64": {
"version": "1.20241011.1",
"resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20241011.1.tgz",
"integrity": "sha512-c26TYtS0e3WZ09nL/a8YaEqveCsTlgDm12ehPMNua9u68sh1KzETMl2G45O934m8UrI3Rhpv2TTecO0S5b9exA==",
"version": "1.20241106.1",
"resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20241106.1.tgz",
"integrity": "sha512-j3dg/42D/bPgfNP3cRUBxF+4waCKO/5YKwXNj+lnVOwHxDu+ne5pFw9TIkKYcWTcwn0ZUkbNZNM5rhJqRn4xbg==",
"cpu": [
"arm64"
],
@ -60,9 +60,9 @@
}
},
"node_modules/@cloudflare/workerd-linux-64": {
"version": "1.20241011.1",
"resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20241011.1.tgz",
"integrity": "sha512-pl4xvHNXnm3cYh5GwHadOTQRWt4Ih/gzCOb6RW4n78oNQQydFvpwqYAjbYk32y485feLhdTKXut/MgZAyWnKyQ==",
"version": "1.20241106.1",
"resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20241106.1.tgz",
"integrity": "sha512-Ih+Ye8E1DMBXcKrJktGfGztFqHKaX1CeByqshmTbODnWKHt6O65ax3oTecUwyC0+abuyraOpAtdhHNpFMhUkmw==",
"cpu": [
"x64"
],
@ -77,9 +77,9 @@
}
},
"node_modules/@cloudflare/workerd-linux-arm64": {
"version": "1.20241011.1",
"resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20241011.1.tgz",
"integrity": "sha512-I4HAF2Qe8xgIjAdE53viT2fDdHXkrb3Be0L3eWeeP5SEkOtQ4cHLqsOV7yhUWOJpHiI1XCDcf+wdfn0PB/EngQ==",
"version": "1.20241106.1",
"resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20241106.1.tgz",
"integrity": "sha512-mdQFPk4+14Yywn7n1xIzI+6olWM8Ybz10R7H3h+rk0XulMumCWUCy1CzIDauOx6GyIcSgKIibYMssVHZR30ObA==",
"cpu": [
"arm64"
],
@ -94,9 +94,9 @@
}
},
"node_modules/@cloudflare/workerd-windows-64": {
"version": "1.20241011.1",
"resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20241011.1.tgz",
"integrity": "sha512-oVr1Cb7NkDpukd7v68FdxOH8vaHRSzHkX9uE/IttHd2yPK6mwOS220nIxK9UMcx5CwZmrgphRwtZwSYVk/lREQ==",
"version": "1.20241106.1",
"resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20241106.1.tgz",
"integrity": "sha512-4rtcss31E/Rb/PeFocZfr+B9i1MdrkhsTBWizh8siNR4KMmkslU2xs2wPaH1z8+ErxkOsHrKRa5EPLh5rIiFeg==",
"cpu": [
"x64"
],
@ -111,9 +111,9 @@
}
},
"node_modules/@cloudflare/workers-shared": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/@cloudflare/workers-shared/-/workers-shared-0.6.0.tgz",
"integrity": "sha512-rfUCvb3hx4AsvdUZsxgk9lmgEnQehqV3jdtXLP/Xr0+P56n11T/0nXNMzmn7Nnv+IJFOV6X9NmFhuMz4sBPw7w==",
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/@cloudflare/workers-shared/-/workers-shared-0.9.0.tgz",
"integrity": "sha512-eP6Ir45uPbKnpADVzUCtkRUYxYxjB1Ew6n/whTJvHu8H4m93USHAceCMm736VBZdlxuhXXUjEP3fCUxKPn+cfw==",
"dev": true,
"license": "MIT OR Apache-2.0",
"dependencies": {
@ -594,9 +594,9 @@
}
},
"node_modules/acorn": {
"version": "8.13.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.13.0.tgz",
"integrity": "sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==",
"version": "8.14.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
"integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==",
"dev": true,
"license": "MIT",
"bin": {
@ -619,20 +619,6 @@
"node": ">=0.4.0"
}
},
"node_modules/anymatch": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
"integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
"dev": true,
"license": "ISC",
"dependencies": {
"normalize-path": "^3.0.0",
"picomatch": "^2.0.4"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/as-table": {
"version": "1.0.55",
"resolved": "https://registry.npmjs.org/as-table/-/as-table-1.0.55.tgz",
@ -643,19 +629,6 @@
"printable-characters": "^1.0.42"
}
},
"node_modules/binary-extensions": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
"integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/blake3-wasm": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/blake3-wasm/-/blake3-wasm-2.1.5.tgz",
@ -663,19 +636,6 @@
"dev": true,
"license": "MIT"
},
"node_modules/braces": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
"dev": true,
"license": "MIT",
"dependencies": {
"fill-range": "^7.1.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/capnp-ts": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/capnp-ts/-/capnp-ts-0.7.0.tgz",
@ -688,28 +648,19 @@
}
},
"node_modules/chokidar": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
"integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz",
"integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==",
"dev": true,
"license": "MIT",
"dependencies": {
"anymatch": "~3.1.2",
"braces": "~3.0.2",
"glob-parent": "~5.1.2",
"is-binary-path": "~2.1.0",
"is-glob": "~4.0.1",
"normalize-path": "~3.0.0",
"readdirp": "~3.6.0"
"readdirp": "^4.0.1"
},
"engines": {
"node": ">= 8.10.0"
"node": ">= 14.16.0"
},
"funding": {
"url": "https://paulmillr.com/funding/"
},
"optionalDependencies": {
"fsevents": "~2.3.2"
}
},
"node_modules/cookie": {
@ -729,6 +680,17 @@
"dev": true,
"license": "MIT"
},
"node_modules/date-fns": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-4.1.0.tgz",
"integrity": "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==",
"dev": true,
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/kossnocorp"
}
},
"node_modules/debug": {
"version": "4.3.7",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
@ -825,19 +787,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/fill-range": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
"dev": true,
"license": "MIT",
"dependencies": {
"to-regex-range": "^5.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/fsevents": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
@ -874,19 +823,6 @@
"source-map": "^0.6.1"
}
},
"node_modules/glob-parent": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
"dev": true,
"license": "ISC",
"dependencies": {
"is-glob": "^4.0.1"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/glob-to-regexp": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
@ -907,19 +843,6 @@
"node": ">= 0.4"
}
},
"node_modules/is-binary-path": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
"dev": true,
"license": "MIT",
"dependencies": {
"binary-extensions": "^2.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/is-core-module": {
"version": "2.15.1",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz",
@ -936,38 +859,12 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
"node_modules/itty-time": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/itty-time/-/itty-time-1.0.6.tgz",
"integrity": "sha512-+P8IZaLLBtFv8hCkIjcymZOp4UJ+xW6bSlQsXGqrkmJh7vSiMFSlNne0mCYagEE0N7HDNR5jJBRxwN0oYv61Rw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/is-glob": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
"dev": true,
"license": "MIT",
"dependencies": {
"is-extglob": "^2.1.1"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/is-number": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.12.0"
}
"license": "MIT"
},
"node_modules/magic-string": {
"version": "0.25.9",
@ -993,9 +890,9 @@
}
},
"node_modules/miniflare": {
"version": "3.20241011.0",
"resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20241011.0.tgz",
"integrity": "sha512-Mb3U9+QvKgIUl9LgHwBxEz8WajMRYqO5mMHRtO8yHjNCLGh24I6Ts9z13zRAYGPDd1xBQ1o983fHT9S+tn6r+A==",
"version": "3.20241106.1",
"resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20241106.1.tgz",
"integrity": "sha512-dM3RBlJE8rUFxnqlPCaFCq0E7qQqEQvKbYX7W/APGCK+rLcyLmEBzC4GQR/niXdNM/oV6gdg9AA50ghnn2ALuw==",
"dev": true,
"license": "MIT",
"dependencies": {
@ -1007,8 +904,8 @@
"glob-to-regexp": "^0.4.1",
"stoppable": "^1.1.0",
"undici": "^5.28.4",
"workerd": "1.20241011.1",
"ws": "^8.17.1",
"workerd": "1.20241106.1",
"ws": "^8.18.0",
"youch": "^3.2.2",
"zod": "^3.22.3"
},
@ -1065,16 +962,6 @@
"node": ">= 6.13.0"
}
},
"node_modules/normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/ohash": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/ohash/-/ohash-1.1.4.tgz",
@ -1103,19 +990,6 @@
"dev": true,
"license": "MIT"
},
"node_modules/picomatch": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8.6"
},
"funding": {
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/printable-characters": {
"version": "1.0.42",
"resolved": "https://registry.npmjs.org/printable-characters/-/printable-characters-1.0.42.tgz",
@ -1124,16 +998,17 @@
"license": "Unlicense"
},
"node_modules/readdirp": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz",
"integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==",
"dev": true,
"license": "MIT",
"dependencies": {
"picomatch": "^2.2.1"
},
"engines": {
"node": ">=8.10.0"
"node": ">= 14.16.0"
},
"funding": {
"type": "individual",
"url": "https://paulmillr.com/funding/"
}
},
"node_modules/resolve": {
@ -1264,23 +1139,10 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"is-number": "^7.0.0"
},
"engines": {
"node": ">=8.0"
}
},
"node_modules/tslib": {
"version": "2.8.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.0.tgz",
"integrity": "sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==",
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
"dev": true,
"license": "0BSD"
},
@ -1313,9 +1175,9 @@
},
"node_modules/unenv": {
"name": "unenv-nightly",
"version": "2.0.0-20241009-125958-e8ea22f",
"resolved": "https://registry.npmjs.org/unenv-nightly/-/unenv-nightly-2.0.0-20241009-125958-e8ea22f.tgz",
"integrity": "sha512-hRxmKz1iSVRmuFx/vBdPsx7rX4o7Cas9vdjDNeUeWpQTK2LzU3Xy3Jz0zbo7MJX0bpqo/LEFCA+GPwsbl6zKEQ==",
"version": "2.0.0-20241121-161142-806b5c0",
"resolved": "https://registry.npmjs.org/unenv-nightly/-/unenv-nightly-2.0.0-20241121-161142-806b5c0.tgz",
"integrity": "sha512-RnFOasE/O0Q55gBkNB1b84OgKttgLEijGO0JCWpbn+O4XxpyCQg89NmcqQ5RGUiy4y+rMIrKzePTquQcLQF5pQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@ -1326,9 +1188,9 @@
}
},
"node_modules/workerd": {
"version": "1.20241011.1",
"resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20241011.1.tgz",
"integrity": "sha512-ORobT1XDkE+p+36yk6Szyw68bWuGSmuwIlDnAeUOfnYunb/Txt0jg7ydzfwr4UIsof7AH5F1nqZms5PWLu05yw==",
"version": "1.20241106.1",
"resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20241106.1.tgz",
"integrity": "sha512-1GdKl0kDw8rrirr/ThcK66Kbl4/jd4h8uHx5g7YHBrnenY5SX1UPuop2cnCzYUxlg55kPjzIqqYslz1muRFgFw==",
"dev": true,
"hasInstallScript": true,
"license": "Apache-2.0",
@ -1339,36 +1201,38 @@
"node": ">=16"
},
"optionalDependencies": {
"@cloudflare/workerd-darwin-64": "1.20241011.1",
"@cloudflare/workerd-darwin-arm64": "1.20241011.1",
"@cloudflare/workerd-linux-64": "1.20241011.1",
"@cloudflare/workerd-linux-arm64": "1.20241011.1",
"@cloudflare/workerd-windows-64": "1.20241011.1"
"@cloudflare/workerd-darwin-64": "1.20241106.1",
"@cloudflare/workerd-darwin-arm64": "1.20241106.1",
"@cloudflare/workerd-linux-64": "1.20241106.1",
"@cloudflare/workerd-linux-arm64": "1.20241106.1",
"@cloudflare/workerd-windows-64": "1.20241106.1"
}
},
"node_modules/wrangler": {
"version": "3.81.0",
"resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.81.0.tgz",
"integrity": "sha512-sa5dhLJAMmYtl/dJWDJ92sdnKj0VUC0DYBfGqbhd5xn7CDdn1oGhICDXtx2E6BNhQ1L+4d9oAcP/oQvOs5gKLA==",
"version": "3.91.0",
"resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.91.0.tgz",
"integrity": "sha512-Hdzn6wbY9cz5kL85ZUvWLwLIH7nPaEVRblfms40jhRf4qQO/Zf74aFlku8rQFbe8/2aVZFaxJVfBd6JQMeMSBQ==",
"dev": true,
"license": "MIT OR Apache-2.0",
"dependencies": {
"@cloudflare/kv-asset-handler": "0.3.4",
"@cloudflare/workers-shared": "0.6.0",
"@cloudflare/workers-shared": "0.9.0",
"@esbuild-plugins/node-globals-polyfill": "^0.2.3",
"@esbuild-plugins/node-modules-polyfill": "^0.2.2",
"blake3-wasm": "^2.1.5",
"chokidar": "^3.5.3",
"chokidar": "^4.0.1",
"date-fns": "^4.1.0",
"esbuild": "0.17.19",
"miniflare": "3.20241011.0",
"itty-time": "^1.0.6",
"miniflare": "3.20241106.1",
"nanoid": "^3.3.3",
"path-to-regexp": "^6.3.0",
"resolve": "^1.22.8",
"resolve.exports": "^2.0.2",
"selfsigned": "^2.0.1",
"source-map": "^0.6.1",
"unenv": "npm:unenv-nightly@2.0.0-20241009-125958-e8ea22f",
"workerd": "1.20241011.1",
"unenv": "npm:unenv-nightly@2.0.0-20241121-161142-806b5c0",
"workerd": "1.20241106.1",
"xxhash-wasm": "^1.0.1"
},
"bin": {
@ -1382,7 +1246,7 @@
"fsevents": "~2.3.2"
},
"peerDependencies": {
"@cloudflare/workers-types": "^4.20241011.0"
"@cloudflare/workers-types": "^4.20241106.0"
},
"peerDependenciesMeta": {
"@cloudflare/workers-types": {

View file

@ -3,14 +3,15 @@
"version": "1.0.0",
"main": "index.js",
"scripts": {
"dev": "wrangler pages dev dist --live-reload",
"deploy": "wrangler pages deploy dist --project-name kitsunecafe"
"watch": "./dev &",
"dev": "npm run watch; wrangler pages dev --live-reload",
"deploy": "wrangler pages deploy --project-name kitsunecafe"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": "",
"devDependencies": {
"wrangler": "^3.81.0"
"wrangler": "^3.91.0"
}
}

View file

@ -58,6 +58,7 @@
border-radius: 50%;
height: 64px;
width: 64px;
max-width: initial;
}
.message .content {

1
static/static Symbolic link
View file

@ -0,0 +1 @@
/home/rowan/Development/kitsu.cafe/static

3
wrangler.toml Normal file
View file

@ -0,0 +1,3 @@
name = "kitsunecafe"
pages_build_output_dir = "./dist"
compatibility_date = "2024-10-04"