Compare commits

..

No commits in common. "f5598d3ea2346a5cc01891921e1f1107d0cfb44f" and "7c8f817310663baf6c96d7137582d2025eee6f6e" have entirely different histories.

6 changed files with 147 additions and 22 deletions

View file

@ -3,9 +3,9 @@
-- https://www.phpmyadmin.net/ -- https://www.phpmyadmin.net/
-- --
-- Host: localhost -- Host: localhost
-- Generation Time: Jul 20, 2024 at 02:33 PM -- Generation Time: May 12, 2024 at 03:59 PM
-- Server version: 11.4.2-MariaDB -- Server version: 11.3.2-MariaDB
-- PHP Version: 8.3.9 -- PHP Version: 8.3.6
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
START TRANSACTION; START TRANSACTION;
@ -20,6 +20,8 @@ SET time_zone = "+00:00";
-- --
-- Database: `zdenekborovec` -- Database: `zdenekborovec`
-- --
CREATE DATABASE IF NOT EXISTS `zdenekborovec` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE `zdenekborovec`;
-- -------------------------------------------------------- -- --------------------------------------------------------
@ -27,15 +29,13 @@ SET time_zone = "+00:00";
-- Table structure for table `blogposts` -- Table structure for table `blogposts`
-- --
CREATE TABLE IF NOT EXISTS `blogposts` ( CREATE TABLE `blogposts` (
`blogpost_id` uuid NOT NULL DEFAULT uuid() COMMENT 'uuid of the blogpost', `blogpost_id` uuid NOT NULL DEFAULT uuid() COMMENT 'uuid of the blogpost',
`readable_address` varchar(64) DEFAULT NULL COMMENT 'Human-readable addressing alternative for an article. For example, blogpost with readable_address = "example" can be accessed by article.php?address=example.',
`title` varchar(64) DEFAULT NULL COMMENT 'title of the blogpost', `title` varchar(64) DEFAULT NULL COMMENT 'title of the blogpost',
`abstract` varchar(512) DEFAULT NULL COMMENT 'short version of the blogpost to be displayed as preview, usually the first paragraph of the real article.', `abstract` varchar(512) DEFAULT NULL COMMENT 'short version of the blogpost to be displayed as preview, usually the first paragraph of the real article.',
`content` text DEFAULT NULL COMMENT 'html for the article', `content` text DEFAULT NULL COMMENT 'html for the article',
`date_posted` datetime NOT NULL DEFAULT current_timestamp() COMMENT 'Datetime at which the article was posted.', `date_posted` datetime NOT NULL DEFAULT current_timestamp() COMMENT 'Datetime at which the article was posted.',
`date_edited` datetime NOT NULL DEFAULT current_timestamp() COMMENT 'Timestamp at the lasted edit.', `date_edited` datetime NOT NULL DEFAULT current_timestamp() COMMENT 'Timestamp at the lasted edit.'
PRIMARY KEY (`blogpost_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- -------------------------------------------------------- -- --------------------------------------------------------
@ -44,14 +44,13 @@ CREATE TABLE IF NOT EXISTS `blogposts` (
-- Table structure for table `blogpost_comments` -- Table structure for table `blogpost_comments`
-- --
CREATE TABLE IF NOT EXISTS `blogpost_comments` ( CREATE TABLE `blogpost_comments` (
`comment_id` uuid NOT NULL DEFAULT uuid() COMMENT 'ID of the comment, PK.', `comment_id` uuid NOT NULL DEFAULT uuid() COMMENT 'ID of the comment, PK.',
`parent_id` uuid DEFAULT NULL COMMENT 'If this is a response to a comment, this is the id of that parent comment.', `parent_id` uuid DEFAULT NULL COMMENT 'If this is a response to a comment, this is the id of that parent comment.',
`blogpost_id` uuid NOT NULL COMMENT 'ID of the blogpost this comment is under.', `blogpost_id` uuid NOT NULL COMMENT 'ID of the blogpost this comment is under.',
`poster_id` uuid DEFAULT NULL COMMENT ' ID of the user who posted this comment. ', `poster_id` uuid DEFAULT NULL COMMENT ' ID of the user who posted this comment. ',
`timestamp` timestamp NOT NULL DEFAULT current_timestamp() COMMENT 'Timestamp when the comment was posted.', `timestamp` timestamp NOT NULL DEFAULT current_timestamp() COMMENT 'Timestamp when the comment was posted.',
`content` mediumtext NOT NULL COMMENT 'Content of the comment. Stored as markdown.', `content` mediumtext NOT NULL COMMENT 'Content of the comment. Stored as markdown.'
PRIMARY KEY (`comment_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Comments on blogposts.'; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Comments on blogposts.';
-- -------------------------------------------------------- -- --------------------------------------------------------
@ -60,11 +59,9 @@ CREATE TABLE IF NOT EXISTS `blogpost_comments` (
-- Table structure for table `blogpost_has_tag` -- Table structure for table `blogpost_has_tag`
-- --
CREATE TABLE IF NOT EXISTS `blogpost_has_tag` ( CREATE TABLE `blogpost_has_tag` (
`blogpost_id` uuid NOT NULL, `blogpost_id` uuid NOT NULL,
`tag_id` int(11) NOT NULL, `tag_id` int(11) NOT NULL
KEY `blogpost_id` (`blogpost_id`),
KEY `tag_id` (`tag_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- -------------------------------------------------------- -- --------------------------------------------------------
@ -73,11 +70,10 @@ CREATE TABLE IF NOT EXISTS `blogpost_has_tag` (
-- Table structure for table `blogpost_tags` -- Table structure for table `blogpost_tags`
-- --
CREATE TABLE IF NOT EXISTS `blogpost_tags` ( CREATE TABLE `blogpost_tags` (
`tag_id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID of the tag, primary key.', `tag_id` int(11) NOT NULL COMMENT 'ID of the tag, primary key.',
`name` varchar(32) NOT NULL COMMENT 'Name of the tag, will be displayed.', `name` varchar(32) NOT NULL COMMENT 'Name of the tag, will be displayed.',
`color` varchar(32) NOT NULL COMMENT 'CSS color string, will be displayed.', `color` varchar(32) NOT NULL COMMENT 'CSS color string, will be displayed.'
PRIMARY KEY (`tag_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Tags that can be used to tag and filter blogposts.'; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Tags that can be used to tag and filter blogposts.';
-- -------------------------------------------------------- -- --------------------------------------------------------
@ -86,16 +82,60 @@ CREATE TABLE IF NOT EXISTS `blogpost_tags` (
-- Table structure for table `users` -- Table structure for table `users`
-- --
CREATE TABLE IF NOT EXISTS `users` ( CREATE TABLE `users` (
`user_id` uuid NOT NULL DEFAULT uuid() COMMENT 'UUID of the user. Primary key.', `user_id` uuid NOT NULL DEFAULT uuid() COMMENT 'UUID of the user. Primary key.',
`username` varchar(64) NOT NULL COMMENT 'Display name of the user.', `username` varchar(64) NOT NULL COMMENT 'Display name of the user.',
`password` varchar(255) NOT NULL COMMENT 'password encrypted by password_hash().', `password` varchar(255) NOT NULL COMMENT 'password encrypted by password_hash().',
`created_at` datetime NOT NULL DEFAULT current_timestamp() COMMENT 'Timestamp at account creation.', `created_at` datetime NOT NULL DEFAULT current_timestamp() COMMENT 'Timestamp at account creation.',
`permissions` bit(8) NOT NULL DEFAULT b'0' COMMENT 'Permission mask for the user. Rules (from left to right):\r\n0: Can post blogposts.\r\n1: reserved\r\n2: reserved\r\n3: reserved\r\n4: reserved\r\n5: reserved\r\n6: reserved\r\n7: reserved', `permissions` bit(8) NOT NULL DEFAULT b'0' COMMENT 'Permission mask for the user. Rules (from left to right):\r\n0: Can post blogposts.\r\n1: reserved\r\n2: reserved\r\n3: reserved\r\n4: reserved\r\n5: reserved\r\n6: reserved\r\n7: reserved'
PRIMARY KEY (`user_id`),
UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Indexes for dumped tables
--
--
-- Indexes for table `blogposts`
--
ALTER TABLE `blogposts`
ADD PRIMARY KEY (`blogpost_id`);
--
-- Indexes for table `blogpost_comments`
--
ALTER TABLE `blogpost_comments`
ADD PRIMARY KEY (`comment_id`);
--
-- Indexes for table `blogpost_has_tag`
--
ALTER TABLE `blogpost_has_tag`
ADD KEY `blogpost_id` (`blogpost_id`),
ADD KEY `tag_id` (`tag_id`);
--
-- Indexes for table `blogpost_tags`
--
ALTER TABLE `blogpost_tags`
ADD PRIMARY KEY (`tag_id`);
--
-- Indexes for table `users`
--
ALTER TABLE `users`
ADD PRIMARY KEY (`user_id`),
ADD UNIQUE KEY `username` (`username`);
--
-- AUTO_INCREMENT for dumped tables
--
--
-- AUTO_INCREMENT for table `blogpost_tags`
--
ALTER TABLE `blogpost_tags`
MODIFY `tag_id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID of the tag, primary key.';
-- --
-- Constraints for dumped tables -- Constraints for dumped tables
-- --

Binary file not shown.

After

Width:  |  Height:  |  Size: 7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View file

@ -0,0 +1,85 @@
<?php
$PageTitle="Zdenek: Blog";
$COMMONS = $_SERVER['DOCUMENT_ROOT'] . "/../common";
include_once($COMMONS."/header.php");
?>
<article>
<h2>
Godot spell casting system prototype.
</h2>
<div class="blog-metadata">
<span class="blog-tag" style="background-color: cornflowerblue">
godot
</span>
<span class="blog-tag" style="background-color: khaki">
game-dev
</span>
<span class="blog-tag" style="background-color: sienna">
the-labyrinth-II
</span>
<span class="blog-publish-date">
Published on: 2024-01-13
</span>
</div>
<p>
I wanted to implement this system in my game "The Labyrinth II" ever since I was maybe 13, but the project failed a few times and for the last few years it has been just rotting in the back of my mind. Well, I have decided to return to it again.
</p>
<p>
The system is inspired by the spell casting system in the videogame <a href="https://en.wikipedia.org/wiki/Dungeon_Master_(video_game)">Dungeon Master</a>. I really liked the way you had to actually study the spells and then cast them. This was not selecting a option in a menu, it was way more involved - and exciting. Originally, when I was thinking about the spell system I wanted in my game I just wanted to pretty much copy their system, but at some point, this appeared to me as a better idea. I think it will allow you to feel not like you are uttering the spells, but insted like you are casting them with your wand, or finger, or a screwdiver or whatever. Plus it gives you a nice natural way to upgrade it once you do get a better mana-channeler: just increase the dimension of the matrix! Allows you to cast new, more complicated spells, and does so in a natural way only once you've mastered the simpler spell matrix.
</p>
<p>
Now, I have to admit, that I am not at all sure if this system will actually work in a modern game, or, really any game that's not basically turn-based. I do have some ideas how to solve these problems (including a time slow-down mechanic), but that is too far in the future now. I am planning on taking this very easy and slow, more focused on having fun and exploring the godot engine, rather than trying to sprint to the goal of a finished game.
</p>
<div class="image-gallery">
<h2> Gallery </h2>
<div>
<div>
<img src="http://www.zdenekborovec-dev.cz/blog/godot_spell_system_prototype/nodes.png" alt="A screenshot of the spell casting system.">
<p>
A path drawn between some nodes, this is what the spell casting looks like.
</p>
</div>
<div>
<img src="http://www.zdenekborovec-dev.cz/blog/godot_spell_system_prototype/console.png" alt="A screenshot showing cast spells log.">
<p>
A log from the spellbook, it detects all entered paths. It also has a dictionary of paths and spells, if you enter a path that corresponds to a spell, you cast it!
</p>
</div>
<div>
<img src="http://www.zdenekborovec-dev.cz/blog/godot_spell_system_prototype/spellbookexports.png" alt="A screenshot from the godot editor showing node export values.">
<p>
This is how I can interact with the spellbook from the editor. I can add in nodes (it then works with them automagically, so I am not anyhow limited to the 3x3 grid). And I can also add in the spell paths and names (I can then use these to emit a spell_cast event with its name, or something like that).
</p>
</div>
</div>
</div>
<p>
Once I tried actually using it in a control node, I found out the mapping of the mouse was completely off, I remade it into control nodes, which I am actually happy about as I feel like the nodes being buttons makes more sense than them being sprites with a collision box that only reacts to the mouse, or whatever I was using, I don't wven remember, but it was wacky :D. But I encountered a problem! I still had to use the Line2D, which is a Node2D. And it's position just did not map well. Through experimentation I found out that it was using the position as relating to its scene origin, but once the control scene was inserted into a control container, it got scaled, as controls should, but it was now offset and the line was not. The only solution I could find was putting the SpellBook scene inside of a MarginContainer, and offseting it using margins and thus preserving its 'relative origin', instead of letting it stretch. I do not like this solution as it requires manual fiddling if you want to change up the HUD, but it was the only solution I could find.
</p>
<p>
Here is a bit of code, so that I can test my code block css:
</p>
<code>
## Add a node to current spell
func _on_spellnode_entered(node: SpellNode)-&gt;void:
if is_receiving_spell &amp;&amp; not spell_builder.has(node):
# Append node to the spell builder
spell_builder.append(node);
# Add new point to the spell line and set the old top to the new nodes position
spell_line.add_point(node.position)
spell_line.set_point_position(spell_line.get_point_count() - 2, node.position)
</code>
<p>
I would like to add some kind of syntax highlighting, but from my research I'd have to write a php function for that, as css cannot look for key words, and writing a bunch of php is not something I am currently in the mood for, so this will have to do, for now.
</p>
</article>
<?php
include_once($COMMONS."/footer.php");
?>

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB