Project Categories
Project Setting | Personal |
Team Size | 1 |
Role(s) | Creator / Developer |
Languages | C# |
Software/Tools Used | Unity (engine), Visual Studio (code), git (version control), Blender (modeling), Inkscape (UI) |
Status | Public demo, active development |
Time Period | July 2020 - Current |
About
Moon Settler (codenamed SFBuilder) is a sci-fi puzzle / city-building hybrid. The player is given 'goals' to complete, which contain a set of required and optional buildings as well as a minimum viability requirement. Viability is the sum of three settlement stats that must be kept above 0 in order to move on: happiness, power, and sustenance. Buildings placed by the player may have a base score that adds or subtracts to those stats. Buildings can also affect others in range in the same way, making building placement strategy and planning ahead important.
Description from the public demo repository
Moon Settler started with the intention of creating a short term project within a month. I set weekly milestones (each Thursday) where I hoped to have certain planned features ready each Thursday. Multiple versions (typically 2-3) were made between each overall weekly milestone to mark a new set of changes or features. I was always either on time or a day early when meeting these milestones. I started the project June 30th and released the first official public demo on August 5th. Since then I have maintained active development of the project to add more features, and will soon fork the public repository to one intended for the full game.
Moon Settler's demo is FOSS. Some components come from a separate FOSS repository, gw-std-unity, such as the tooltip and camera systems. More information about the game itself can be found in the links included in Places.
My Work
Gameplay
- Setup scene structure and level state system for smooth level transitions
- Create goal-based leveling system which is based off of a simple-to-learn scoring mechanic
- Scoring system with the name 'viability' which is based off of three values: happiness, power, and sustenance
- Trigger-based placement system which reports potential scores based off nearby structures and sets score once the structure is placed
UX/UI
- Keyboard/Gamepad navigable, legible menus following several guidelines defined at Game Accessibility Guidelines and Accessible Games
- System to apply color palettes to game HUD at scene-level to ensure each level stands alone as much as possible
- Ensure as much information as possible is presented in multiple ways (e.g. bonuses/penalties are displayed with both +/- symbols and color; placement states indicated by both sound cues and HUD changes/transitions)
- Fully rebindable controls with a variety of options related to input
Modeling
- Model-sets which each use a specific color palette
- Utilize a single, 32x32 resolution pixel atlas and material for all models, creating a textureless color-based aesthetic
- Ensure models maintain a moderately low-poly aesthetic and are as optimized as possible (reducing poly-count by carefully doing multiple passes to find things such as unnecessary edges)
Other
- Custom trance/electro soundtrack with a focus on positive energy or chill vibes to compliment the game
- Custom sound effects for UI, user actions, etc.
- Various flat, high quality sprites for UI
Samples
These are some samples from the project.
Videos
Early prototype video, testing the core mechanics of the game, originally posted on Twitter
Official video of the first build of Moon Settler, outlining the core concepts and other mechanics behind the game
Screenshots

Screenshots taken during the modeling phase, originally posted on Twitter

Testing environmental 'structures': objects that exist from the very beginning of a settlement which can have effects on placement (originally posted on Twitter)

Testing the banishment window (resets settlement) and settlement (level) progression window (originally posted on Twitter: Link 1, Link 2)

Demonstrating some of the various accessibility and UI settings, in this case the UI scaling and font style, originally posted on Twitter
Code
Calculate
is called when a BuilderObject
calls the BuilderObjectRanger
's OnTriggerEnter
/OnTriggerExit
. This holds the core game mechanic: where all structures the player places in the scene (as well as pre-existing environmental objects) have an affect on one another in terms of the player's score. Calculate
iterates through BuilderObject
s in the BuilderObjectRanger
's range and calls the static method BuilderObject.ScoreOfTwoTypes
comparing the BuilderObjectRanger
's parent BuilderObject
and the one being iterated. The previous score is compared with the calculated, and the delta is sent to the GameEventSystem to update the game scoring and UI.
/// <summary>
/// Calculates the resulting score based on the BuilderObject's position and others within the BuilderObject's ranger
/// </summary>
private void Calculate()
{
int prevHappiness = placedHappiness;
int prevPower = placedPower;
int prevSustenance = placedSustenance;
placedHappiness = objectHappiness;
placedPower = objectPower;
placedSustenance = objectSustenance;
foreach (BuilderObject po in othersCollided)
{
BuilderObject.ScoreOfTwoTypes(parent.Type, po.Type, out int workingHappiness, out int workingPower, out int workingSustenance);
placedHappiness += workingHappiness;
placedPower += workingPower;
placedSustenance += workingSustenance;
}
int deltaHappiness = placedHappiness - prevHappiness;
int deltaPower = placedPower - prevPower;
int deltaSustenance = placedSustenance - prevSustenance;
if (deltaHappiness != 0)
GameEventSystem.Instance.UpdateScoreSystem(ScoreType.PotentialHappiness, deltaHappiness);
if (deltaPower != 0)
GameEventSystem.Instance.UpdateScoreSystem(ScoreType.PotentialPower, deltaPower);
if (deltaSustenance != 0)
GameEventSystem.Instance.UpdateScoreSystem(ScoreType.PotentialSustenance, deltaSustenance);
}
Almost all text elements in the game are deemed StyleableText
, which is a way to make text in the game more accessible by applying fonts and scaling to the text element. This process utilizes System.Linq
to find the appropriate font and material assets defined in UIAssets
based on the current setting.
/// <summary>
/// Handle GameEventSystem.SettingsUpdated by applying font settings
/// </summary>
private void OnSettingsUpdated()
{
if (text == null)
text = GetComponent<TMP_Text>();
text.font = UIAssets.Instance
.Fonts.First(f => f.style == GameSettings.Instance.Settings.accessibility_FontStyle).font;
text.fontSharedMaterial = UIAssets.Instance
.Fonts.First(f => f.style == GameSettings.Instance.Settings.accessibility_FontStyle)
.presets.First(m => m.type == type).material;
text.fontSize = GameConstants.UIScaleToFloat(GameSettings.Instance.Settings.accessibility_UIScale, format);
if (format == FontFormat.Tooltip)
{
TooltipPrefab tooltip = GetComponentInParent<TooltipPrefab>();
if (tooltip != null)
tooltip.ApplyTextSettings();
}
}
Places
Home Page | Goldenwere |
Itch.io | Demo Page |
IndieDB | Game Page |
Source Code | GitHub Repo |