Jump to content
simmaster07

Scion, a WIP implementation of the Maxis Gonzo-Rizzo engine

19 posts in this topic Last Reply

Highlighted Posts

Posted:
Last Online:  
 

Nice to see Scion getting further progress.

I see that Scion contains several things that would be useful for gzcom-dll and sc3k-gzcom-dll (e.g. cRZRandom, cRZDate, cRZTime). But the LGPL restriction on Scion prevents those items from being ported over to the other two MIT-licensed projects. I am also skeptical that it would be easy to re-license gzcom-dll as LGPL, due to needing agreement from all 4 contributors.

If you need a cGZPersistDBSegmentMultiPackedFiles implementation, my Startup Performance Optimization DLL has one as BaseMultiPackedFile. That file is a base class for multi-packed file classes that handle both .DAT and .SC4* files, so it has a few features that are not necessary for handling just DAT files.

I have been slowly re-implementing some of the STLPORT classes in gzcom-dll, currently I have SC4Vector implemented. I went with re-implementing because I was never able to get STLPORT 4.5.3 to work under MSVC 2022.

I remember seeing an explanation by Don Hopkins on the relationship between Gonzo and Rizzo, but I can't find a link for that.

There was a discussion on the ST discord about how Maxis shipped debug symbols for the main executable in some CD versions of SC3K, it is a shame they didn't make that mistake with SC4.

  • Like 8

Share this post


