From 435e12dcd9f1d4882420d76442027812fc33b456 Mon Sep 17 00:00:00 2001 From: Theomund <34360334+theomund@users.noreply.github.com> Date: Sat, 18 Jul 2026 17:36:22 +0000 Subject: [PATCH 01/10] feat: enable MSAA config flag --- app.odin | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app.odin b/app.odin index c5e1771..48df2ea 100644 --- a/app.odin +++ b/app.odin @@ -9,6 +9,8 @@ package main import rl "vendor:raylib" run :: proc() -> Error { + rl.SetConfigFlags({.MSAA_4X_HINT}) + rl.InitWindow(WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_TITLE) defer rl.CloseWindow() From a708e34514d5da312cd4de1ee63151616ad043a2 Mon Sep 17 00:00:00 2001 From: Theomund <34360334+theomund@users.noreply.github.com> Date: Sat, 18 Jul 2026 17:48:25 +0000 Subject: [PATCH 02/10] feat: add README badges --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index fa80ce8..f2acb11 100644 --- a/README.md +++ b/README.md @@ -4,4 +4,8 @@ # Spinward +![Build](https://img.shields.io/github/actions/workflow/status/theomund/spinward/linux.yml?style=for-the-badge&logo=linux&logoColor=white) +![License](https://img.shields.io/github/license/theomund/spinward?style=for-the-badge&logo=mozilla&logoColor=white) +![Toolchain](https://img.shields.io/badge/toolchain-dev--2026--07a-blue?style=for-the-badge&logo=odin&logoColor=white) + Traveller map viewer built with Odin. From 565ec2bee903414ae8e90d61920455d578333dae Mon Sep 17 00:00:00 2001 From: Theomund <34360334+theomund@users.noreply.github.com> Date: Sat, 18 Jul 2026 21:53:43 +0000 Subject: [PATCH 03/10] feat: parse sector name from file --- app.odin | 2 +- assets/Spinward Marches.tab | 443 ++++++++++++++++++++++++++++++++++++ sector.odin | 7 +- sector_test.odin | 7 +- types.odin | 10 +- 5 files changed, 462 insertions(+), 7 deletions(-) create mode 100644 assets/Spinward Marches.tab diff --git a/app.odin b/app.odin index 48df2ea..a144ae1 100644 --- a/app.odin +++ b/app.odin @@ -19,7 +19,7 @@ run :: proc() -> Error { } camera := new_camera() - sector := new_sector("Spinward Marches") + sector := new_sector("assets/Spinward Marches.tab") or_return for !rl.WindowShouldClose() { rl.BeginDrawing() diff --git a/assets/Spinward Marches.tab b/assets/Spinward Marches.tab new file mode 100644 index 0000000..558477b --- /dev/null +++ b/assets/Spinward Marches.tab @@ -0,0 +1,443 @@ +# Generated file - DO NOT MODIFY +# Update source files in res/t5ss/data instead + +Sector SS Hex Name UWP Bases Remarks Zone PBG Allegiance Stars {Ix} (Ex) [Cx] Nobility W RU +Spin A 0101 Zeycude C430698-9 De Na Ni Po 613 ZhIN K9 V { -1 } (C53-1) [6559] 8 -180 +Spin A 0102 Reno C4207B9-A De He Na Po Pi Pz A 603 ZhIN G8 V M1 V { 1 } (C6A+2) [886B] 12 1440 +Spin A 0103 Errere B563664-B KM Ni Ri O:0304 910 ZhIN M1 V M4 V { 3 } (957+1) [4939] 9 315 +Spin A 0104 Cantrel C566243-9 Lo 520 ZhIN F1 V { -1 } (610-4) [1126] 12 -24 +Spin A 0108 Gyomar C8B2889-8 Fl He Ph (Tethmari) 824 NaHu A8 V { -1 } (G77+1) [9769] 14 784 +Spin E 0111 Atson B310598-8 Ni 933 NaHu K8 V { -1 } (D43-1) [5458] 10 -156 +Spin E 0114 Yiktor C6B6431-A Fl Ni 123 NaHu G4 V M4 V { 0 } (B33-4) [1416] 12 -396 +Spin E 0115 Xhosa EA95124-5 Lo Lt 910 NaHu M0 V { -3 } (300-5) [1133] 8 -15 +Spin I 0122 Junction D550441-4 De Ni Po Lt 210 NaHu M2 V M3 V { -3 } (631-5) [1111] 10 -90 +Spin I 0129 Uniqua E62556B-7 Ni O:0130 210 NaHu K9 V M9 V { -3 } (741-1) [7279] 8 -28 +Spin I 0130 Garoo A2008CB-A Na Va Ph Pi Pz (Garoo) A 210 NaHu M1 V M5 V { 2 } (B7B+4) [AA7C] 9 3388 +Spin M 0133 Emape B564500-B N Ag Ni Pr Da A 503 ImDd M0 V { 2 } (A46-2) [1716] BcC 6 -480 +Spin M 0139 Raweh B430300-B N De Lo Po Da A 920 ImDd G3 V M1 V { 1 } (721-3) [1416] B 5 -42 +Spin M 0140 876-574 E687200-3 Lo Ga Lt 702 NaHu K7 V { -3 } (410-5) [1111] 11 -20 +Spin A 0202 Thengo C868586-5 Ag Ni Pr Lt 801 ZhIN G5 V M3 V { -1 } (743-2) [4444] 12 -168 +Spin E 0212 Prinx C436635-6 Ni 720 NaHu A9 V K8 V { -2 } (852-4) [4434] 9 -320 +Spin E 0215 Rushu E766674-4 Ag Ni Ga Ri VargW Lt 903 CsZh G0 V M3 V { -1 } (853-3) [4532] 8 -360 +Spin E 0218 Bael E200100-8 Lo Va 812 NaHu K2 V { -3 } (600-5) [1113] 9 -30 +Spin I 0223 Stern-Stern B421558-B He Ni Po DaryW 701 DaCf M0 V M3 V { 1 } (845+1) [565B] 9 160 +Spin I 0230 886-945 E833000-0 Ba Po Lt 004 NaXX F8 V { -3 } (200-5) [0000] 16 -10 +Spin M 0231 Saxe EAA5543-8 Fl Ni 910 NaHu A2 V { -3 } (841-5) [2225] 9 -160 +Spin M 0236 Andor C695735-9 Ag An Pi Fo DroyW R 603 ImDd F3 V { 1 } (C6A-1) [5837] 6 -720 +Spin M 0240 769-422 E754401-8 Ni Pa (minor) 924 NaHu G2 V { -3 } (C31-5) [1114] 10 -180 +Spin A 0301 Rio C686648-8 Ag Ni Ga Ri 201 NaHu M0 V M1 V { 0 } (954+1) [6658] 8 180 +Spin A 0303 Gesentown B31169B-C KM Ic Na Ni Da Ht A 801 ZhIN M2 V M9 V { 2 } (956+4) [887E] 12 1080 +Spin A 0304 Chronor A6369A5-D KM Hi Cp Ht 810 ZhIN F8 V { 4 } (C8G+2) [7D3B] 5 3072 +Spin A 0307 Atsa B4337CA-A KM Na Po An Pz A 810 ZhIN F7 V M3 V { 3 } (A6C+5) [9A7C] 8 3600 +Spin E 0311 Mizan-fel B56258A-8 Ni Pr 323 NaHu F3 V { -1 } (C43+1) [747A] 13 144 +Spin I 0321 Nonym C433898-A M Na Po Ph 623 NaHu G0 V { 1 } (F7A+1) [895A] 14 1050 +Spin I 0325 Laberv B554443-7 M Ni Pa DaryW 834 DaCf G0 V { -1 } (632-4) [1324] 12 -144 +Spin I 0326 Ektron C432652-9 Na Ni Po Asla1 Dary8 423 DaCf M1 V { -1 } (D53-5) [2515] 14 -975 +Spin M 0332 Gothe E42159B-7 He Ni Po Da A 310 ImDd F5 V { -3 } (741-1) [7279] B 9 -28 +Spin M 0333 Mirriam B9998A6-A NW Ph Pi Pz A 514 ImDd G6 V { 3 } (F7C+2) [7B49] BDe 13 2520 +Spin M 0336 Candory C593634-8 Ni An Fo DroyW R 920 ImDd F6 V M3 V { -2 } (A52-4) [4436] 5 -400 +Spin M 0340 Wonderay E88A47A-4 Ni Wa Lt 210 NaHu M1 V M3 V { -3 } (631-1) [6176] 7 -18 +Spin E 0412 Sansibar B200310-A KM Lo Va Droy4 701 ZhIN M3 V M3 V { 2 } (622-2) [1515] 12 -48 +Spin E 0414 Attica C400546-8 Ni Va 810 NaHu K1 V M6 V { -2 } (842-3) [4347] 8 -192 +Spin E 0416 Retinae E8C69AA-9 Fl Hi In Pz (Tashaki) RsD A 910 CsIm M1 V { 1 } (C8B+3) [BA7B] 11 3168 +Spin I 0421 Zamine C897977-A Hi In Dary9 223 DaCf M3 V { 3 } (G8D+3) [9C5A] 12 4992 +Spin I 0425 Engrange C554769-8 Ag Asla1 Dary8 O:0426 701 DaCf M1 V M3 V { 0 } (A68+1) [8769] 10 480 +Spin I 0426 Ilium B544831-9 KM Pa Ph Pi DaryW 401 DaCf G3 V M8 V { 2 } (B7B-2) [4A15] 6 -1694 +Spin I 0427 Roget B566777-9 Ag Ri Asla6 Dary3 420 DaCf F8 V M3 V { 3 } (B6C+3) [7A59] 7 2376 +Spin I 0429 Kardin E553123-6 Lo Po An 410 NaHu F7 V { -3 } (300-5) [1123] 10 -15 +Spin I 0430 Bularia C774622-5 Ag Ni Lt 310 CsIm K5 V M3 V { -1 } (853-5) [2511] 8 -600 +Spin M 0433 Jone B792785-9 N He Pi Pz A 810 ImDd G8 V M5 V { 1 } (A6A-1) [5837] BD 13 -600 +Spin M 0440 Jinx D100133-7 Lo Va Da A 202 NaHu G3 IV D { -3 } (300-5) [1124] 10 -15 +Spin A 0503 Whenge D648500-8 Ag Ni 610 NaHu F8 V { -2 } (842-5) [1313] 13 -320 +Spin E 0511 Terra Nova C786342-9 Lo Ga 812 ZhIN K2 V { -1 } (820-5) [1215] 8 -80 +Spin E 0512 Asmodeus E596400-5 Ni Pa Lt 205 ZhIN K8 V { -3 } (631-5) [1111] 11 -90 +Spin E 0518 Faisal D545436-5 Ni Pa Lt 810 CsIm K9 V M7 V { -3 } (631-4) [3144] 9 -72 +Spin I 0526 Rorre D765657-3 Ag Ni Ga Ri DaryW Lt 103 DaCf F4 V M2 V { -1 } (853-1) [6553] 13 -120 +Spin I 0527 Mire A665A95-C KM Hi Ga Cx Dary8 Asla1 Ht 110 DaCf K6 V { 4 } (D9F+2) [8E3A] 10 3510 +Spin I 0528 Condaria E54779B-5 Ag Pi Pz Lt A 901 NaHu K3 V M0 V { -1 } (966+1) [9677] 12 324 +Spin I 0530 Dorannia E42158A-8 He Ni Po 510 NaHu K4 V { -3 } (841-1) [727A] 9 -32 +Spin M 0532 Ucella D574654-7 Ag Ni 410 CsIm F2 V M2 V { -2 } (852-4) [4435] 8 -320 +Spin M 0533 Penelope C560642-4 De Ni Ri Lt 323 ImDd F6 V M2 V { -1 } (853-5) [2511] BC 10 -600 +Spin M 0534 Karin A767768-C NS Ag Ga Ri Pz Mr Ht A 410 ImDd G7 V { 5 } (A6F+5) [7C5C] BCf 6 4500 +Spin M 0538 Wonstar B555741-7 N Ag Pz A 910 ImDd M0 V { 1 } (969-3) [3813] BC 5 -1458 +Spin M 0539 Froin C535225-9 Lo RsZ 601 ImDd M2 V M7 V { -1 } (510-3) [1137] B 12 -15 +Spin A 0601 Enlas-du E975776-6 Ag Pi 323 NaHu F1 V { -1 } (966-2) [6645] 14 -648 +Spin A 0605 Algebaster C665658-9 Ag Ni Ga Ri 410 NaHu M0 V M1 V { 1 } (955+1) [6759] 10 225 +Spin A 0607 Rasatt E883401-7 Ni 910 NaHu F0 V { -3 } (631-5) [1113] 6 -90 +Spin A 0608 Ninjar A311666-C KM Ic Na Ni Mr Ht 410 ZhIN A4 V { 2 } (956+1) [584B] 6 270 +Spin A 0610 Sheyou B756779-A KM Ag Ga 111 ZhIN F4 V M0 V { 4 } (B6D+5) [8B6B] 13 4290 +Spin E 0613 Lebeau B869554-C Ni Pr Ht 901 ZhIN G8 V M5 V { 1 } (845-1) [363A] 10 -160 +Spin E 0614 Querion B554788-9 KM Ag Cp (Sheol) 804 ZhIN G6 V { 3 } (D6C+3) [7A59] 13 2808 +Spin E 0618 Dekalb EA8A799-6 Oc Ri 320 CsIm M1 V { -1 } (966+1) [8667] 13 324 +Spin E 0620 Winston E887573-6 Ag Ni Ga Pr 501 SwCf K5 V M9 V { -2 } (742-5) [2323] 6 -280 +Spin I 0622 Terant 340 D5405A7-9 De He Ni Po DaryW 523 DaCf G0 V M5 V { -2 } (C42-2) [5359] 8 -192 +Spin I 0624 Jacent A433744-D Na Po DaryW Ht 710 DaCf M0 V { 2 } (A6D+1) [593B] 7 780 +Spin I 0625 494-908 X893000-0 Ba Fo Re Lt R 010 DaCf M1 V { -3 } (200-5) [0000] 6 -10 +Spin I 0627 Darrian A463955-G Hi An Pr (Daryen)8 Asla0 Ht 225 DaCf G1 V D { 4 } (J8F+1) [7D3E] 10 2160 +Spin M 0632 Gohature C754766-7 S Ag O:0732 523 ImDd F8 V { 0 } (968-1) [6746] BC 15 -432 +Spin M 0637 Quhaiathat C31479B-9 Ic Pi Pz A 210 ImDd K8 V { 0 } (A69+2) [977B] BD 6 1080 +Spin M 0638 Lakou E779454-7 Ni Da A 601 ImDd M2 V { -3 } (631-5) [2135] B 13 -90 +Spin A 0703 Indo E434662-6 Ni O:0605 320 NaHu F6 V { -3 } (851-5) [2312] 11 -200 +Spin A 0704 Nerewhon E738475-7 Ni 820 NaHu K5 V { -3 } (631-5) [2135] 10 -90 +Spin A 0705 Cipango A886865-C KM Ga Ri Pa Ph O:0304 Ht 121 ZhIN G2 V { 4 } (D7E+2) [6C3A] 10 2548 +Spin A 0710 Stave E7667A8-2 Ag Ga Ri (Obeyery) Lt 801 NaHu K9 V M2 V { 0 } (965+1) [7752] 8 270 +Spin E 0712 Rapp's World C592320-8 M He Lo 402 ZhIN K5 V M8 V { -2 } (720-5) [1113] 9 -70 +Spin E 0717 Thanber B543653-C Ni Po Ht 210 CsIm M0 V M1 V { 1 } (955-2) [3729] 9 -450 +Spin E 0720 Entrope E436AAA-B Hi Pz A 110 SwCf G6 V M1 V { 1 } (D9C+3) [CB7D] 10 4212 +Spin I 0721 Torment X433268-6 Lo Po Fo DaryW Px R 820 DaCf M0 V { -3 } (410-3) [2156] 12 -12 +Spin I 0723 Trifuge C546556-9 Ag Ni (Dphone)1 Dary9 210 DaCf F0 V { 0 } (844-1) [4548] 10 -128 +Spin I 0724 Nosea B4326BB-C Na Ni Po Da DaryW Ht A 620 DaCf M2 V { 1 } (A55+3) [877E] 13 750 +Spin I 0727 Spume C540200-A M De He Lo Po DaryW 434 DaCf M2 V { 0 } (B10-4) [1215] 12 -44 +Spin I 0729 Ator D426258-7 Lo An 821 NaHu F7 V M2 V { -3 } (410-3) [2157] 6 -12 +Spin M 0731 Ralhe E424574-8 Ni 801 NaHu M2 V M3 V { -3 } (841-5) [3236] 9 -160 +Spin M 0732 Iderati A887798-C N Ag Ga Ri Cp Ht 201 ImDd G9 V { 4 } (A6E+4) [7B5C] BCF 11 3360 +Spin M 0739 Tondoul E5136A7-7 Ic Na Ni 701 NaHu K8 V M1 V { -3 } (851-3) [6357] 10 -120 +Spin A 0805 Narval D525688-7 M Ni Da A 603 CsZh G4 V M6 V { -3 } (851-3) [6357] 10 -120 +Spin A 0807 Plaven E845300-5 Lo Lt 910 NaHu G8 V M7 V { -3 } (520-5) [1111] 6 -50 +Spin A 0808 Quar B532720-B N Na Po Pz A 401 CsIm M2 V { 2 } (A6C-2) [2916] 9 -1440 +Spin A 0810 Frond E9C3300-9 Fl Lo 103 CsIm F8 V { -2 } (820-5) [1114] 12 -80 +Spin E 0820 Anselhome C310588-8 Ni 601 SwCf M0 V M1 V { -2 } (842-2) [5358] 7 -128 +Spin I 0822 Cunnonic E65767A-3 Ag Ni Ga Asla0 Dary9 Lt 502 DaCf K0 V { -2 } (852+1) [8475] 8 80 +Spin I 0830 Debarre B854123-9 Lo 822 CsIm M2 V { 0 } (700-3) [1126] 15 -21 +Spin M 0834 875-496 E888421-7 S Ni Pa Da A 510 CsIm M3 V M7 V { -3 } (631-5) [1113] 8 -90 +Spin M 0837 Ochecate E747569-7 Ag Ni O:1040 210 NaHu G8 V M8 V { -2 } (742-1) [6368] 7 -56 +Spin M 0838 Mewey D786799-5 Ag Ga Ri (Mewey) Lt 701 NaHu K3 V M3 V { 0 } (967+1) [8766] 8 378 +Spin M 0840 975-452 E100316-9 Lo Va 821 NaHu M0 V { -2 } (820-3) [2148] 10 -48 +Spin B 0901 Condyole E7A1522-8 Fl He Ni (Vexx) 923 NaHu F8 V { -3 } (C41-5) [1214] 10 -240 +Spin B 0902 Puparkin C7B3386-9 Fl Lo Varg8 502 NaHu K8 V M4 V { -1 } (720-2) [2248] 6 -28 +Spin B 0904 Chwistyoch B766766-A KM Ag Ga Ri Mr 424 ZhIN M2 V { 5 } (F6E+4) [6C49] 15 5040 +Spin B 0909 Gougeste C572510-A He Ni Da A 420 CsIm K2 V { 0 } (944-4) [1515] 10 -576 +Spin F 0911 Caloran C796746-5 Ag Pi Lt 510 NaHu G2 V M4 V { 0 } (967-1) [6744] 6 -378 +Spin F 0912 899-076 E201300-8 Ic Lo Va 520 NaHu F7 V { -3 } (720-5) [1113] 8 -70 +Spin F 0915 Quare B200545-9 Ni Va 204 CsIm M3 V { 0 } (B44-2) [3537] 10 -352 +Spin F 0919 Zeta 2 X6B0000-0 Ba He Fo (Viji) Re Lt R 020 NaXX M0 V { -3 } (200-5) [0000] 13 -10 +Spin J 0921 Hrunting B563747-9 KM Ri 313 SwCf M2 V { 3 } (D6C+3) [7A59] 10 2808 +Spin J 0922 Tizon B586887-A KM Ri Pa Ph 323 SwCf K2 IV M3 V { 4 } (F7D+4) [8C5A] 15 5460 +Spin J 0927 Narsil B574A55-A KM Hi In 224 SwCf G6 IV M0 V { 5 } (J9F+3) [8F38] 10 7290 +Spin J 0930 Flammarion A623514-B NW Ni Po 710 ImDd F8 V { 2 } (846+1) [3739] B 11 192 +Spin N 0931 Asteltine B7A7402-A Fl Ni 210 NaHu K7 V M3 V { 1 } (734-3) [1516] 10 -252 +Spin N 0938 Inchin D42035A-A De He Lo Po Sa 823 NaHu F0 V { -1 } (A20+1) [527C] 8 20 +Spin N 0940 Singer D553774-6 Po 901 NaHu M2 V M2 V { -2 } (965-4) [5534] 9 -1080 +Spin B 1004 Esalin C565673-8 Ag Ni Ri Da A 223 NaHu F3 V M2 V { 0 } (D54-3) [3625] 9 -780 +Spin B 1005 Ruby B400445-B S Ni Va 201 ImDd M1 V M3 V { 1 } (734-1) [2539] B 9 -84 +Spin B 1006 Emerald B766555-B S Ag Ni Ga Pr 534 ImDd M1 V { 2 } (E46+1) [3739] BcC 12 336 +Spin B 1010 Zenopit D430546-7 De Ni Po 622 NaHu M3 V { -3 } (741-4) [4246] 7 -112 +Spin F 1011 Arden B5549CB-9 Hi Pz A 110 NaHu G4 V M5 V { 2 } (C8C+4) [BB7B] 12 4608 +Spin F 1018 Choleosti C200100-9 Lo Va 101 ImDd K9 V M4 V { -1 } (400-5) [1114] B 5 -20 +Spin F 1020 Margesi C575677-6 Ag Ni Da A 910 ImDd K4 V M7 V { -1 } (853-1) [6556] BC 10 -120 +Spin J 1022 Colada B564685-B KM Ag Ni Ri 211 SwCf K2 V M8 V { 4 } (A58+2) [4A39] 10 800 +Spin J 1026 Anduril B985855-B KM Ri Pa Ph 222 SwCf F2 V { 4 } (E7E+2) [6C39] 11 2744 +Spin N 1031 567-908 E532000-0 Ba Po (Shriekers) Lt 010 NaXX K5 III D { -3 } (200-5) [0000] 9 -10 +Spin N 1037 Avastan C433520-A Ni Po 724 NaHu M3 V { 0 } (D44-4) [1515] 11 -832 +Spin N 1040 Kuai Qing C503758-A Ic Na Va Pi 320 NaHu K3 V { 1 } (B6A+1) [785A] 7 660 +Spin B 1102 Riverland C566A99-9 Hi Pz A 214 ZhIN M2 V { 1 } (H9B+2) [BB6A] 14 3366 +Spin B 1103 Clan B672899-A KM He Ph Pi Pz A 901 ZhIN K8 V { 3 } (B7C+4) [9B6B] 12 3696 +Spin B 1106 Jewell A777999-C NS Hi In Ht 623 ImDd G7 V { 5 } (G8G+5) [AE6D] BEf 10 10240 +Spin B 1110 Zircon C792668-8 M He Ni O:1011 624 NaHu F0 V { -2 } (E52-2) [6458] 12 -280 +Spin F 1116 Frenzie A200436-A N Ni Va Cp 110 ImDd M3 III M2 V { 1 } (734+1) [3549] BF 5 84 +Spin F 1118 Garda-Vilis B978868-A S Pa Ph Pi O:1119 512 ImDd M3 V { 2 } (D7B+2) [8A5A] BcDe 14 2002 +Spin F 1119 Vilis A593943-A Hi In 820 ImDd G5 V M8 V { 4 } (D8E+1) [6D27] BEf 9 1456 +Spin J 1121 Mjolnir B530544-A KM De Ni Po 522 SwCf A5 V G0 V { 2 } (B46+1) [3738] 12 264 +Spin J 1123 Joyeuse B564778-A KM Ag Ri Pz A 401 SwCf M3 V M9 V { 5 } (A6E+5) [7C5A] 13 4200 +Spin J 1126 Orcrist B8A6733-A KM Fl Lk 401 SwCf K7 V M7 V { 3 } (A6C+1) [4A27] 8 720 +Spin J 1130 Enos E35059B-4 M De Ni Po Da Lt A 710 SwCf M1 V { -3 } (741-1) [7276] 8 -28 +Spin N 1131 Faldor E5936A7-5 Ni (Otarri) Lt 520 NaHu M2 V { -3 } (851-3) [6355] 7 -120 +Spin N 1132 Bowman D000300-9 S As Lo Va 831 CsIm M0 V { -2 } (920-5) [1114] 13 -90 +Spin N 1133 Squallia C438679-9 Ni 320 NaHu F0 V { -1 } (A53+1) [756A] 8 150 +Spin N 1138 Tarsus B584620-A Ag Ni Ri 202 CsIm K9 V { 3 } (A57-1) [1915] 7 -350 +Spin B 1201 Ao-dai E410644-7 Na Ni 312 ZhIN K2 V M3 V { -3 } (851-5) [4335] 10 -200 +Spin B 1204 Mongo A568685-A NS Ag Ni Ri 603 ImDd M6 III M0 V { 4 } (B58+2) [4A38] BCf 7 880 +Spin B 1209 Utoland C573464-7 M Ni O:1011 410 NaHu M0 V { -2 } (631-4) [2235] 8 -72 +Spin B 1210 Pequan E5656B9-4 Ag Ni Ri Da Lt A 710 NaHu K5 V { -1 } (853+1) [7565] 5 120 +Spin F 1212 Digitis E53668A-6 Ni 920 NaHu M3 V { -3 } (851-1) [8378] 8 -40 +Spin F 1213 Edinina E400220-7 Lo Va Da A 401 CsIm K6 V M0 V { -3 } (410-5) [1112] 6 -20 +Spin F 1214 728-907 E955000-0 Ba Lt 010 ImDd F1 V M2 V { -3 } (200-5) [0000] 10 -10 +Spin F 1216 Stellatio D5A4420-8 Fl Ni 210 ImDd M3 V { -3 } (731-5) [1113] B 14 -105 +Spin F 1217 Arkadia E546845-6 Pa Ph Pi 402 ImDd G8 V { -2 } (A75-4) [6634] BcDe 7 -1400 +Spin J 1221 Gungnir B544779-8 M Ag Pi 432 SwCf G3 IV M4 V { 1 } (E69+2) [8869] 13 1512 +Spin J 1223 Gram A895957-C KM Hi In Cx Ht 603 SwCf F2 V M2 V { 5 } (E8G+5) [9E5C] 10 8960 +Spin J 1225 Excalibur B424755-A KM Pi 402 SwCf K5 V { 3 } (B6C+1) [5A38] 10 792 +Spin N 1232 Walston C544338-8 S Lo Varg7 302 CsIm M2 V { -2 } (720-2) [3158] 7 -28 +Spin N 1233 Flexos E5A1422-8 Fl He Ni 610 NaHu M1 V M2 V { -3 } (731-5) [1114] 8 -105 +Spin N 1237 Collace B628943-D S Hi In Ht 101 CsIm F1 V M3 V { 4 } (C8G+1) [6D2A] 5 1536 +Spin N 1238 Pavabid C6678D8-6 Ga Ri Pa Ph Pz A 701 NaHu K7 V { 0 } (A77+1) [8856] 14 490 +Spin B 1305 Nakege D591314-5 He Lo Da (minor) Lt A 501 ImDd K2 V M0 V { -3 } (520-5) [1133] B 14 -50 +Spin B 1307 Lysen B592655-A S He Ni 623 ImDd M3 V { 1 } (D55-1) [4738] B 12 -325 +Spin F 1311 Tremous Dex B511411-C Ic Ni Ht 201 NaHu K8 V M5 V { 1 } (734-3) [1518] 8 -252 +Spin F 1315 Mirriam E572300-8 N He Lo 110 ImDd F5 V { -3 } (620-5) [1113] B 11 -60 +Spin F 1320 Saurus D888588-7 Ag Ni Pr (Saurians) 820 ImDd G8 V M1 V { -2 } (742-2) [5357] BcC 13 -112 +Spin J 1324 Tyrfing B637735-A KM 701 SwCf M2 V { 3 } (A6C+1) [5A38] 6 720 +Spin J 1325 Sacnoth A775956-C KM Hi In Ht 801 SwCf F9 V M3 V { 5 } (C8G+4) [8E4B] 7 6144 +Spin J 1329 Caladbolg B565776-A S Ag Ri 710 ImDd F7 V M0 V M4 V { 4 } (A6D+3) [6B49] BCf 9 2340 +Spin N 1331 Datrillian E427633-8 Ni 801 NaHu M1 V { -3 } (951-5) [3325] 9 -225 +Spin N 1332 Nirton X500000-0 Ba Va Fo Lt R 011 NaXX M0 V { -3 } (200-5) [0000] 11 -10 +Spin N 1337 Judice E9B2000-0 Ba Fl He RsT Lt 021 CsIm M3 V { -3 } (200-5) [0000] 8 -10 +Spin N 1339 Trexalon B561851-C Ri Ph Ht 923 NaHu K8 V { 3 } (F7D-1) [4B18] 13 -1365 +Spin N 1340 Motmos B68468B-5 N Ag Ni Ri Lt 710 CsIm M2 V M2 V { 1 } (855+3) [8777] 7 600 +Spin B 1401 Foelen B638665-8 Ni Da (Chokari)4 Dolp2 O:1103 A 910 ZhIN K0 V { -1 } (953-3) [4536] 14 -405 +Spin B 1402 Farreach A200400-B KM Ni Va Da A 415 ZhIN M3 III M0 V { 2 } (C35-2) [1616] 10 -360 +Spin F 1411 Rangent E67A612-7 Ni Wa 503 NaHu K8 V { -3 } (851-5) [2313] 14 -200 +Spin F 1413 Denotam B739573-A N Ni 324 ImDd M2 V { 1 } (D45-2) [2627] B 9 -520 +Spin F 1417 Ficant E567353-5 Lo Lt 910 ImDd M0 V M1 V { -3 } (520-5) [1122] B 13 -50 +Spin J 1424 Beater B685686-A KM Ag Ni Ga Ri 610 SwCf K4 V { 4 } (958+3) [5A49] 11 1080 +Spin J 1429 Gunn E544110-8 Lo Da A 602 ImDd M3 V { -3 } (500-5) [1113] B 9 -25 +Spin J 1430 Caliburn E000514-A As Ni Va 914 ImDd M2 V { -1 } (C43-3) [3438] B 13 -432 +Spin N 1433 Noctocol E7A5747-8 Fl 602 NaHu F5 V M2 V { -2 } (B66-2) [7558] 15 -792 +Spin N 1434 Tarkine C566662-7 S Ag Ni Ri Da O:1435 A 310 CsIm M0 V M2 V { 0 } (854-4) [2613] 9 -640 +Spin N 1435 Dallia B885883-9 Ga Ri Pa Ph 610 CsIm F2 V { 2 } (B7B-1) [5A26] 9 -847 +Spin N 1436 Talos E433532-9 Ni Po 820 NaHu F9 V M1 V { -2 } (942-5) [1315] 9 -360 +Spin B 1510 871-438 E722000-0 Ba He Po Lt 001 NaXX M3 V M8 V { -3 } (200-5) [0000] 7 -10 +Spin F 1511 Tionale C674321-8 Lo Da (minor) A 910 CsIm M2 V M5 V { -2 } (620-5) [1114] 11 -60 +Spin F 1515 Calit C434887-7 Ph 501 ImDd K9 V M1 V { -1 } (A77-1) [8757] Be 4 -490 +Spin F 1519 Asgard X5437C7-5 Po Pi Fo Lt R 520 ImDd F5 V M1 V { -2 } (965-2) [7555] 13 -540 +Spin F 1520 Tavonni E567000-0 Ba Lt 034 ImDd G6 V { -3 } (200-5) [0000] 10 -10 +Spin J 1522 Dyrnwyn B958812-A KM Pa Ph 201 SwCf K4 V M8 V { 3 } (B7C-1) [4B16] 7 -924 +Spin J 1523 Durendal B687734-B KM Ag Ga Ri 714 SwCf M1 V { 5 } (E6F+3) [5C39] 11 3780 +Spin J 1524 Hofud B666853-A KM Ga Ri Pa Ph 601 SwCf G6 V M9 V { 4 } (B7D+1) [5C27] 8 1001 +Spin J 1525 Sting B645796-A KM Ag Pi 702 SwCf M0 V { 4 } (B6D+3) [6B49] 9 2574 +Spin J 1526 Biter B354623-A KM Ag Ni 301 SwCf G7 V M1 V { 3 } (957+1) [3927] 8 315 +Spin J 1529 Steel E655000-0 Ba Ga Re Lt 024 SwCf K8 V { -3 } (200-5) [0000] 15 -10 +Spin N 1531 Dawnworld E885000-0 Ba Ga Lt 025 NaXX F8 V M2 V { -3 } (200-5) [0000] 17 -10 +Spin N 1532 Elixabeth B426467-8 N Ni O:1435 201 CsIm M1 V M5 V { -1 } (732-1) [4358] 8 -42 +Spin N 1533 Forine D3129B8-A Hi Ic In Na 610 NaHu G9 V { 2 } (C8C+2) [9B5A] 8 2304 +Spin N 1537 Mertactor B562732-B S Ri 110 ImDd G1 V { 3 } (A6D-1) [3A17] BC 14 -780 +Spin B 1604 Louzy D422A88-8 He Hi In Na Po 110 ImDd M2 V { 0 } (D99+1) [AA58] BE 7 1053 +Spin B 1607 Grant X664100-3 Lo Fo Re Lt R 222 ImDd K6 V { -3 } (300-5) [1111] 13 -15 +Spin F 1611 Phlume C887624-8 Ag Ni Ga Ri 710 ImDd G5 V M8 V { 0 } (954-2) [4636] BC 5 -360 +Spin J 1626 Iron E529000-0 Ba Re Lt 014 SwCf F0 V { -3 } (200-5) [0000] 9 -10 +Spin J 1627 Bronze E201000-0 Ba Ic Va Re Lt 010 SwCf M3 V { -3 } (200-5) [0000] 5 -10 +Spin J 1628 Mithril E568000-0 Ba Re Lt 001 SwCf F4 V { -3 } (200-5) [0000] 8 -10 +Spin N 1631 Talchek C7B1442-8 Fl He Ni Da A 601 CsIm K8 V M5 V { -2 } (731-5) [1214] 10 -105 +Spin N 1632 Milagro E31178A-7 Ic Na Pi 920 NaHu M2 V { -2 } (966+1) [9579] 15 324 +Spin N 1634 Pagaton C769873-4 Ri Ph Lt 913 NaHu F0 V { 0 } (A76-3) [5821] 11 -1260 +Spin N 1635 Binges A500231-A Lo Va 720 NaHu M0 V { 1 } (611-3) [1316] 6 -18 +Spin N 1637 Mille Falcs B9A2469-C NS Fl He Ni Mr Ht 301 ImDd M2 V { 2 } (735+3) [566D] B 12 315 +Spin C 1705 Efate A646930-D NW Hi In An Ht 800 ImDd F8 V { 5 } (B8H+1) [4E18] BEf 8 1496 +Spin C 1706 Alell B56789C-A Ri Pa Ph Pz A 210 ImDd M1 V M7 V { 3 } (B7C+5) [BB8D] BcCe 6 4620 +Spin G 1711 Extolay B55589A-A N Pa Ph Varg2 110 ImDd M2 V M4 V { 2 } (B7B+4) [AA7C] Bce 8 3388 +Spin G 1719 Lanth A879533-B NS Ni Cp 710 ImDd F5 IV M1 V { 2 } (846-1) [2728] BF 14 -192 +Spin K 1721 Arba C200200-C Lo Va Ht 610 ImDd M2 V { 0 } (510-4) [1217] B 11 -20 +Spin K 1727 Wardn B756486-B S Ni Ga Pa 502 ImDd K2 V { 1 } (834+1) [354A] Bc 7 96 +Spin K 1728 Olympia C428342-7 Lo 120 ImDd M3 V { -2 } (520-5) [1113] B 6 -50 +Spin K 1729 Smoug C54078A-9 De He Po Pi 902 ImDd M1 V M7 V { 0 } (B69+2) [977B] BD 7 1188 +Spin O 1731 Grote A400404-B Ni Va 124 ImDd F8 V { 1 } (C34-1) [2539] B 11 -144 +Spin O 1733 Lydia E310430-7 Ni 902 ImDd M4 III M0 V { -3 } (631-5) [1112] B 11 -90 +Spin O 1736 Melior D540466-7 De He Ni Po Da Jonk5 O:2036 A 724 ImDd G3 V { -3 } (631-4) [3146] B 9 -72 +Spin O 1737 Egypt BAC6567-9 N Fl Ni Mr 521 ImDd F8 V { 0 } (A44+1) [5559] B 14 160 +Spin O 1739 Aster C86A410-9 Ni Wa 401 ImDd K9 V { -1 } (732-5) [1314] B 14 -210 +Spin C 1802 Yres BAC6773-9 Fl 335 ImDd G5 V { 1 } (H6A-2) [4826] B 13 -2040 +Spin C 1803 Menorb C652998-7 Hi Po 310 ImDd K2 V { 0 } (B89+1) [9957] BE 7 792 +Spin C 1805 Uakye B439598-D Ni Ht 320 ImDd M3 V { 1 } (945+1) [565D] B 12 180 +Spin C 1806 Whanga E676126-7 Lo 224 ImDd G1 V M1 V { -3 } (300-4) [1146] B 14 -12 +Spin C 1807 Knorbes E888765-2 Ag Ri An Re Lt 834 ImDd G3 V { 0 } (965-2) [5731] BC 15 -540 +Spin C 1808 Forboldn D893614-5 Ni Lt 312 ImDd G0 V { -3 } (851-5) [4333] B 14 -200 +Spin C 1809 Ruie C776977-7 Hi In Pz Di(Daccamites) A 701 NaHu G5 V { 1 } (B8A+1) [9A57] 8 880 +Spin C 1810 Jenghe C799663-9 S Ni O:1910 323 ImDd M0 V { -1 } (D53-4) [3526] B 11 -780 +Spin G 1811 Dinom D300535-A Ni Va Sa 201 ImDd A4 V { -1 } (843-3) [3438] B 14 -288 +Spin G 1815 Ghandi B311455-A N Ic Ni 303 ImDd F8 V M3 V { 1 } (934-1) [2538] B 13 -108 +Spin G 1817 Victoria D6D7772-2 An Fo Lt R 112 ImDd K6 V { -2 } (963-5) [3511] 8 -810 +Spin K 1822 Rabwhar D5448BA-6 S Pa Ph Pi Pz A 313 ImDd K5 V { -2 } (A75+1) [A678] BcDe 12 350 +Spin K 1824 Adabicci A57189B-B N He Ph Pi Pz A 801 ImDd K8 V M8 V { 2 } (B7C+4) [AA7D] BDe 6 3696 +Spin K 1825 Zaibon B000544-B As Ni Va 502 ImDd M6 III M3 V { 1 } (945-1) [3639] B 9 -180 +Spin K 1826 Tenalphi A774722-E Ag An Pi Ht 610 ImDd F7 V { 3 } (A6E-1) [3A1A] BCD 12 -840 +Spin O 1836 Callia E550852-6 De Po Ph 810 ImDd M3 V { -2 } (A75-5) [4612] Be 11 -1750 +Spin C 1903 Pixie A100103-D N Lo Va An Px Ht 901 ImDd K1 V M0 V { 1 } (401-2) [122A] B 14 -8 +Spin C 1904 Boughene A8B3531-D S Fl Ni An Ht 601 ImDd M1 V { 1 } (845-3) [1619] B 13 -480 +Spin C 1909 Hefry C200423-7 S Ni Va 320 ImDd K6 II M2 V { -2 } (631-5) [1224] B 13 -90 +Spin C 1910 Regina A788899-C NS Ri Pa Ph An Cp (Amindii)2 Varg0 Asla0 Sa Ht 703 ImDd F7 V BD M3 V { 4 } (D7E+5) [9C6D] BcCeF 9 6370 +Spin G 1912 Dinomn B674632-9 S Ag Ni 204 ImDd G8 V { 1 } (C55-3) [2715] BC 11 -900 +Spin G 1916 Ylaven X587552-4 Ag Ni Pr Fo Lt R 922 ImDd F9 V { -2 } (742-5) [1311] 11 -280 +Spin G 1918 Sonthert D6266AB-7 Ni Da A 314 ImDd K6 V M0 V { -3 } (851-1) [8379] B 8 -40 +Spin G 1920 D'Ganzio B420410-D N De He Ni Po Ht 312 ImDd M0 V M3 V { 1 } (934-3) [1518] B 6 -324 +Spin K 1924 Ianic E560697-5 De Ni Ri Lt 924 ImDd M3 V M7 V { -2 } (852-2) [6455] BC 9 -160 +Spin K 1927 Spirelle C766846-8 S Ga Ri Pa Ph 715 ImDd G7 V { 0 } (G78-1) [7847] BcCe 14 -896 +Spin O 1932 Mithras C8B5568-8 Fl Ni Px 302 ImDd M2 III M0 V { -2 } (942-2) [5358] B 6 -144 +Spin O 1934 Weiss A626464-B Ni Da O:2036 A 703 ImDd M1 V { 1 } (934-1) [2539] B 10 -108 +Spin O 1935 Windsor C783511-9 Ni Pr 210 ImDd K9 V M0 V { -1 } (843-5) [1415] Bc 9 -480 +Spin O 1937 Overnale B55467A-9 Ag Ni 423 ImDd G3 V { 1 } (D55+3) [877B] BC 17 975 +Spin O 1938 New Rome B837866-B N Ph Asla3 O:2036 704 ImDd F8 V M0 V { 2 } (E7C+1) [7A4A] Be 12 1176 +Spin O 1939 Craw C573645-5 Ni (Crawni)2 Asla8 Lt 923 ImDd G7 V { -2 } (852-4) [4433] B 11 -320 +Spin C 2005 Feri B584879-B S Ri Pa Ph 620 ImDd G4 V M3 V { 3 } (C7D+4) [9B6C] BcCe 14 4368 +Spin C 2007 Roup C77A9A9-7 S Hi In Wa Pz A 323 ImDd F9 V { 1 } (B8A+2) [AA68] BE 14 1760 +Spin G 2011 Wypoc E9C4547-9 Fl Ni Da A 922 ImDd M3 V { -2 } (B42-2) [5359] B 9 -176 +Spin K 2024 Derchon C512799-8 S Ic Na Pi 901 ImDd M0 V M7 V { -1 } (A67+1) [8669] BD 5 420 +Spin O 2035 Aki B543987-9 Hi In Po Pz A 214 ImDd G6 V M2 V { 3 } (G8D+3) [9C59] BE 16 4992 +Spin O 2036 Glisten A000986-F NS As Hi In Na Va Cp Ht 811 ImDd K9 V { 5 } (D8H+4) [8E4E] BEF 13 7072 +Spin O 2038 Trane C639422-B Ni An 704 ImDd F4 V M3 V { 0 } (A33-4) [1417] B 12 -360 +Spin C 2106 Pscias X555423-2 Ni Pa Fo Lt R 501 ImDd K5 V { -3 } (631-5) [1121] 14 -90 +Spin C 2110 Yori C560757-A De Ri An (Zhurphani)6 RsB 713 ImDd F1 V { 2 } (D6B+2) [795A] BC 15 1716 +Spin G 2111 Djinni X559000-0 Ba Fo Lt R 022 ImDd K5 V { -3 } (200-5) [0000] 11 -10 +Spin G 2112 Rech D9957AA-6 Ag Pi Pz A 501 ImDd M0 V { -1 } (966+1) [9678] BCD 14 324 +Spin K 2124 Lunion A995984-D NS Hi In Cp Ht 810 ImDd G5 V { 5 } (C8H+3) [7E3B] BEF 11 4896 +Spin K 2125 Shirene B984510-B S Ag Ni Pr Da A 723 ImDd G4 V M1 V M1 V { 2 } (C46-2) [1716] BcC 12 -576 +Spin K 2128 Penkwhar D978310-5 Lo Da Lt A 320 ImDd M0 V { -3 } (520-5) [1111] B 9 -50 +Spin K 2129 Harvosette C430737-9 De Na Po 910 ImDd M0 V M5 V { 0 } (A69+1) [7759] B 11 540 +Spin O 2132 Centry E422447-7 He Ni Po 220 ImDd K3 V { -3 } (631-3) [4157] B 10 -54 +Spin O 2134 Caledonia C541636-5 He Ni Po Lt 910 ImDd M4 III M0 V { -2 } (852-3) [5444] B 10 -240 +Spin O 2137 Sorel E58569A-2 Ag Ni Ri Lt 921 ImDd G3 V M3 V { -1 } (853+1) [8574] BC 8 120 +Spin O 2138 Horosho C4378A6-A S Ph 920 ImDd F4 V { 1 } (C7A+1) [7949] Be 10 840 +Spin O 2140 Romar B550456-8 NS De Ni Po 112 ImDd K2 V M3 V { 0 } (933-1) [3447] B 6 -81 +Spin C 2201 Dentus C979500-A S Ni 920 ImDd M2 V { 0 } (944-4) [1515] B 10 -576 +Spin C 2202 Kinorb A663659-8 Ni Ri 622 ImDd G7 V { 0 } (C54+1) [7669] BC 7 240 +Spin C 2204 Beck's World D88349D-4 Ni An Da Lt A 701 ImDd K0 V M2 V { -3 } (631+1) [8198] B 10 18 +Spin C 2205 Enope C411988-7 Hi Ic In Na 600 ImDd K6 V M5 V { 1 } (B8A+1) [9A57] BE 8 880 +Spin C 2207 Wochiers EAC28CC-9 Fl He Ph Pz A 703 ImDd F0 V { -1 } (D78+2) [B78C] Be 16 1456 +Spin G 2212 K'Kirka CAA5345-8 Fl Lo 102 ImDd M2 V { -2 } (720-4) [1136] B 7 -56 +Spin G 2215 Quopist B551679-A Ni Po Da A 721 ImDd M3 V { 1 } (B55+2) [776B] B 8 550 +Spin K 2224 Carse C563325-9 Lo 601 ImDd M3 V M6 V { -1 } (620-3) [1237] B 13 -36 +Spin K 2228 Persephone B775833-A W Pa Ph Pi 922 ImDd M2 V { 3 } (E7C+1) [5B27] BcDe 10 1176 +Spin O 2231 Marastan D868764-5 S Ag Ri Pz Re Lt A 924 ImDd K7 V { 0 } (967-2) [5733] BC 12 -756 +Spin O 2232 Crout E4359CA-7 Hi Pz A 314 ImDd M7 III M2 V { -1 } (B88+1) [B879] BE 9 704 +Spin O 2233 Tirem C7B5975-B Fl Hi In 621 ImDd K5 V { 3 } (E8E+1) [7C39] BE 13 1568 +Spin O 2234 Inthe C100598-B Ni Va 924 ImDd K3 V { 0 } (D44+1) [555B] B 14 208 +Spin O 2236 Tsarina D420636-7 De He Na Ni Po 301 ImDd M2 V M2 V { -3 } (851-4) [5346] B 10 -160 +Spin O 2237 Wurzburg C795300-A S Lo Da A 510 ImDd F8 V { 0 } (620-4) [1315] B 7 -48 +Spin C 2303 Yorbund C7C6503-9 Fl Ni 220 ImDd M3 V { -1 } (943-4) [2426] B 9 -432 +Spin C 2306 Shionthy C000742-8 As Na Va An Pi Fo R 714 ImDd F6 V { -1 } (E67-5) [3614] 14 -2940 +Spin C 2308 Algine X766977-4 Hi Ga Pr Fo Lt R 723 ImDd G9 V { -1 } (B86-1) [9854] 11 -528 +Spin C 2309 Yurst E7B4643-8 Fl Ni (Ursty) 824 ImDd K9 V { -3 } (E51-5) [3325] B 13 -350 +Spin G 2311 Treece D432866-8 Na Po Ph O:2410 610 ImDd M1 V { -2 } (B76-3) [7647] Be 9 -1386 +Spin G 2313 Echiste C53A313-A Lo Wa 720 ImDd G4 V { 0 } (720-3) [1327] B 10 -42 +Spin G 2314 Pirema D691142-5 He Lo Lt 802 ImDd M2 V { -3 } (300-5) [1111] B 7 -15 +Spin G 2317 Rhise C100576-A Ni Va Da A 710 ImDd K7 V { 0 } (844-1) [4549] B 8 -128 +Spin G 2319 Ivendo B424659-A NS Ni 112 ImDd A9 V { 2 } (B56+3) [786B] B 11 990 +Spin K 2321 Quiru B565300-8 Lo 323 ImDd M3 V { -1 } (A20-5) [1213] B 9 -100 +Spin K 2322 Gorram X554220-2 Lo Fo Lt R 801 ImDd K8 V M6 V { -3 } (410-5) [1111] 9 -20 +Spin K 2323 Resten B310100-B S Lo 501 ImDd K5 V M8 V { 1 } (401-3) [1216] B 10 -12 +Spin K 2324 Capon B747748-A N Ag Pi 610 ImDd F9 V { 3 } (A6C+3) [7A5A] BCD 10 2160 +Spin K 2325 Sharrip C575101-A Lo 503 ImDd K5 V { 0 } (600-4) [1116] B 16 -24 +Spin K 2327 Strouden A745988-D N Hi In Ht 920 ImDd G5 V M4 V { 4 } (D8G+4) [9D5D] BEf 8 6656 +Spin O 2331 Bicornn E563576-2 Ni Pr Lt 210 ImDd F3 V M3 V { -3 } (741-4) [4241] Bc 11 -112 +Spin O 2334 Ffudn A41489D-C Ic Ph Pi Pz Ht A 904 ImDd M0 V { 2 } (E7C+5) [CA9G] BDe 12 5880 +Spin O 2336 Bendor A756656-C NS Ag Ni Ga Ht 820 ImDd F5 V { 3 } (A57+2) [594B] BC 8 700 +Spin C 2402 Heya B687745-5 Ag Ga Ri Lt 734 ImDd K6 III M3 V { 2 } (969+1) [5933] BC 16 486 +Spin C 2405 Keng E5718CA-5 He Ph Pi Pz Lt A 812 ImDd G5 V M9 V { -2 } (A75+1) [A677] BDe 6 350 +Spin C 2406 Moughas CA5A588-B Ni Oc 801 ImDd K9 V M9 V { 0 } (844+1) [555B] B 13 128 +Spin C 2408 Rethe E430AA8-8 De Hi Na Po 323 ImDd G7 V { -1 } (H98-1) [A958] BE 11 -1224 +Spin C 2410 Inthe B575776-9 NS Ag An Pi 423 ImDd F8 V { 3 } (E6C+2) [6A48] BCD 8 2016 +Spin G 2411 Keanou C792348-7 S He Lo 213 ImDd M3 III M2 V { -2 } (520-2) [3157] B 12 -20 +Spin G 2414 Tureded C565540-9 Ag Ni Pr 614 ImDd M3 V { 0 } (C44-4) [1514] BcC 11 -768 +Spin G 2415 Vreibefger E581542-3 Ni Pr RsE Lt 901 ImDd K9 V { -3 } (741-5) [1211] Bc 8 -140 +Spin G 2416 La'Belle C564112-4 Lo Lt 701 ImDd F2 V M3 V { -2 } (300-5) [1111] B 11 -15 +Spin G 2417 Equus B55A858-B S Wa Ph Dolp1 202 ImDd F6 V M1 V { 2 } (C7C+2) [8A5B] Be 12 2016 +Spin G 2418 Icetina B5245A9-7 N Ni 301 ImDd K9 V M8 V { -1 } (743+1) [6468] B 13 84 +Spin G 2419 Cogri CA6A643-9 Ni Oc Ri 432 ImDd M1 V { 0 } (D54-3) [3626] BC 8 -780 +Spin G 2420 Skull C4237C7-9 N Na Po Pi 601 ImDd M0 V M1 V { 0 } (A69+1) [7759] BD 12 540 +Spin K 2425 Gandr E000347-8 As Lo Va 803 ImDd M1 V { -3 } (820-3) [3158] B 9 -48 +Spin K 2426 Drolraw EAB6311-8 Fl Lo 904 ImDd F1 V { -3 } (920-5) [1114] B 12 -90 +Spin D 2509 Paya A655241-9 N Lo Ga 603 ImDd F3 V { 0 } (710-4) [1215] B 14 -28 +Spin D 2510 Dhian C9A769D-8 Fl Ni Da A 202 ImDd K5 V { -2 } (A52+2) [A49C] B 13 200 +Spin H 2512 Kinorb C549433-9 Ni 502 ImDd F0 V K9 V { -1 } (832-4) [1326] B 14 -192 +Spin H 2514 Gileden C583103-6 Lo 203 ImDd M1 V { -2 } (300-5) [1123] B 13 -15 +Spin H 2519 Pannet E9C5677-9 Fl Ni 224 ImDd K5 V { -2 } (E52-2) [6459] B 11 -280 +Spin H 2520 Garrincski B632520-7 S Ni Po 410 ImDd M0 V M7 V { -1 } (743-5) [1412] B 9 -420 +Spin L 2521 Heroni B6449B9-8 Hi In Pz A 721 ImDd F3 V { 2 } (E8B+3) [AB69] BE 14 3696 +Spin L 2523 Byret B585697-6 Ag Ni Ri (Larianz) 812 ImDd G9 V { 1 } (855+1) [6756] BC 7 200 +Spin L 2527 Pimane E500343-7 Lo Va 903 ImDd K0 V { -3 } (520-5) [1124] B 10 -50 +Spin P 2534 Burtson C562667-8 Ni Ri O:2733 402 ImDd G4 V { -1 } (A53-1) [6558] BC 13 -150 +Spin P 2536 Squanine A300550-B Ni Va 303 ImDd F4 V M2 V { 1 } (A45-3) [1616] B 8 -600 +Spin P 2537 Dobham A550457-A S De Ni Po 523 ImDd G0 V { 1 } (B34+1) [455A] B 11 132 +Spin P 2538 Pyramus E566335-2 Lo Lt 214 ImDd K6 V { -3 } (520-5) [1131] B 11 -50 +Spin P 2539 Thisbe E4305AD-6 De Ni Po Da A 322 ImDd F8 V { -3 } (741+1) [929A] B 10 28 +Spin P 2540 Aramis B659772-6 924 ImDd K5 V { 0 } (967-4) [3712] B 9 -1512 +Spin D 2602 Corfu C895674-8 Ag Ni An Da A 222 ImDd M0 V { -1 } (C53-3) [4536] BC 7 -540 +Spin D 2607 Focaline EA88544-7 Ag Ni Pr 724 ImDd F3 V { -2 } (742-4) [3335] BcC 11 -224 +Spin H 2612 Macene B000453-E N As Ni Va Ht 901 ImDd G8 V M8 V { 1 } (734-2) [152B] B 11 -168 +Spin H 2613 Fulacin A674210-D Lo An Ht 810 ImDd G3 V { 1 } (511-3) [1318] B 12 -15 +Spin H 2620 Natoko C8879AB-9 Hi Ga An Pr Pz A 204 ImDd F4 V { 1 } (F8B+3) [BA7B] BcE 9 3960 +Spin L 2621 Fosey A633656-A Na Ni Po 620 ImDd M3 V { 1 } (A55+1) [5749] B 11 250 +Spin L 2624 Mercury B658663-8 NS Ag Ni Mr 304 ImDd F7 V { 1 } (C55-2) [3725] BC 13 -600 +Spin L 2627 Tivid C534477-8 Ni 401 ImDd M3 V { -2 } (731-2) [4258] B 11 -42 +Spin P 2637 Robin C00059C-C As Ni Va Da Ht A 202 ImDd M2 V { 0 } (944+3) [858F] B 6 432 +Spin P 2638 D'Mara E75A798-5 Wa Lt 910 ImDd F4 V { -2 } (965-2) [7555] B 14 -540 +Spin P 2639 Keltchner C525567-9 Ni O:Troj-2402 602 ImDd K6 V { -1 } (943-1) [5459] B 15 -108 +Spin D 2701 Lablon B646589-A Ag Ni 503 ImDd M2 III M4 V { 2 } (A46+3) [676B] BC 14 720 +Spin D 2706 Heguz E66A224-9 Lo Wa 510 ImDd K2 V M7 V { -2 } (510-4) [1137] B 10 -20 +Spin D 2708 Violante C669452-A Ni 420 ImDd G2 V { 0 } (833-4) [1416] B 10 -288 +Spin H 2712 Risek A425579-A N Ni 401 ImDd M2 V M3 V { 1 } (845+2) [666B] B 11 320 +Spin H 2715 Porozlo A867A74-B Hi Ga 201 ImDd M1 V M9 V { 3 } (D9E+1) [8D39] BE 11 1638 +Spin H 2716 Rhylanor A434934-F NS Hi Cp Llel4 Ht 810 ImDd M2 V { 4 } (C8G+2) [7D3D] BEF 12 3072 +Spin H 2720 Loneseda C86A215-7 Lo Wa 705 ImDd K9 V { -2 } (410-4) [1135] B 14 -16 +Spin L 2726 Carey C579221-9 Lo 910 ImDd M2 V M2 V { -1 } (510-5) [1115] B 4 -25 +Spin L 2728 Duale A5437BF-B Po Pi Pz RsA A 401 ImDd M0 V M2 V { 2 } (A6C+5) [C9AG] BD 5 3600 +Spin P 2731 Tussinian B678324-7 Lo 520 ImDd K0 V { -1 } (520-3) [1235] B 7 -30 +Spin P 2733 Edenelt A5638BD-B Ri Ph Pz A 934 ImDd G7 V { 3 } (H7D+5) [CB9F] BCe 10 7735 +Spin P 2735 Conway D894586-7 S Ag Ni 311 ImDd F0 V M0 V { -2 } (742-3) [4346] BC 12 -168 +Spin P 2739 Dodds C5439DF-7 S Hi In Po Pz A 423 ImDd G7 V { 1 } (B8A+5) [EAAC] BE 13 4400 +Spin H 2811 Valhalla E565432-5 Ni Pa Lt 622 ImDd G4 V { -3 } (631-5) [1111] Bc 9 -90 +Spin H 2812 Zivije C6B199C-B Fl He Hi In Pz A 421 ImDd G6 V { 3 } (E8E+5) [CC8E] BE 11 7840 +Spin H 2814 Jae Tellona A560565-8 N De Ni Pr Mr 913 ImDd F9 V { -1 } (B43-3) [3436] Bc 9 -396 +Spin H 2818 Gerome X573000-0 Ba Fo Lt R 001 ImDd K2 V { -3 } (200-5) [0000] 11 -10 +Spin L 2824 Catuz C42048C-9 De He Ni Po Da A 510 ImDd K8 V M6 V { -1 } (732+2) [738C] B 5 84 +Spin L 2827 Meleto C675100-5 S Lo Lt 724 ImDd F9 V { -2 } (300-5) [1111] B 9 -15 +Spin L 2828 Hexos B534420-8 N Ni 123 ImDd K1 V M2 V { -1 } (B32-5) [1313] B 10 -330 +Spin L 2830 Pedase C415346-7 S Ic Lo 101 ImDd M2 V M7 V { -2 } (520-3) [2146] B 11 -30 +Spin P 2832 Leander E695244-5 Lo Lt 801 ImDd K5 V M1 V { -3 } (410-5) [1133] B 10 -20 +Spin P 2833 Pepernium D567530-3 Ag Ni Pr Lt 503 ImDd M1 V { -2 } (742-5) [1311] BcC 10 -280 +Spin P 2834 Traltha B590630-6 De He Ni An 410 ImDd F5 V { -1 } (853-5) [1511] B 8 -600 +Spin P 2839 Farquahar C625543-7 S Ni 201 ImDd M3 V { -2 } (742-5) [2324] B 11 -280 +Spin D 2905 Pavanne E310000-0 Ba Lt 025 ImDd M0 V { -3 } (200-5) [0000] 12 -10 +Spin D 2906 Carsten C427402-B Ni 804 ImDd M1 V { 0 } (A33-4) [1417] B 15 -360 +Spin D 2908 Zila E556727-7 Ag Pz A 701 ImDd K6 V M3 V { -1 } (967-1) [7657] BC 8 -378 +Spin H 2912 Henoz A545543-B Ag Ni 824 ImDd F3 V { 2 } (D46-1) [2728] BC 11 -312 +Spin H 2913 Celepina B434456-9 NS Ni 201 ImDd M2 V { 1 } (734+1) [3548] B 13 84 +Spin H 2918 Gitosy B000676-9 As Na Ni Va 610 ImDd G6 V M3 V { 0 } (954-1) [5648] B 6 -180 +Spin L 2924 Moran C567300-8 N Lo 201 ImDd M3 V M7 V { -2 } (620-5) [1113] B 10 -60 +Spin L 2927 Maitz A201511-B Ic Ni Va 122 ImDd F1 V { 1 } (B45-3) [1617] B 11 -660 +Spin L 2930 Mainz C553352-A S Lo Po 803 ImDd K2 V M7 V { 0 } (820-4) [1316] B 11 -64 +Spin P 2933 Raydrad E99467A-6 Ag Ni 303 ImDd M7 III M2 V { -2 } (852+1) [8478] BC 10 80 +Spin P 2934 Zyra B555448-7 Ni Pa 601 ImDd K8 V { -1 } (632-1) [4357] Bc 7 -36 +Spin P 2935 Murchison B544433-6 N Ni Pa 305 ImDd M5 III M3 V { -1 } (632-4) [1323] Bc 8 -144 +Spin P 2936 Hammermium A5525AB-B Ni Po Da A 535 ImDd M3 V { 1 } (F45+3) [767D] B 11 900 +Spin P 2940 Thornnastor D534443-8 S Ni 804 ImDd M1 V { -3 } (A31-5) [1125] B 12 -150 +Spin D 3001 Jesedipere C775300-7 Lo Varg3 611 ImDd F4 V { -2 } (520-5) [1112] B 12 -50 +Spin D 3002 Yebab C9A489A-8 Fl Ph (Ebokin) 712 ImDd G9 V { -1 } (D77+1) [A77A] Be 10 637 +Spin D 3003 Nasemin B98A422-B S Ni Wa 612 ImDd F5 V { 1 } (934-3) [1517] B 10 -324 +Spin D 3004 Zykoca D994542-6 Ag Ni Da A 320 ImDd K9 V { -2 } (742-5) [1312] BC 12 -280 +Spin D 3005 Aramanx B657974-7 Hi Ga Pz A 210 ImDd G0 V { 1 } (B8A-1) [7A35] BE 13 -880 +Spin D 3008 Pysadi C5766D8-5 Ag Ni Da Lt A 201 ImDd F9 V M1 V { -1 } (853-1) [6555] BC 8 -120 +Spin D 3010 L'oeul d'Dieu B98A510-B N Ni Wa Pr 502 ImDd G1 V M9 V { 1 } (945-3) [1616] Bc 6 -540 +Spin H 3015 Belizo B895646-5 Ag Ni Asla3 Lt 923 ImDd K1 V { 0 } (854-1) [5644] BC 11 -160 +Spin H 3016 Kegena E869569-3 Ni Pr Da O:2716 Lt A 224 ImDd F6 V { -3 } (741-2) [6264] Bc 12 -56 +Spin H 3017 Heroni E7A0614-8 He Ni 820 ImDd G5 V { -3 } (A51-5) [4336] B 8 -250 +Spin H 3019 457-973 X572776-5 He Pi Fo (minor) Lt R 334 ImDd G9 V { -2 } (965-3) [6544] 10 -810 +Spin H 3020 Somem C301340-B Ic Lo Va 201 ImDd M2 V M7 V { 0 } (620-4) [1316] B 14 -48 +Spin L 3021 Brodie C410468-7 Ni O:3124 114 ImDd M1 III M7 V { -2 } (631-2) [4257] B 15 -36 +Spin L 3022 Rorise C994100-A Lo 502 ImDd M1 V { 0 } (500-4) [1115] B 8 -20 +Spin L 3024 Jokotre B6548D9-7 Pa Ph Pz A 810 ImDd K6 V { 0 } (A78+1) [9868] Bce 9 560 +Spin L 3025 Fornice A554A87-C Hi Ht 202 ImDd M0 V { 3 } (E9E+3) [AD5C] BE 13 5292 +Spin L 3026 Grille E410335-7 Lo 701 ImDd M2 V M2 V { -3 } (520-5) [1135] B 12 -50 +Spin L 3029 Palique A511965-E Hi Ic In Na Pz O:3025 Ht A 320 ImDd M0 V M1 V { 4 } (D8G+2) [7D3C] BEf 5 3328 +Spin L 3030 Nexine C97A443-8 S Ni Wa (Nexxies) 801 ImDd G9 V M2 V { -2 } (731-5) [1225] B 12 -105 +Spin P 3032 Katarulu B552665-B NW Ni Po Mr 201 ImDd M0 V M9 V { 2 } (956+1) [4839] B 9 270 +Spin P 3035 Prilissa B985588-6 Ag Ni Pr 510 ImDd K4 V { 0 } (744+1) [5556] BcC 9 112 +Spin P 3038 Tee-Tee-Tee C310530-9 Ni 902 ImDd M2 V { -1 } (943-5) [1414] B 7 -540 +Spin P 3039 Youghal AA95345-B Lo 201 ImDd K3 V { 1 } (621-1) [1439] B 14 -12 +Spin P 3040 Tenelphi D76A579-9 S Ni Wa Pr 901 ImDd F4 V M0 V { -2 } (842-1) [636A] Bc 11 -64 +Spin D 3102 Rugbird BAC5634-A Fl Ni Da A 811 ImDd M1 V { 1 } (A55-1) [4738] B 14 -250 +Spin D 3103 Towers B544448-A S Ni Pa Da A 735 ImDd G8 V K6 V { 1 } (E34+1) [455A] Bc 11 168 +Spin D 3104 Feneteman C422200-C He Lo Po Ht 910 ImDd G4 V M7 V { 0 } (510-4) [1217] B 4 -20 +Spin D 3107 Lewis D427402-7 Ni Fo R 701 ImDd F8 V { -3 } (631-5) [1113] 9 -90 +Spin D 3110 Aramis A5A0556-B NS He Ni Cp 710 ImDd M2 V { 2 } (846+1) [474A] BF 9 192 +Spin H 3111 Vinorian B879610-9 Ni 610 ImDd M3 V M4 V { 0 } (954-4) [1614] B 13 -720 +Spin H 3112 Nutema B864310-8 N Lo 822 ImDd M3 V { -1 } (920-5) [1213] B 7 -90 +Spin H 3114 Huderu X575000-0 Ba Fo Lt R 020 ImDd M0 V { -3 } (200-5) [0000] 10 -10 +Spin H 3118 Cipatwe B55879A-6 Ag 623 ImDd M1 V { 1 } (968+3) [9878] BC 12 1296 +Spin H 3119 Vanejen C686854-5 Ga Ri Pa Ph Chir1 RsG Lt 520 ImDd G1 V M0 V { 0 } (A77-2) [6833] BcCe 11 -980 +Spin L 3123 Nadrin D420203-7 S De He Lo Po 920 ImDd K5 V M1 V { -3 } (410-5) [1124] B 15 -20 +Spin L 3124 Mora AA99AC7-F NS Hi In Cs Ht 112 ImDd F0 V { 5 } (F9H+5) [AF5F] BEF 9 11475 +Spin P 3138 Zephyr C89556A-5 Ag Ni Da O:3235 Lt A 404 ImDd K5 V { -1 } (743+1) [7477] BC 9 84 +Spin P 3139 Chamois B544642-5 S Ag Ni Lt 723 ImDd F9 V { 0 } (854-4) [2611] BC 8 -640 +Spin D 3202 Junidy B434ABD-B W Hi Pz (Llellewyloly)5 A 310 ImDd F7 V M2 V { 4 } (D9F+5) [EE9F] BEf 14 8775 +Spin D 3207 Patinir C000632-9 As Na Ni Va An 213 ImDd F3 V { -1 } (C53-5) [2515] B 15 -900 +Spin D 3209 Natoko B582211-8 N Lo 801 ImDd M2 V M6 V { -1 } (510-5) [1114] B 14 -25 +Spin D 3210 Reacher C9A8542-8 Fl Ni Da A 233 ImDd G4 V { -2 } (D42-5) [1314] B 12 -520 +Spin H 3212 Margesi A576257-C NS Lo Ht 920 ImDd F0 V { 2 } (612+2) [245C] B 12 24 +Spin H 3216 Bevey D4209CC-A S De He Hi In Na Po Pz A 224 ImDd F4 V { 2 } (H8C+5) [CB8D] BE 9 8160 +Spin H 3218 Tacaxeb C430411-B De Ni Po 801 ImDd A5 V M2 V { 0 } (733-4) [1417] B 10 -252 +Spin H 3220 Powaza C787566-5 Ag Ni Ga Pr O:3124 Lt 332 ImDd K4 V M2 V { -1 } (743-2) [4444] BcC 13 -168 +Spin L 3223 Dojodo C512311-7 S Ic Lo 710 ImDd M0 V { -2 } (520-5) [1113] B 14 -50 +Spin L 3228 Fenl's Gren C647346-9 Lo Da A 423 ImDd K7 V { -1 } (A20-2) [2248] B 12 -40 +Spin P 3233 Ramiva B3107A7-8 Na Pi 913 ImDd M3 V { 0 } (D68+1) [7758] BD 9 624 +Spin P 3235 Trin A894A96-F NS Hi In Cp Ht 101 ImDd G0 V { 5 } (D9H+4) [9F4E] BEF 8 7956 +Spin P 3236 Hazel C645747-5 Ag Pi Pz Lt A 110 ImDd F1 V M3 V { 0 } (967+1) [7755] BCD 14 378 diff --git a/sector.odin b/sector.odin index ff010af..7f1584c 100644 --- a/sector.odin +++ b/sector.odin @@ -7,10 +7,13 @@ package main import "core:math" +import "core:path/filepath" import "core:strings" import rl "vendor:raylib" -new_sector :: proc(name: string, origin: Point = {0, 0}) -> Sector { +new_sector :: proc(path: string, origin: Point = {0, 0}) -> (sector: Sector, err: Error) { + name := filepath.short_stem(path) + hexes: map[string]Hex left := origin.x @@ -29,7 +32,7 @@ new_sector :: proc(name: string, origin: Point = {0, 0}) -> Sector { layout := new_layout(flat_orientation(), origin, {HEX_SIZE, HEX_SIZE}) - return {name, hexes, layout} + return {name, hexes, layout}, nil } delete_sector :: proc(sector: Sector) { diff --git a/sector_test.odin b/sector_test.odin index 2a4c99b..902c884 100644 --- a/sector_test.odin +++ b/sector_test.odin @@ -10,10 +10,13 @@ import "core:testing" @(test) test_new_sector :: proc(t: ^testing.T) { - sector := new_sector("Foo") + sector, err := new_sector("assets/Spinward Marches.tab") + if err != nil { + testing.fail(t) + } defer delete_sector(sector) - testing.expect_value(t, sector.name, "Foo") + testing.expect_value(t, sector.name, "Spinward Marches") testing.expect_value(t, sector.layout.origin, Point{0, 0}) testing.expect_value(t, sector.layout.size, Point{HEX_SIZE, HEX_SIZE}) } diff --git a/types.odin b/types.odin index 5f87e13..f67d765 100644 --- a/types.odin +++ b/types.odin @@ -6,10 +6,12 @@ package main +import "core:os" import rl "vendor:raylib" -Error :: enum { - Initialization_Failed, +Error :: union { + os.Error, + Spinward_Error, } Hex :: rl.Vector3 @@ -34,3 +36,7 @@ Sector :: struct { hexes: map[string]Hex, layout: Layout, } + +Spinward_Error :: enum { + Initialization_Failed, +} From c1322f90f47cfa104412a5afadb2e82c6d45120e Mon Sep 17 00:00:00 2001 From: Theomund <34360334+theomund@users.noreply.github.com> Date: Sun, 19 Jul 2026 00:06:55 +0000 Subject: [PATCH 04/10] feat: create star systems --- app.odin | 2 ++ constants.odin | 7 ++++++- hex.odin | 7 +++++++ sector.odin | 57 +++++++++++++++++++++++++++++++++++--------------- system.odin | 50 +++++++++++++++++++++++++++++++++++++++++++ types.odin | 14 ++++++++++--- 6 files changed, 116 insertions(+), 21 deletions(-) create mode 100644 system.odin diff --git a/app.odin b/app.odin index a144ae1..defe8ea 100644 --- a/app.odin +++ b/app.odin @@ -19,7 +19,9 @@ run :: proc() -> Error { } camera := new_camera() + sector := new_sector("assets/Spinward Marches.tab") or_return + defer delete_sector(sector) for !rl.WindowShouldClose() { rl.BeginDrawing() diff --git a/constants.odin b/constants.odin index 4a4ff4b..e147294 100644 --- a/constants.odin +++ b/constants.odin @@ -6,7 +6,10 @@ package main -HEX_SIZE :: 24 +FONT_SIZE :: 16 +FONT_SPACING :: 2 + +HEX_SIZE :: 64 ODD_OFFSET :: -1 @@ -16,3 +19,5 @@ WINDOW_TITLE :: "Spinward" SECTOR_COLUMNS :: 32 SECTOR_ROWS :: 40 + +WORLD_SIZE :: 12 diff --git a/hex.odin b/hex.odin index 394c1be..41a2645 100644 --- a/hex.odin +++ b/hex.odin @@ -8,6 +8,7 @@ package main import "core:fmt" import "core:math" +import rl "vendor:raylib" new_hex :: proc(q, r, s: f32) -> Hex { assert(math.round(q + r + s) == 0) @@ -55,3 +56,9 @@ hex_round :: proc(hex: Hex) -> Hex { return new_hex(q, r, s) } + +draw_hex :: proc(layout: Layout, hex: Hex, color: rl.Color) { + center := hex_to_pixel(layout, hex) + + rl.DrawPolyLines(center, 6, HEX_SIZE, 0, color) +} diff --git a/sector.odin b/sector.odin index 7f1584c..2fa95a7 100644 --- a/sector.odin +++ b/sector.odin @@ -6,15 +6,17 @@ package main +import "core:encoding/csv" import "core:math" +import "core:os" import "core:path/filepath" import "core:strings" import rl "vendor:raylib" new_sector :: proc(path: string, origin: Point = {0, 0}) -> (sector: Sector, err: Error) { - name := filepath.short_stem(path) + name := strings.clone_to_cstring(filepath.short_stem(path)) - hexes: map[string]Hex + systems: map[string]System left := origin.x right := origin.x + SECTOR_COLUMNS @@ -26,17 +28,48 @@ new_sector :: proc(path: string, origin: Point = {0, 0}) -> (sector: Sector, err for r := top - q_offset; r <= bottom - q_offset; r += 1 { hex := new_hex(q, r, -q - r) index := hex_index(hex) - hexes[index] = hex + systems[index] = new_system(hex) + } + } + + reader := csv.Reader { + comma = '\t', + comment = '#', + fields_per_record = -1, + reuse_record = true, + reuse_record_buffer = true, + } + defer csv.reader_destroy(&reader) + + data := os.read_entire_file(path, context.allocator) or_return + defer delete(data) + + csv.reader_init_with_string(&reader, string(data)) + + for record, _, err in csv.iterator_next(&reader) { + if err != nil { + return sector, err + } + + if system := &systems[record[2]]; system != nil { + system.name = strings.clone_to_cstring(record[3]) + system.world = true } } layout := new_layout(flat_orientation(), origin, {HEX_SIZE, HEX_SIZE}) - return {name, hexes, layout}, nil + return {name, systems, layout}, nil } delete_sector :: proc(sector: Sector) { - delete(sector.hexes) + delete(sector.name) + + for _, system in sector.systems { + delete_system(system) + } + + delete(sector.systems) } contains_hex :: proc(hex: Hex) -> bool { @@ -46,24 +79,14 @@ contains_hex :: proc(hex: Hex) -> bool { } draw_sector :: proc(sector: Sector, camera: rl.Camera2D) { - for _, hex in sector.hexes { - draw_hex(sector.layout, hex, rl.DARKGRAY) + for index, system in sector.systems { + draw_system(sector, strings.clone_to_cstring(index), system) } position := rl.GetScreenToWorld2D(rl.GetMousePosition(), camera) hovered := pixel_to_hex_rounded(sector.layout, position) if contains_hex(hovered) { - index := strings.clone_to_cstring(hex_index(hovered)) - - rl.DrawText(index, i32(position.x), i32(position.y - 8), 8, rl.WHITE) - draw_hex(sector.layout, hovered, rl.RED) } } - -draw_hex :: proc(layout: Layout, hex: Hex, color: rl.Color) { - center := hex_to_pixel(layout, hex) - - rl.DrawPolyLines(center, 6, HEX_SIZE, 0, color) -} diff --git a/system.odin b/system.odin new file mode 100644 index 0000000..6129dcd --- /dev/null +++ b/system.odin @@ -0,0 +1,50 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +package main + +import rl "vendor:raylib" + +new_system :: proc(hex: Hex, name: cstring = "", world := false) -> System { + return {name, hex, world} +} + +delete_system :: proc(system: System) { + if system.name != "" { + delete(system.name) + } +} + +draw_system :: proc(sector: Sector, index: cstring, system: System) { + draw_hex(sector.layout, system.hex, rl.DARKGRAY) + + center := hex_to_pixel(sector.layout, system.hex) + + if system.world { + rl.DrawCircle(i32(center.x), i32(center.y), WORLD_SIZE, rl.BLUE) + } + + font := rl.GetFontDefault() + name_size := rl.MeasureTextEx(font, system.name, FONT_SIZE, FONT_SPACING) + index_size := rl.MeasureTextEx(font, index, FONT_SIZE, FONT_SPACING) + + rl.DrawTextEx( + font, + system.name, + {center.x - (name_size.x / 2), (center.y - (HEX_SIZE / 2)) - (name_size.y / 2)}, + FONT_SIZE, + FONT_SPACING, + rl.WHITE, + ) + rl.DrawTextEx( + font, + index, + {center.x - (index_size.x / 2), (center.y + (HEX_SIZE / 2)) - (index_size.y / 2)}, + FONT_SIZE, + FONT_SPACING, + rl.DARKGRAY, + ) +} diff --git a/types.odin b/types.odin index f67d765..4607ba2 100644 --- a/types.odin +++ b/types.odin @@ -6,10 +6,12 @@ package main +import "core:encoding/csv" import "core:os" import rl "vendor:raylib" Error :: union { + csv.Error, os.Error, Spinward_Error, } @@ -32,9 +34,15 @@ Orientation :: struct { Point :: rl.Vector2 Sector :: struct { - name: string, - hexes: map[string]Hex, - layout: Layout, + name: cstring, + systems: map[string]System, + layout: Layout, +} + +System :: struct { + name: cstring, + hex: Hex, + world: bool, } Spinward_Error :: enum { From a29feb9e9e222f75be7e532e732fee077ed8e830 Mon Sep 17 00:00:00 2001 From: Theomund <34360334+theomund@users.noreply.github.com> Date: Sun, 19 Jul 2026 00:21:04 +0000 Subject: [PATCH 05/10] feat: remove world boolean --- sector.odin | 1 - system.odin | 6 +++--- types.odin | 5 ++--- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/sector.odin b/sector.odin index 2fa95a7..6493488 100644 --- a/sector.odin +++ b/sector.odin @@ -53,7 +53,6 @@ new_sector :: proc(path: string, origin: Point = {0, 0}) -> (sector: Sector, err if system := &systems[record[2]]; system != nil { system.name = strings.clone_to_cstring(record[3]) - system.world = true } } diff --git a/system.odin b/system.odin index 6129dcd..5424b06 100644 --- a/system.odin +++ b/system.odin @@ -8,8 +8,8 @@ package main import rl "vendor:raylib" -new_system :: proc(hex: Hex, name: cstring = "", world := false) -> System { - return {name, hex, world} +new_system :: proc(hex: Hex, name: cstring = "") -> System { + return {name, hex} } delete_system :: proc(system: System) { @@ -23,7 +23,7 @@ draw_system :: proc(sector: Sector, index: cstring, system: System) { center := hex_to_pixel(sector.layout, system.hex) - if system.world { + if system.name != "" { rl.DrawCircle(i32(center.x), i32(center.y), WORLD_SIZE, rl.BLUE) } diff --git a/types.odin b/types.odin index 4607ba2..1c90714 100644 --- a/types.odin +++ b/types.odin @@ -40,9 +40,8 @@ Sector :: struct { } System :: struct { - name: cstring, - hex: Hex, - world: bool, + name: cstring, + hex: Hex, } Spinward_Error :: enum { From c7c65df4c5ea8dcace0fa41c58a69fdac767fca4 Mon Sep 17 00:00:00 2001 From: Theomund <34360334+theomund@users.noreply.github.com> Date: Sun, 19 Jul 2026 02:05:39 +0000 Subject: [PATCH 06/10] feat: create sector reader --- reader.odin | 44 ++++++++++++++++++++++++++++++++++++++++++++ sector.odin | 27 +++------------------------ types.odin | 2 ++ 3 files changed, 49 insertions(+), 24 deletions(-) create mode 100644 reader.odin diff --git a/reader.odin b/reader.odin new file mode 100644 index 0000000..ac15ca5 --- /dev/null +++ b/reader.odin @@ -0,0 +1,44 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +package main + +import "core:encoding/csv" +import "core:os" +import "core:strings" + +new_reader :: proc() -> Reader { + return { + comma = '\t', + comment = '#', + fields_per_record = -1, + reuse_record = true, + reuse_record_buffer = true, + } +} + +destroy_reader :: proc(reader: ^Reader) { + csv.reader_destroy(reader) +} + +read_sector :: proc(reader: ^Reader, path: string, systems: map[string]System) -> Error { + data := os.read_entire_file(path, context.allocator) or_return + defer delete(data) + + csv.reader_init_with_string(reader, string(data)) + + for record, _, err in csv.iterator_next(reader) { + if err != nil { + return err + } + + if system := &systems[record[2]]; system != nil { + system.name = strings.clone_to_cstring(record[3]) + } + } + + return nil +} diff --git a/sector.odin b/sector.odin index 6493488..387bb03 100644 --- a/sector.odin +++ b/sector.odin @@ -6,9 +6,7 @@ package main -import "core:encoding/csv" import "core:math" -import "core:os" import "core:path/filepath" import "core:strings" import rl "vendor:raylib" @@ -32,29 +30,10 @@ new_sector :: proc(path: string, origin: Point = {0, 0}) -> (sector: Sector, err } } - reader := csv.Reader { - comma = '\t', - comment = '#', - fields_per_record = -1, - reuse_record = true, - reuse_record_buffer = true, - } - defer csv.reader_destroy(&reader) - - data := os.read_entire_file(path, context.allocator) or_return - defer delete(data) + reader := new_reader() + defer destroy_reader(&reader) - csv.reader_init_with_string(&reader, string(data)) - - for record, _, err in csv.iterator_next(&reader) { - if err != nil { - return sector, err - } - - if system := &systems[record[2]]; system != nil { - system.name = strings.clone_to_cstring(record[3]) - } - } + read_sector(&reader, path, systems) layout := new_layout(flat_orientation(), origin, {HEX_SIZE, HEX_SIZE}) diff --git a/types.odin b/types.odin index 1c90714..52352c7 100644 --- a/types.odin +++ b/types.odin @@ -33,6 +33,8 @@ Orientation :: struct { Point :: rl.Vector2 +Reader :: csv.Reader + Sector :: struct { name: cstring, systems: map[string]System, From 7b0f52ad60a984e394d0aa5148a96397f70460da Mon Sep 17 00:00:00 2001 From: Theomund <34360334+theomund@users.noreply.github.com> Date: Sun, 19 Jul 2026 02:42:19 +0000 Subject: [PATCH 07/10] feat: add debugger tool --- .devcontainer/Dockerfile | 1 + Makefile | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 5031985..6c22e40 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -15,6 +15,7 @@ RUN dnf copr enable -y sisyphus1813/odin-lang \ libXinerama-devel-1.1.5 \ libxkbcommon-devel-1.13.1 \ libXrandr-devel-1.5.4 \ + lldb-22.1.8 \ mesa-libGL-devel-26.1.4 \ odin-lang-2026.07 \ ols-2026.05 \ diff --git a/Makefile b/Makefile index 5fb527e..dc62f15 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ ifneq (,$(wildcard ./.env)) export endif -.PHONY: all build clean coverage format lint run test +.PHONY: all build clean coverage debug format lint run test all: lint test build @@ -21,6 +21,10 @@ coverage: odin build . -build-mode:test -debug kcov --dump-summary --exclude-pattern=_test.odin --include-path=. .kcov spinward +debug: + odin build . -debug + lldb spinward + format: odinfmt . -w From beec0b820d2721b1533d9c43076701e3822522f7 Mon Sep 17 00:00:00 2001 From: Theomund <34360334+theomund@users.noreply.github.com> Date: Sun, 19 Jul 2026 03:16:05 +0000 Subject: [PATCH 08/10] feat: add memory leak detection --- hex.odin | 2 +- main.odin | 7 +++++++ sector.odin | 5 ++++- tracker.odin | 33 +++++++++++++++++++++++++++++++++ types.odin | 7 +++++++ 5 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 tracker.odin diff --git a/hex.odin b/hex.odin index 41a2645..d63b73b 100644 --- a/hex.odin +++ b/hex.odin @@ -19,7 +19,7 @@ new_hex :: proc(q, r, s: f32) -> Hex { hex_index :: proc(hex: Hex) -> string { offset := qoffset_from_cube(hex) - return fmt.tprintf("%02d%02d", i32(offset.x + 1), i32(offset.y + 1)) + return fmt.aprintf("%02d%02d", i32(offset.x + 1), i32(offset.y + 1)) } hex_lerp :: proc(a, b: Hex, t: f32) -> Hex { diff --git a/main.odin b/main.odin index dbd4c47..10f233a 100644 --- a/main.odin +++ b/main.odin @@ -9,6 +9,13 @@ package main import "core:os" main :: proc() { + when ODIN_DEBUG { + tracker := new_tracker() + context = tracker.ctx + + defer delete_tracker(tracker) + } + if err := run(); err != nil { os.exit(1) } diff --git a/sector.odin b/sector.odin index 387bb03..1fd5389 100644 --- a/sector.odin +++ b/sector.odin @@ -58,7 +58,10 @@ contains_hex :: proc(hex: Hex) -> bool { draw_sector :: proc(sector: Sector, camera: rl.Camera2D) { for index, system in sector.systems { - draw_system(sector, strings.clone_to_cstring(index), system) + clone := strings.clone_to_cstring(index) + defer delete(clone) + + draw_system(sector, clone, system) } position := rl.GetScreenToWorld2D(rl.GetMousePosition(), camera) diff --git a/tracker.odin b/tracker.odin new file mode 100644 index 0000000..f496d51 --- /dev/null +++ b/tracker.odin @@ -0,0 +1,33 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +package main + +import "base:runtime" +import "core:fmt" +import "core:mem" + +new_tracker :: proc() -> Tracker { + allocator := new(mem.Tracking_Allocator) + ctx := runtime.default_context() + + mem.tracking_allocator_init(allocator, ctx.allocator) + + ctx.allocator = mem.tracking_allocator(allocator) + + return {allocator, ctx} +} + +delete_tracker :: proc(tracker: Tracker) { + if len(tracker.allocator.allocation_map) > 0 { + fmt.eprintf("=== %v allocations not freed: ===\n", len(tracker.allocator.allocation_map)) + for _, entry in tracker.allocator.allocation_map { + fmt.eprintf("- %v bytes @ %v\n", entry.size, entry.location) + } + } + + mem.tracking_allocator_destroy(tracker.allocator) +} diff --git a/types.odin b/types.odin index 52352c7..361925a 100644 --- a/types.odin +++ b/types.odin @@ -6,7 +6,9 @@ package main +import "base:runtime" import "core:encoding/csv" +import "core:mem" import "core:os" import rl "vendor:raylib" @@ -49,3 +51,8 @@ System :: struct { Spinward_Error :: enum { Initialization_Failed, } + +Tracker :: struct { + allocator: ^mem.Tracking_Allocator, + ctx: runtime.Context, +} From 9a96ce01f330fda98e808b5cb1a3b0201de479e9 Mon Sep 17 00:00:00 2001 From: Theomund <34360334+theomund@users.noreply.github.com> Date: Sun, 19 Jul 2026 03:32:44 +0000 Subject: [PATCH 09/10] fix: address memory leak with hex indexes --- hex_test.odin | 19 +++++++++++++++---- sector.odin | 3 ++- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/hex_test.odin b/hex_test.odin index 273b9e4..228fe58 100644 --- a/hex_test.odin +++ b/hex_test.odin @@ -16,10 +16,21 @@ test_new_hex :: proc(t: ^testing.T) { @(test) test_hex_index :: proc(t: ^testing.T) { - testing.expect_value(t, hex_index(new_hex(0, 0, 0)), "0101") - testing.expect_value(t, hex_index(new_hex(1, 0, -1)), "0201") - testing.expect_value(t, hex_index(new_hex(0, 1, -1)), "0102") - testing.expect_value(t, hex_index(new_hex(1, 1, -2)), "0202") + index := hex_index(new_hex(0, 0, 0)) + testing.expect_value(t, index, "0101") + delete(index) + + index = hex_index(new_hex(1, 0, -1)) + testing.expect_value(t, index, "0201") + delete(index) + + index = hex_index(new_hex(0, 1, -1)) + testing.expect_value(t, index, "0102") + delete(index) + + index = hex_index(new_hex(1, 1, -2)) + testing.expect_value(t, index, "0202") + delete(index) } @(test) diff --git a/sector.odin b/sector.odin index 1fd5389..2f09c10 100644 --- a/sector.odin +++ b/sector.odin @@ -43,7 +43,8 @@ new_sector :: proc(path: string, origin: Point = {0, 0}) -> (sector: Sector, err delete_sector :: proc(sector: Sector) { delete(sector.name) - for _, system in sector.systems { + for index, system in sector.systems { + delete(index) delete_system(system) } From d641f3dd4baeb44c42d8d6554a2a58f54afb7c28 Mon Sep 17 00:00:00 2001 From: Theomund <34360334+theomund@users.noreply.github.com> Date: Sun, 19 Jul 2026 04:13:02 +0000 Subject: [PATCH 10/10] feat: parse and display sector allegiance --- reader.odin | 1 + sector.odin | 6 +++++- system.odin | 25 +++++++++++++++++++++++-- types.odin | 5 +++-- 4 files changed, 32 insertions(+), 5 deletions(-) diff --git a/reader.odin b/reader.odin index ac15ca5..bc98ab5 100644 --- a/reader.odin +++ b/reader.odin @@ -36,6 +36,7 @@ read_sector :: proc(reader: ^Reader, path: string, systems: map[string]System) - } if system := &systems[record[2]]; system != nil { + system.allegiance = strings.clone_to_cstring(record[9]) system.name = strings.clone_to_cstring(record[3]) } } diff --git a/sector.odin b/sector.odin index 2f09c10..651d9ea 100644 --- a/sector.odin +++ b/sector.odin @@ -65,10 +65,14 @@ draw_sector :: proc(sector: Sector, camera: rl.Camera2D) { draw_system(sector, clone, system) } + for _, system in sector.systems { + draw_border(sector, system) + } + position := rl.GetScreenToWorld2D(rl.GetMousePosition(), camera) hovered := pixel_to_hex_rounded(sector.layout, position) if contains_hex(hovered) { - draw_hex(sector.layout, hovered, rl.RED) + draw_hex(sector.layout, hovered, rl.YELLOW) } } diff --git a/system.odin b/system.odin index 5424b06..8671bc4 100644 --- a/system.odin +++ b/system.odin @@ -8,14 +8,35 @@ package main import rl "vendor:raylib" -new_system :: proc(hex: Hex, name: cstring = "") -> System { - return {name, hex} +new_system :: proc(hex: Hex) -> System { + return {hex = hex} } delete_system :: proc(system: System) { if system.name != "" { delete(system.name) } + + if system.allegiance != "" { + delete(system.allegiance) + } +} + +draw_border :: proc(sector: Sector, system: System) { + color: rl.Color + + switch system.allegiance { + case "DaCf": + color = rl.WHITE + case "ImDd": + color = rl.RED + case "SwCf": + color = rl.DARKBLUE + case "ZhIN": + color = rl.BLUE + } + + draw_hex(sector.layout, system.hex, color) } draw_system :: proc(sector: Sector, index: cstring, system: System) { diff --git a/types.odin b/types.odin index 361925a..eecbc6b 100644 --- a/types.odin +++ b/types.odin @@ -44,8 +44,9 @@ Sector :: struct { } System :: struct { - name: cstring, - hex: Hex, + name: cstring, + allegiance: cstring, + hex: Hex, } Spinward_Error :: enum {