avatar to main merge

I have completed the character creation screen on the avatar branch and am preparing to merge it into main.
This commit is contained in:
pricewowen
2026-05-23 23:24:36 -06:00
parent 8957ecb81d
commit 61f98866e8
39 changed files with 2361 additions and 436 deletions

View File

@@ -0,0 +1,67 @@
-- Layered avatar customization: hex colors per layer and sprite variant ids.
alter table public.avatar_state
drop constraint if exists avatar_state_skin_tone_check,
drop constraint if exists avatar_state_head_style_check,
drop constraint if exists avatar_state_torso_style_check,
drop constraint if exists avatar_state_shoe_style_check,
drop constraint if exists avatar_state_eye_type_check;
alter table public.avatar_state
rename column skin_tone to skin_color;
alter table public.avatar_state
alter column skin_color type text using
case skin_color
when 'peach' then '#FFDFC4'
when 'tan' then '#A87149'
when 'brown' then '#8D5524'
when 'olive' then '#C68642'
when 'deep' then '#3B2212'
else coalesce(nullif(skin_color, ''), '#808080')
end;
alter table public.avatar_state
alter column skin_color set default '#808080';
alter table public.avatar_state
add column if not exists pants_style text not null default 'none',
add column if not exists pants_color text not null default '#808080',
add column if not exists head_color text not null default '#808080',
add column if not exists torso_color text not null default '#808080',
add column if not exists shoe_color text not null default '#808080',
add column if not exists avatar_customized boolean not null default false;
alter table public.avatar_state
alter column head_style set default 'none',
alter column torso_style set default 'none',
alter column shoe_style set default 'none',
alter column eye_type set default 'none',
alter column eye_color set default '#808080';
update public.avatar_state
set
head_style = 'none',
torso_style = 'none',
shoe_style = 'none',
eye_type = 'none',
skin_color = coalesce(nullif(skin_color, ''), '#808080'),
pants_color = '#808080',
head_color = '#808080',
torso_color = '#808080',
shoe_color = '#808080',
eye_color = coalesce(nullif(eye_color, ''), '#808080')
where avatar_customized = false;
comment on column public.avatar_state.skin_color is 'Skin layer tint hex color.';
comment on column public.avatar_state.pants_style is 'Pants sprite variant id or none.';
comment on column public.avatar_state.pants_color is 'Pants layer tint hex color.';
comment on column public.avatar_state.shoe_style is 'Shoes sprite variant id or none.';
comment on column public.avatar_state.shoe_color is 'Shoes layer tint hex color.';
comment on column public.avatar_state.torso_style is 'Torso sprite variant id or none.';
comment on column public.avatar_state.torso_color is 'Torso layer tint hex color.';
comment on column public.avatar_state.eye_type is 'Eyes sprite variant id or none.';
comment on column public.avatar_state.eye_color is 'Eyes layer tint hex color.';
comment on column public.avatar_state.head_style is 'Head sprite variant id or none.';
comment on column public.avatar_state.head_color is 'Head layer tint hex color.';
comment on column public.avatar_state.avatar_customized is 'True after the user confirms avatar setup during onboarding.';

View File