Link to post
Share on other sites
  • Original Poster
  • Posted:
    Last Online:  
     
    14 minutes ago, Null 45 said:

    I see that Scion contains several things that would be useful for gzcom-dll and sc3k-gzcom-dll (e.g. cRZRandom, cRZDate, cRZTime). But the LGPL restriction on Scion prevents those items from being ported over to the other two MIT-licensed projects.

    Fair point - from a licensing perspective it'd be fine to vendor those classes separately and link them with the MIT code, but for simplicity's sake I'll probably just relicense Scion to MIT when I get home tonight. I'll also have to check out the BaseMultiPackedFile implementation, that should be a big help for wrapping up the GZResourceD implementation.

    24 minutes ago, Null 45 said:

    There was a discussion on the ST discord about how Maxis shipped debug symbols for the main executable in some CD versions of SC3K, it is a shame they didn't make that mistake with SC4.

    Thankfully Aspyr at least included retail symbols for SC4 and TS2 in their Mac ports, and a lot of the stuff that isn't platform specific is reused between those two games and SC3K, so the work is still doable, just takes additional time to correlate those symbols with the Windows ship builds. Might be worth setting up a Ghidra server at some point for that.

    • Like 6

    Share this post


    Link to post
    Share on other sites
    Posted:
    Last Online:  
     
    15 minutes ago, simmaster07 said:

    from a licensing perspective it'd be fine to vendor those classes separately and link them with the MIT code, but for simplicity's sake I'll probably just relicense Scion to MIT when I get home tonight.

    That is probably the easy way, although I wouldn't have a problem with gzcom-dll and sc3k-gzcom-dll being re-licensed to LGPL.

    The community would typically release any SC4 DLLs as open-source, but the LGPL license enforces it. I made my graphics options DLL LGPL due to needing some SCGL headers, and I have slowly been changing over to LGPL for my DLLs.

    15 minutes ago, simmaster07 said:

    I'll also have to check out the BaseMultiPackedFile implementation, that should be a big help for wrapping up the GZResourceD implementation.

    I will be checking out your cGZDBSegmentPackedFile implementation. I had considered re-implementing that for my Startup Performance Optimization DLL, but it was a massive amount of work.

    The main reason for me to have a cGZDBSegmentPackedFile re-implementation would be to see if I can squeeze more performance out of the resource loading code. Although my experiments with multi-threading the plugin loading were disappointing, I had to bypass GZCOM when creating cGZDBSegmentPackedFile instances just to break even with the single-threaded code.

    • Like 6

    Share this post


    Link to post
    Share on other sites
  • Original Poster
  • Posted:
    Last Online:  
     

    re: gzcom-dll, I think you and I are the two main contributors on that project, and one contributor was making an automated fix to a solution file, so as long as @memo is okay with relicensing to LGPL to enforce source code sharing then we should be fine.

    • Like 6

    Share this post


    Link to post
    Share on other sites
    Posted:
    Last Online:  
     

    What version(s) of the LGPL are you allowing for projects derived from SCGL, Scion, and gzcom-dll?

    SCGL doesn't have a LGPL header in any files I looked at, and the readme doesn't say that LGPL versions after 2.1 are allowed. Scion's files also appear to be LGPL 2.1 only, the LGPL 2.1 text allowing derived projects to use a later version was removed.

    The apparent lack of support for derived projects using newer LGPL versions would be a problem for gzcom-dll, as NAM-dll and many of my DLLs use LGPL 3.0.

    • Like 3

    Share this post


    Link to post
    Share on other sites
  • Original Poster
  • Posted:
    Last Online:  
     
    3 hours ago, Null 45 said:

    SCGL doesn't have a LGPL header in any files I looked at, and the readme doesn't say that LGPL versions after 2.1 are allowed. Scion's files also appear to be LGPL 2.1 only, the LGPL 2.1 text allowing derived projects to use a later version was removed.

    That's my bad, I was aiming for LGPL-2.1 to be more permissive (e.g. allowing GPLv2 projects to use it), but I didn't mean to restrict the use of LGPL-3.0. I just pushed a couple of commits to SCGL and Scion to relicense as LGPL-2.1-or-later (and add the notice headers to SCGL), and if I were going to relicense gzcom-dll, it would also be under LGPL-2.1-or-later.

    • Like 4

    Share this post


    Link to post
    Share on other sites
    Posted:
    Last Online:  
     

    Hi, nice to see you working again for this project! Although I have done some fixups to SC3U exe based what I found in embedded debug info (I surprised why they did it), and did some unfinished boilerplate code of interfaces targets for VC6 SP3 (for build 949 Unlimited, some later UK edition with slightly newer build 966 is using VC6 SP4). At that time, I decided to create from scratch rather use scion as base because what I found is SC3U & SC4 have some differences how base app framework were created, and so on. Unfortunately I didn't have much time for now as still busy for ongoing thesis. However I would like to contribute to scion instead if I have spare time later.

    Some tidbits:

    • SC3U debug info were only on on main exe, but it still contains valuable since it provides more detailed how Maxis create functions like arguments name, enums, structs and interfaces from external modules. Most Internet functions that isn't essential still lives there, and still ping to EA's SimCity.com when idle (didn't figure yet how disable this elegantly, there's also lot undocumented ini options for this internet feature).
    • SC3K and SC3U apperently didn't use STLPort or MSVC standard STL, but instead use SGI STL v3.13 (they may not update this more often because it was integrated on rizzo framework base on debug info). Loki port build is use SGI STL too instead of GCC stdc++ and this why Linux build is bigger because of how GCC aggresively inlined most of STL functions.
    • The Sims 1 actually have leaked custom build with Edith development tool, it has release & unoptimzed debug build with MSVC assertions & fraction of RTTI. Sadly both didn't include PDB.
    • While SC4 Rush Hour EP built with MSVC 2003, older SC4 base game up to build 272 apparently built on VC6 SP4 or SP5 with older Lua 4.x. This may affects decompilation as VC 2003 allegedly have more optimized code generation than VC6.
    • To reduce guessing function names, you can use Ghidra Function ID feature. That's work by: compiling known library source code with exact version (e.g Lua 5.0) to the exact same compiler that exe game used to decompile (e.g SC4 Rush Hour is using MSVC 2003 RTM without SP) as static library, then create Ghidra new project, import lib to extracts OBJs. Open all OBJs by select .lib file, then select batch, make sure you set language to `x86:LE:32:default:windows` (sometimes Ghidra misrepresenting as gcc), make sure check both "strip leading path" & "strip container path". Open all objs by selecting all obj, right click -> open with -> code browser. Don't analyze now, instead select No, then go to menu Analysis -> Analyze all open. Then use build FID as usual I not mentioned here but there's much basic tutorial to build Ghidra FID. You can do this for MSVC 2003 libraries like libcmt.lib an others as SC4 is built CRT staticaly & Ghidra built in MSVC FIDB is quite bad. Attached file for example to detect Lua 5.0 function in latest SC4. Not perfect (some not recognized) but still time saver.

    Screenshot_20250601_115016.jpg

    Screenshot_20250601_103328.jpg

    • Like 7

    Share this post


    Link to post
    Share on other sites
    Posted:
    Last Online:  
     
    15 hours ago, simmaster07 said:

    so as long as @memo is okay with relicensing to LGPL to enforce source code sharing then we should be fine.

    Yes, I'm definitely okay with that. I've been using LGPL for all my DLLs as well.

    • Like 8

    Share this post


    Link to post
    Share on other sites
    Posted:
    Last Online:  
     
    16 hours ago, thiekus said:

    To reduce guessing function names, you can use Ghidra Function ID feature.

    That is a good suggestion. I added the MSVC 2003 function id data to my SimCity 4 Ghidra symbol repository.

    I don't have a MSVC 2003 build environment configured, that seems like a lot of work to set up. I would find a FID database for STLPORT to be more useful than the low-level Lua code, but there is no way of knowing what STLPORT version Maxis used.

    • Like 5

    Share this post


    Link to post
    Share on other sites
    Posted:
    Last Online:  
     
    2 hours ago, Null 45 said:

    That is a good suggestion. I added the MSVC 2003 function id data to my SimCity 4 Ghidra symbol repository.

    I don't have a MSVC 2003 build environment configured, that seems like a lot of work to set up. I would find a FID database for STLPORT to be more useful than the low-level Lua code, but there is no way of knowing what STLPORT version Maxis used.

    You don't need whole Visual Studio 2003 IDE to install, which is pain to install and use even in Windows 7 in my experience, as turn out there's weird issue with DWM enabled. But the good news is, Microsoft at one point give VC 2003 compiler tools only as freeware as Visual C++ Toolkit 2003 and some basic libraries (AFAIK, you need another platform SDK for Windows 2003 to use WinAPI headers & libraries). There's 2 version, v1.00 (build 3052) and v1.01 (build 3077 same as VC 2003 RTM) which according to Microsoft Q&A here is doesn't matter (but v1.01 is preferable to ensure match the VC 2003 RTM). There's someone who posting both version (v1.01 is signed with newer June 2004), take for risk consideration as Microsoft have remove original download link for long time ago. Here's comparison between my VC 2003 RTM and VC 2003 Toolkit 2003 v1.01 on my WinXP VM.

    Screenshot_20250602_071658.png

    • Like 3

    Share this post


    Link to post
    Share on other sites
    Posted:
    Last Online:  
     
    38 minutes ago, thiekus said:

    There's 2 version, v1.00 (build 3052) and v1.01 (build 3077 same as VC 2003 RTM) which according to Microsoft Q&A here is doesn't matter (but v1.01 is preferable to ensure match the VC 2003 RTM).

    Good to know. I tried to check the compiler versions, but I didn't see that 3052 was different from the VC2003 RTM. So I will be rebuilding my FID database.

    I don't need the full IDE, I just want a working CLI environment that can build make files. Sadly the Visual C++ Toolkit 2003 doesn't include that functionality. If I had VC2003 with nmake, that would allow me to compile Lua 5.0, various STLPORT versions, and possibly the graphics libraries. Although the strings in the Windows binary hint that GIMEX was built with MSVC 6.0 using some Intel compiler, for whatever reason the compiler command stings are in the v641 executable.

    Feel free to submit PRs to that repository with more function id databases. *:)

    • Like 3

    Share this post


    Link to post
    Share on other sites
    Posted:
    Last Online:  
     
    1 hour ago, Null 45 said:

    I don't need the full IDE, I just want a working CLI environment that can build make files. Sadly the Visual C++ Toolkit 2003 doesn't include that functionality. If I had VC2003 with nmake, that would allow me to compile Lua 5.0, various STLPORT versions, and possibly the graphics libraries. Although the strings in the Windows binary hint that GIMEX was built with MSVC 6.0 using some Intel compiler, for whatever reason the compiler command stings are in the v641 executable.

    VC Toolkit is barebone cli compiler with minimal CRT library, so as I said before, you need Platform SDK for complete toolchain like nmake, etc. I was able to reproduce STLPort 4.6 that detected in SC4 build 641 using VC Toolkit v1.01 and Windows Platform SDK 2003 SP1(from same link I mentioned before) since compiling STLPort only need nmake.

    First, you need open "Windows Server 2003 32-bit Build Environment" from PSDK 2003 start menu (XP 32bit may works too although not tested yet). Then apply VC Toolkit 2003 env by copying absolute vcvars32.bat to command window.

    For 32 bit Windows

    "C:\Program Files\Microsoft Visual C++ Toolkit 2003\vcvars32.bat"

    For 64 bit Windows (not tested yet)

    C:\Program Files (x86)\Microsoft Visual C++ Toolkit 2003\vcvars32.bat

    And test by cl /?, make sure you execute the right compiler. If not, probably you need check vcvars32.bat environments in VC Toolkit directory is correct. Build static build stlport with nmake -f vc7.mak as usual. It works on STLPort 4.6 but didn't in older 4.5.x.

    Forgot to mention, you should not check at analysis options when analyze Function ID when building own FID. Also sometime Ghidra has annoying bug that makes Function ID is missing from analysis options, just close and open new instance of Ghidra should solve this problem. I need check further if this is correct fidb and STLPort version.

    Screenshot_20250602_094006.jpg

    vctoolkit2.jpg

    • Like 3

    Share this post


    Link to post
    Share on other sites
  • Original Poster
  • Posted:
    Last Online:  
     
    9 hours ago, Null 45 said:

    I would find a FID database for STLPORT to be more useful than the low-level Lua code, but there is no way of knowing what STLPORT version Maxis used.

     

    On 5/31/2025 at 10:00 PM, thiekus said:

    SC3K and SC3U apperently didn't use STLPort or MSVC standard STL, but instead use SGI STL v3.13 (they may not update this more often because it was integrated on rizzo framework base on debug info).

    Worth noting that STLport is a fork of SGI STL that worked on making it portable to different platforms, and doing general maintenance when SGI stopped maintaining their library. MSVC was also unreliable at the time since the string class in VC6 had bad bugs like corrupting memory when multi-threading and being slow at string assignment (Paul Pedriana called this out in his GDC talk).

    My best guess is that SC4 Deluxe uses a pre-release version of STLport 4.6, but I also don't think the changes since 4.5.1 or 4.5.3 were major enough to really break function ID. I opened a PR to add FID databases for STLport 4.6 and Lua 5.0, built with Visual C++ 2003, and I get pretty solid coverage on SC4.exe v641 from that. Unfortunately a lot of the STL template types are both inlined and only generated at compile time with those types, which was necessary for performance but makes the FIDBs fairly limited.

    I'm also looking at getting FIDBs set up for libpng and zlib, but I suspect those were built with a different compiler than the game was using, because the function prologues are a lot less optimized than VC6 or VC7, and I can't find a combination of compiler flags that reproduces that. (For example, libpng functions always copy registers edi, esi and ebx to the stack and preserve them, even if those registers aren't used by that function.)

    • Like 3

    Share this post


    Link to post
    Share on other sites
    Posted:
    Last Online:  
     
    24 minutes ago, simmaster07 said:

    I'm also looking at getting FIDBs set up for libpng and zlib, but I suspect those were built with a different compiler than the game was using, because the function prologues are a lot less optimized than VC6 or VC7, and I can't find a combination of compiler flags that reproduces that. (For example, libpng functions always copy registers edi, esi and ebx to the stack and preserve them, even if those registers aren't used by that function.)

    The GIMEX compiler info is present as strings in the GOG binary, Intel(R) C++ Compiler for 32-bit applications, Version 6.0   Build 020321Z. I found Intel's product page on the Internet Archive, but I haven't had any luck tracking down the compiler binaries.

    • Like 4

    Share this post


    Link to post
    Share on other sites
    Posted:
    Last Online:  
     
    2 hours ago, simmaster07 said:

    Worth noting that STLport is a fork of SGI STL that worked on making it portable to different platforms, and doing general maintenance when SGI stopped maintaining their library. MSVC was also unreliable at the time since the string class in VC6 had bad bugs like corrupting memory when multi-threading and being slow at string assignment (Paul Pedriana called this out in his GDC talk).

    My best guess is that SC4 Deluxe uses a pre-release version of STLport 4.6, but I also don't think the changes since 4.5.1 or 4.5.3 were major enough to really break function ID. I opened a PR to add FID databases for STLport 4.6 and Lua 5.0, built with Visual C++ 2003, and I get pretty solid coverage on SC4.exe v641 from that. Unfortunately a lot of the STL template types are both inlined and only generated at compile time with those types, which was necessary for performance but makes the FIDBs fairly limited.

    Makes sense since from the SGI STL FAQ, it's header only library implementation, and while STLPort fork is evolved to their own, may still have traces from old SGI STL. Before I caught SC3U debug info, I've tried to create stub program that purposely calls to any STL functions I can call compiles with VC6, then put resulted OBJ to Ghidra and generate FID from there. It got some functions detected but I stopped doing that for SC3U immediately after I found exe debug info. Attached code is my crude attempt to generate sc3u STL signatures.

    I agree that VC6 is notoriously joke that even defying the C++ standards that should be correct.

    1 hour ago, Null 45 said:

    The GIMEX compiler info is present as strings in the GOG binary, Intel(R) C++ Compiler for 32-bit applications, Version 6.0   Build 020321Z. I found Intel's product page on the Internet Archive, but I haven't had any luck tracking down the compiler binaries.

    I looked at Internet Archive and found interesting "Intel® Software Development Products Evaluation CD" dated from 2002. It contains 30-days of various Intel development tool products including Intel C++ Compiler 6.0. I didn't try to install yet but after I extracted icl.exe, it use the same version & revision that used in SC4 compiler option strings. Look promising. Edit: it requires valid FlexLM license after I install and need explicitly request trial to Intel, the request link from the CD isn't work anymore.

    Some part of Gimex source code likely published as well on CnC Generals source code.

    stlimpl.cpp

    Screenshot_20250602_152641.png

    • Like 5

    Share this post


    Link to post
    Share on other sites
    Posted:
    Last Online:  
     
    15 hours ago, thiekus said:

    Some part of Gimex source code likely published as well on CnC Generals source code.

    I added a Gimex archive to my repository based on gimex.h, that file (version 3.46) is almost identical to what SC4 used (version 3.45). Interestingly, the CnC Generals source code contains two version of Gimex, the auto-run code has a much older version (2.26). I already had some of the low-level Gimex stuff decoded, but it is extremely helpful to have the original structures. 

    • Like 5

    Share this post


    Link to post
    Share on other sites
    Posted:
    Last Online:  
     

    I was able to past from license check and compile libpng and zlib using that same Intel C++ Compiler. You really need VC6 or VC 2002 to really use this version of ICC, it wouldn't integrate to any newer VS. I've did PR for this FIDB.

    I'd tried to build IJG libjpeg 6b database and only detects very few jpeg functions. Turns out it's use Intel Jpeg Library (IJL) statically which nowhere to found (DLL versions is more common, it used by The Sims 1). So I'm not put them on PR, but attached is built jpeg 6b static lib for reference. Edit: seems SC4 actually load IJL dynamically at 0x00a0ee50.

    libjpeg.lib

    • Like 5

    Share this post


    Link to post
    Share on other sites
    Posted:
    Last Online:  
     

    I have idea to move mangled symbols from Aspyr SC4 Mac to SC4 Windows (probably) more faster. As turns out, Ghidra understands compiler Map (*.map files) besides to other debug info formats like PDB. AFAIK, map files usually generates from compilers like older versions of Visual C++ and Borland compilers (C++ and Delphi). Unlike PDB, Map files is plain text, so it's easy to create and edit. Ghidra usually didn't allow to demangle GCC mangled names if you input Visual C++ exe, but there's trick:

    • Prepare attached crafted mapfile, save as .map extension. It's simple format so no need more explanations.
    • Import new "SimCity 4.exe" as usual. Did auto analysis as usual.
    • After analysis finished, select menu File -> Add to Program.
    • Select the crafted map info. If that valid map file, format will be "Program Mapfile (MAP)", otherwise mapfile format is wrong.
    • If succeed, defined function will be renamed as GCC mangled name as defined in mapfile.
    • To able use GCC demangler, you need temporarily change compiler spec by select menu Edit -> Options for 'SimCity 4.exe'. Then select "Program Information". From there, change Compiler from "visualstudio:unknown" to "gcc:unknown". Click Ok to proceed.
    • Save and close active CodeBrowser, then open it again. In analysis options, you now have "Demangler GNU" that not available before.
    • Do demangler analysis only by menu Analysis -> One Shot -> Demangler GNU. Now you don't waste time to manually edit many functions, demangler will did the job :D
    • After done, change back compiler spec back to original "visualstudio:unknown". Save and close CodeBrowser, then open again.

    Every you have new symbol entries, you just load map file again. You only need change compiler spec when you need demangle them all at once. There's small caveat, every you reload map file after demangle process, demangled static data/variable symbols will be renamed to mangled name back (demangled functions isn't affected). I don't see anyone did this tricks before (or did exists but I don't know yet), and it would be more ideal if mangled GCC names can be converted to MSVC mangled name. I didn't see another side effects but take this tricks at your risk.

    Here my sample mapfile for SC4 build 641

      Address         Publics by Value
    
     ;
     ; Formats are:
     ; <section:RVA> <symbol name> <absolute address>
     ; 
     ; Ghidra only cares 2nd and 3rd parameters (absolute address), it don't care about RVA in 1st param.
     ; Name and origin address comes from SC4 Rush Hour Mac universal binary x86 beta.
     ; Comments are using semicolon prefix, that entries can't be have blank lines (Ghira will skipped it).
     ;
     ; [0x00008302] SC4AppStart(cRZCmdLine const&, bool)
     0000:00000000       __Z11SC4AppStartRK10cRZCmdLineb 0044c170
     ; [0x0002456c] SC4DisplayResourceError
     0000:00000000       __Z23SC4DisplayResourceErrorm 005f8d40
     ;
     ; [0x00ab71e8] cGZFramework::mpFrameWork
     0000:00000000       __ZN12cGZFramework11mpFrameWorkE 00b540ac
     ; [0x00ab71e0] cGZFramework::mpApp
     0000:00000000       __ZN12cGZFramework5mpAppE 00b540b4
     ; [0x00ab71ec] cGZFramework::mnReturnCode
     0000:00000000      __ZN12cGZFramework12mnReturnCodeE 00b540a8
     ;
     ; [0x0001cc0c] cGZFramework::Main(cRZCmdLine const&, bool)
     0000:00000000       __ZN12cGZFramework4MainERK10cRZCmdLineb 0087b0b9
     ; [0x0001c81c] cGZFramework::sInit(cRZCmdLine const&, bool)
     0000:00000000       __ZN12cGZFramework5sInitERK10cRZCmdLineb 0087af13
     ; [0x0001a67c] cGZFramework::sRun()
     0000:00000000       __ZN12cGZFramework4sRunEv 0087957a
     ; [0x0001cbf8] cGZFramework::sShutdown()
     0000:00000000       __ZN12cGZFramework9sShutdownEv 0087ab07
     ; [0x0001a448] cGZFramework::sSetApplication(cIGZApp*)
     0000:00000000       __ZN12cGZFramework15sSetApplicationEP7cIGZApp 008793dd
     ; [0x0001a41e] cGZFramework::sSetFrameWork(cGZFramework*)
     0000:00000000       __ZN12cGZFramework13sSetFrameWorkEPS_ 008793bd
     ; [0x0001c7aa] cGZFramework::HookPreFrameWorkInit()
     0000:00000000       __ZN12cGZFramework20HookPreFrameWorkInitEv 0087a286
     ; [0x0001c738] cGZFramework::HookPreAppInit()
     0000:00000000       __ZN12cGZFramework14HookPreAppInitEv 0087a2d6
     ; [0x0001c6c6] cGZFramework::HookPostAppInit()
     0000:00000000       __ZN12cGZFramework15HookPostAppInitEv 0087a326
     ;
     ; [0x00007ba4] cSC4App::cSC4App(char const*)
     0000:00000000       __ZN7cSC4AppC1EPKc 0044acd0
     ;
     ; [0x0001120c] cRZAppCmdLine::FixCommandLine(cIGZCmdLine&, cIGZString const*)
     0000:00000000       __ZN13cRZAppCmdLine14FixCommandLineER11cIGZCmdLinePK10cIGZString 0091479d
     

     

    • Like 5

    Share this post


    Link to post
    Share on other sites

    Sign In or register to comment...

    To comment in reply, you must be a community member

    Sign In  

    Already have an account? Sign in here.

    Sign In Now

    Create an Account  

    Sign up to join our friendly community. It's easy!  

    Register a New Account


    ×

    Thank You for the Continued Support!

    Simtropolis depends on donations to fund site maintenance costs.
    Without your support, we just would not be in our 24th year online!  You really help make this a great community. *:thumb:

    But we still need your support to stay online. If you're able to, please consider a donation to help us stay up and running. This helps sustain a platform where we can share our community creations for years to come.

    Make a Donation, Get a Gift!

    Expand your city with the best from the Simtropolis Exchange.
    Make a Donation and get one or all three discs today!

    STEX Collections

    By way of a "Thank You" gift, we'd like to send you our STEX Collector's DVD. It's some of the best buildings, lots, maps and mods collected for you over the years. Check out the STEX Collections for more info.

    Each donation helps keep Simtropolis online, open and free!

    Thank you for reading and enjoy the site!

    More About STEX Collections