This commit is contained in:
parent
33c20bf59d
commit
a92bfc1d22
14 changed files with 2629 additions and 59 deletions
|
|
@ -1290,4 +1290,111 @@ BEGIN
|
|||
) THEN
|
||||
ALTER TABLE realms ADD COLUMN live_started_at TIMESTAMP WITH TIME ZONE;
|
||||
END IF;
|
||||
END $$;
|
||||
END $$;
|
||||
|
||||
-- ============================================
|
||||
-- PYRAMID PIXEL WORLD (Collaborative Canvas)
|
||||
-- ============================================
|
||||
|
||||
-- Pyramid world configuration (singleton)
|
||||
CREATE TABLE IF NOT EXISTS pyramid_world (
|
||||
id INTEGER PRIMARY KEY DEFAULT 1 CHECK (id = 1),
|
||||
name VARCHAR(100) DEFAULT 'The Pyramid',
|
||||
is_active BOOLEAN DEFAULT true,
|
||||
total_pixels_placed BIGINT DEFAULT 0,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Insert default pyramid world row
|
||||
INSERT INTO pyramid_world (id, name, is_active)
|
||||
VALUES (1, 'The Pyramid', true)
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
|
||||
-- Trigger for pyramid_world updated_at
|
||||
DROP TRIGGER IF EXISTS update_pyramid_world_updated_at ON pyramid_world;
|
||||
CREATE TRIGGER update_pyramid_world_updated_at BEFORE UPDATE ON pyramid_world
|
||||
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||||
|
||||
-- Current pixel state (latest placement wins)
|
||||
-- Face IDs: 0 = Base (square 200x200), 1-4 = North/East/South/West triangular faces
|
||||
CREATE TABLE IF NOT EXISTS pyramid_pixels (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
face_id SMALLINT NOT NULL CHECK (face_id >= 0 AND face_id <= 4),
|
||||
x SMALLINT NOT NULL CHECK (x >= 0 AND x < 200),
|
||||
y SMALLINT NOT NULL CHECK (y >= 0 AND y < 200),
|
||||
color VARCHAR(7) NOT NULL, -- Hex color #RRGGBB
|
||||
placed_by BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
placed_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE(face_id, x, y)
|
||||
);
|
||||
|
||||
-- Create indexes for pyramid_pixels
|
||||
CREATE INDEX IF NOT EXISTS idx_pyramid_pixels_face ON pyramid_pixels(face_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_pyramid_pixels_coords ON pyramid_pixels(face_id, x, y);
|
||||
CREATE INDEX IF NOT EXISTS idx_pyramid_pixels_user ON pyramid_pixels(placed_by);
|
||||
CREATE INDEX IF NOT EXISTS idx_pyramid_pixels_placed_at ON pyramid_pixels(placed_at DESC);
|
||||
|
||||
-- Pixel history (append-only for rollback and lookup)
|
||||
CREATE TABLE IF NOT EXISTS pyramid_pixel_history (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
face_id SMALLINT NOT NULL CHECK (face_id >= 0 AND face_id <= 4),
|
||||
x SMALLINT NOT NULL CHECK (x >= 0 AND x < 200),
|
||||
y SMALLINT NOT NULL CHECK (y >= 0 AND y < 200),
|
||||
color VARCHAR(7) NOT NULL,
|
||||
placed_by BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
placed_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
rolled_back BOOLEAN DEFAULT false,
|
||||
rolled_back_by BIGINT REFERENCES users(id),
|
||||
rolled_back_at TIMESTAMP WITH TIME ZONE
|
||||
);
|
||||
|
||||
-- Create indexes for pyramid_pixel_history
|
||||
CREATE INDEX IF NOT EXISTS idx_pyramid_history_coords ON pyramid_pixel_history(face_id, x, y);
|
||||
CREATE INDEX IF NOT EXISTS idx_pyramid_history_user ON pyramid_pixel_history(placed_by);
|
||||
CREATE INDEX IF NOT EXISTS idx_pyramid_history_placed_at ON pyramid_pixel_history(placed_at DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_pyramid_history_active ON pyramid_pixel_history(rolled_back) WHERE rolled_back = false;
|
||||
|
||||
-- Daily pixel limits per user (resets at midnight UTC)
|
||||
CREATE TABLE IF NOT EXISTS pyramid_daily_limits (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
date DATE NOT NULL DEFAULT CURRENT_DATE,
|
||||
pixels_placed INTEGER DEFAULT 0,
|
||||
UNIQUE(user_id, date)
|
||||
);
|
||||
|
||||
-- Create index for pyramid_daily_limits
|
||||
CREATE INDEX IF NOT EXISTS idx_pyramid_daily_user_date ON pyramid_daily_limits(user_id, date);
|
||||
|
||||
-- 16-color palette (r/place style)
|
||||
CREATE TABLE IF NOT EXISTS pyramid_colors (
|
||||
id SERIAL PRIMARY KEY,
|
||||
color VARCHAR(7) NOT NULL UNIQUE,
|
||||
name VARCHAR(50),
|
||||
sort_order INTEGER DEFAULT 0,
|
||||
is_active BOOLEAN DEFAULT true
|
||||
);
|
||||
|
||||
-- Insert default 16-color palette
|
||||
INSERT INTO pyramid_colors (color, name, sort_order) VALUES
|
||||
('#FFFFFF', 'White', 1),
|
||||
('#E4E4E4', 'Light Gray', 2),
|
||||
('#888888', 'Gray', 3),
|
||||
('#222222', 'Black', 4),
|
||||
('#FFA7D1', 'Pink', 5),
|
||||
('#E50000', 'Red', 6),
|
||||
('#E59500', 'Orange', 7),
|
||||
('#A06A42', 'Brown', 8),
|
||||
('#E5D900', 'Yellow', 9),
|
||||
('#94E044', 'Lime', 10),
|
||||
('#02BE01', 'Green', 11),
|
||||
('#00D3DD', 'Cyan', 12),
|
||||
('#0083C7', 'Blue', 13),
|
||||
('#0000EA', 'Dark Blue', 14),
|
||||
('#CF6EE4', 'Magenta', 15),
|
||||
('#820080', 'Purple', 16)
|
||||
ON CONFLICT (color) DO NOTHING;
|
||||
|
||||
-- Create index for pyramid_colors
|
||||
CREATE INDEX IF NOT EXISTS idx_pyramid_colors_sort ON pyramid_colors(sort_order) WHERE is_active = true;
|
||||
Loading…
Add table
Add a link
Reference in a new issue