@@ -0,0 +1,62 @@
-- Onboarding flags on profiles, equipped shop items, variant id validation.
alter table public.profiles
add column if not exists onboarding_quiz_complete boolean not null default false;
comment on column public.profiles.onboarding_quiz_complete is
'True after the user completes the focus-topic onboarding quiz.';
comment on column public.profiles.onboarding_complete is
'True after the user confirms avatar customization and enters the app.';
alter table public.avatar_state
add column if not exists equipped_items text[] not null default '{}';
comment on column public.avatar_state.equipped_items is
'Shop item ids currently equipped on the avatar (accessories and backgrounds).';
alter table public.avatar_state
drop constraint if exists avatar_state_pants_style_check,
drop constraint if exists avatar_state_shoe_style_check,
drop constraint if exists avatar_state_torso_style_check,
drop constraint if exists avatar_state_eye_type_check,
drop constraint if exists avatar_state_head_style_check;
alter table public.avatar_state
add constraint avatar_state_pants_style_check
check (pants_style in ('none', 'pants-1', 'pants-2', 'pants-3')),
add constraint avatar_state_shoe_style_check
check (shoe_style in ('none', 'shoes-1', 'shoes-2', 'shoes-3')),
add constraint avatar_state_torso_style_check
check (torso_style in ('none', 'torso-1', 'torso-2', 'torso-3', 'torso-4')),
add constraint avatar_state_eye_type_check
check (eye_type in ('none', 'eyes-1', 'eyes-2')),
add constraint avatar_state_head_style_check
check (head_style in ('none', 'head-1', 'head-2', 'head-3', 'head-4', 'head-5', 'head-6', 'head-7'));
alter table public.avatar_state
drop constraint if exists avatar_state_skin_color_check,
drop constraint if exists avatar_state_pants_color_check,
drop constraint if exists avatar_state_shoe_color_check,
drop constraint if exists avatar_state_torso_color_check,
drop constraint if exists avatar_state_eye_color_check,
drop constraint if exists avatar_state_head_color_check;
alter table public.avatar_state
add constraint avatar_state_skin_color_check
check (skin_color ~ '^#[0-9A-Fa-f]{6}$'),
add constraint avatar_state_pants_color_check
check (pants_color ~ '^#[0-9A-Fa-f]{6}$'),
add constraint avatar_state_shoe_color_check
check (shoe_color ~ '^#[0-9A-Fa-f]{6}$'),
add constraint avatar_state_torso_color_check
check (torso_color ~ '^#[0-9A-Fa-f]{6}$'),
add constraint avatar_state_eye_color_check
check (eye_color ~ '^#[0-9A-Fa-f]{6}$'),
add constraint avatar_state_head_color_check
check (head_color ~ '^#[0-9A-Fa-f]{6}$');
-- Backfill quiz completion for users who already finished onboarding.
update public.profiles
set onboarding_quiz_complete = true
where onboarding_complete = true
and onboarding_quiz_complete = false;

View File

@@ -1,8 +1,32 @@
insert into shop_items (id, name, type, price, image_path)
-- Character layer styles sold in the shop (id = variant id, type = layer id).
delete from public.user_items
where item_id in ('hat_blue', 'glasses_round', 'room_sunset');
delete from public.shop_items
where id in ('hat_blue', 'glasses_round', 'room_sunset');
insert into public.shop_items (id, name, type, price, image_path)
values
('hat_blue', 'Blue Hat', 'accessory', 20, '/items/hat-blue.png'),
('glasses_round', 'Round Glasses', 'accessory', 30, '/items/glasses-round.png'),
('room_sunset', 'Sunset Room', 'background', 40, '/backgrounds/room-sunset.png')
('pants-1', 'Pants 1', 'pants', 20, '/character/pants/pants-1.png'),
('pants-2', 'Pants 2', 'pants', 25, '/character/pants/pants-2.png'),
('pants-3', 'Pants 3', 'pants', 30, '/character/pants/pants-3.png'),
('shoes-1', 'Shoes 1', 'shoes', 20, '/character/shoes/shoes-1.png'),
('shoes-2', 'Shoes 2', 'shoes', 25, '/character/shoes/shoes-2.png'),
('shoes-3', 'Shoes 3', 'shoes', 30, '/character/shoes/shoes-3.png'),
('torso-1', 'Torso 1', 'torso', 25, '/character/torso/torso-1.png'),
('torso-2', 'Torso 2', 'torso', 30, '/character/torso/torso-2.png'),
('torso-3', 'Torso 3', 'torso', 35, '/character/torso/torso-3.png'),
('torso-4', 'Torso 4', 'torso', 40, '/character/torso/torso-4.png'),
('eyes-1', 'Eyes 1', 'eyes', 15, '/character/eyes/eyes-1.png'),
('eyes-2', 'Eyes 2', 'eyes', 20, '/character/eyes/eyes-2.png'),
('head-1', 'Head 1', 'head', 30, '/character/head/head-1.png'),
('head-2', 'Head 2', 'head', 35, '/character/head/head-2.png'),
('head-3', 'Head 3', 'head', 40, '/character/head/head-3.png'),
('head-4', 'Head 4', 'head', 45, '/character/head/head-4.png'),
('head-5', 'Head 5', 'head', 50, '/character/head/head-5.png'),
('head-6', 'Head 6', 'head', 55, '/character/head/head-6.png'),
('head-7', 'Head 7', 'head', 60, '/character/head/head-7.png')
on conflict (id) do update
set
name = excluded.name,