Coder Social home page Coder Social logo

onallfronts-public's Introduction

On All Fronts

Latest Demo

Check out our latest updates on our YouTube: https://www.youtube.com/@haywireinteractive/videos

What is this?

On All Fronts is a tactical shooter and strategy FPS / RTS game developed with Unreal Engine 5, leveraging the new Mass Entity (ECS) framework to have a very large number of entities not seen in traditional FPS games (tens or hundreds of thousands). Think Squad meets Foxhole meets PlanetSide 2 mixed in with massive number of AI controlled soldiers.

Note that the project has transitioned to closed source so we could use paid assets, but this open source repo will stay around to help others learn the Mass Entity system which is not very well-documented/supported yet.

Join our Discord Server here.

Motivation

In today's MilSim games players frequently end up doing things or seeing things that would not happen in an actual MilSim. Examples:

  • Soldiers magically spawn onto the battlefield
  • Areas of interest are captured by standing near them
  • Areas that should be defended have little or no one defending them (because it's boring)
  • Soldiers being revived who should be dead
  • Soldiers being healed much faster than they should be able to

On All Fronts aims to eliminate these unrealistic occurrences while keeping the game fun. It mainly does this by leveraging AI to do the not-so-fun stuff such as:

  • Moving soldiers to the frontlines
  • Defending all areas of interest, even those with little activity
  • Logistics
  • Vehicle repairs
  • Medical evacuation (medevac)

Human players will never spawn soldiers onto the battlefield. Instead they will possess an AI-controller soldier already on the battlefield. Each match will last until all soldiers of one team are dead or main objectives have been accomplished.

Roadmap

The project is broken into multiple phases. For current status, see Project Tracker.

Phase 1: Demo

  • Single player: One human player and thousands of AI soldiers (no vehicles)
  • Epic's City Sample map

Phase 2: Early Access

  • Multiplayer FPS game with per-server battles
  • Human and AI soldiers only (no vehicles)
  • Epic's City Sample map

Phase 3: Release

  • Ground vehicles
  • Commander assets (e.g. artillery)
  • More maps

Phase 4: Multiplayer MMO

All players in the game will be in a single battle at a time, across multiple servers.

This phase is split into two sub-phases below.

Phase 4A: Server switching between zones

The map will be split up into zones. When a player reaches the border between zones, they load into a different server that manages that area of the map.

Phase 4B: Server meshing across zones

Seamless switching between servers and players at the borders of servers will talk to all nearby servers to have a seamless experience across zones.

End Game

The ultimate goal is to recreate a war at a scale such as in this video (with the teams a bit more balanced): https://youtu.be/RSqKx3FG0Lw

Possible Features

These ideas below would be explored in one of the phases above.

  1. Railroad system for logistics. Railroads can be damaged and repaired.
  2. Oil pipelines for transfering oil to vehicles quicker.
  3. Base building (FOBs and COPs)
  4. Pontoon bridges which can be built for river crossings. Bridges can be destroyed.
  5. Building destruction
  6. Naval warfare
  7. Helicopters
  8. Airplanes (not player controlled initially, only AI)

FAQ

Development Environment Setup

Prerequisites

  1. Install Git. Two recommended options:
    1. For Git beginners, GitHub Desktop is recommended.
    2. For more advanced users, Git for Windows is recommended. Use the default options in installer.
  2. Install Unreal Engine 5.0.3 from Epic Games Launcher.
  3. Install Visual Studio 2022.
    1. Follow steps here for which options to choose when installing.

    2. In Visual Studio Installer make sure to select a .NET Framework SDK version, at least 4.6. image

    3. If you don't have it installed, install latest .NET Core 3.1: https://dotnet.microsoft.com/en-us/download/dotnet?cid=getdotnetcore

  4. If you plan to modify C++/C# code: Launch Visual Studio > Tools > Options
    1. Text Editor > C/C++ > Tabs > select "Keep tabs"
    2. Text Editor > C# > Tabs > select "Keep tabs"
    3. Text Editor > Advanced > uncheck "Use adaptive formatting"

Quick Start

The project is structured as an Unreal Engine plugin. To quickly get started, we have an Unreal Engine starter project that already includes a reference to plugin. To use it:

  1. In GitHub Desktop:
    1. File > Clone repository > URL tab
    2. URL: https://github.com/Leroy231/ProjectMStarter.git
    3. Local path: choose a folder on your machine where you want the Unreal Engine project created
    4. Click Clone
  2. In Windows Explorer double click the .uproject at the root of the folder where you cloned the project.
  3. You should get a prompt about missing modules. Click Yes to build them.
  4. Note that you won't see any progress while it's building, just be patient. If you want to make sure it's building, open Task Manager and you should see Microsoft C++ Compiler using CPU. On an Intel Core i7-9700K CPU @ 3.60GHz this took about 3 minutes.
  5. When it's done, it should open the project in Unreal Engine. Now move onto the next section below.

Add Assets

  1. First confirm that the ProjectM folder shows up in your Content Drawer under Plugins. If you don't see Plugins, click Settings button on top right of Content Drawer > Show Plugin Content.
  2. Add Content Packs from Content Drawer > Add > Add Feature or Content Pack > Blueprint
    1. First Person > Add to project.
    2. Third Person > Add to project.
  3. Add Unreal Engine Marketplace free content to project. Note that some of this content hasn't been migrated to UE5 yet, so when you try to add it from the Epic Games Launcher, check "Show all projects" after clicking "Add to Project". Then in the "Select Version" dropdown select the newest version in the list.
    1. Military Weapons Silver
    2. M1A1 Abrams Tank
    3. Realistic Starter VFX Pack Vol 2
    4. Animation Starter Pack
  4. Now in Content Drawer open "Plugins/ProjectM Content/Playgrounds/Maps/L_MediumWithTanks" level and use PIE to test out the project.
    1. You might have to build NavMesh paths via menu for move commands to work: Build > Build Paths.

Adding Plugin to Existing Project

  1. If you want to use the City Sample project for developing in a large level, get the project from UE Marketplace and then create a project using that template.
  2. If there is no .sln in the project folder, generate VS project from right clicking .uproject in project folder.
  3. Open .sln in Visual Studio if it isn't already open.
  4. If project isn't open yet in UE, run the project from VS.
  5. Enable the required plugins in UE project if they are not already:
    1. Edit > Plugins
    2. Search for "mass"
    3. Check MassAI, MassCrowd, MassEntity, MassGameplay. Answer Yes if it asks if you're sure.
  6. Quit UE.
  7. In PowerShell:
    1. cd to project folder. This is the folder that has the .uproject file.
    2. If Plugins folder does not exist, mkdir Plugins.
    3. cd Plugins
    4. git clone https://github.com/Leroy231/OnAllFronts.git
    5. If in City Sample: rmdir -recurse AnimToTexture
    6. git clone --branch projectm https://github.com/Leroy231/AnimToTexture.git
  8. Right click the .uproject file again and re-generate the solution to get the new files from the Plugins folder to show in VS.
  9. In order to get Mass ParallelForEachEntityChunk to actually parallelize, it requires passing an argument to editor on launch:
    1. In VS Solution Explorer, right click the project under Games folder > Properties.
    2. Debugging > Command Arguments > Add " -ParallelMassQueries=1" to the end (without quotes).
  10. Rerun project from VS.
  11. Edit > Project Settings
    1. Engine - Input > Bindings
      1. Ensure you have all the AxisMappings and ActionMappings from here: https://github.com/Leroy231/ProjectMStarter/blob/main/Config/DefaultInput.ini
    2. Engine - Mass
      1. Search for "MassUpdateISMProcessor" > Mass > Module Settings > Mass Entity > Processor CDOs > Index (for MassUpdateISMProcessor) > Auto Register with Processing Phases > uncheck. Note this will already be unchecked in the City Sample project.
      2. Search for "MassGenericUpdateISMVertexAnimationProcessor" > Mass > Module Settings > Mass Entity > Processor CDOs > Index (for MassGenericUpdateISMVertexAnimationProcessor) > Auto Register with Processing Phases > check
      3. Do the same as previous for "MassSimpleUpdateISMProcessor".
    3. Engine - Navigation System > Agents > Supported Agents > Add agents based on the "SupportedAgents" towards bottom of this file: https://github.com/Leroy231/ProjectMStarter/blob/main/Config/DefaultEngine.ini
      1. Only the Name, Nav Agent Radius, and Nav Agent Height need to be set.
  12. Follow steps above in Add Assets section.

To add soldiers to City Sample Level

  1. Duplicate Small_City_LVL and call it Small_City_ProjectM_LVL
  2. Open Small_City_ProjectM_LVL
  3. Delete Actors
    1. Mass Spawners: BP_MassTraffic* and BP_MassCrowdSpawner
    2. BP_CitySampleWorldInfo
    3. BP_Nightmode
    4. SmartObjectCollection
  4. Open L_Template
  5. Copy PM_* actors
  6. Paste in Small_City_ProjectM_LVL. Ensure locations of all actors were preserved.
  7. Set up world info
    1. Select actor "PM_WorldInfo"
    2. Details pane > Sim > Sunlight > set "Sun Light" to "DirectionalLight_WP"
    3. Set "Sky Dome" to "SM_dome"
  8. From menu: Build > Build ZoneGraph
  9. Select each PM_MilitaryUnitMassSpawner* actor > Details > World Partition > Is Spatially Loaded > uncheck
  10. World Settings > GameMode Override > BP_FirstPersonGameModeCommander
  11. We need to make collisions loaded all the time because AI soldiers rely on them to determine if they have line of sight to enemies:
    1. Load all cells in World Partition
    2. While we've got all cells loaded, build NavMesh from menu: Build > Build Paths
    3. In Outliner search for "coll"
    4. Click on any actor in the Outliner and select all (Ctrl+A)
    5. Details > World Partition > Is Spatially Loaded > uncheck
    6. World Partition: Unload all cells and load any if desired

onallfronts-public's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

onallfronts-public's Issues

Fix occasional crash related to clean up of Mass created actors when stopping play

  • Seems to happen with "Human_Character_AI_BLUFOR_C"_6 actor. Can happen after simply starting and then stopping the level.
  • For non-soldiers: It's possible this happens because some of the effect actors get destroyed by Mass system due to delayed destruction trait, but also because the actor blueprint has a destroy actor call after some delay. We should only do the entity delayed destruction?

Log message:

Assertion failed: IsEntityValid(Entity) [File:D:\build\++UE5\Sync\Engine\Plugins\Runtime\MassEntity\Source\MassEntity\Private\MassEntityManager.cpp] [Line: 1147] 
Invalid entity (ID: 67, SN:67, already destroyed)

Call Stack:

 	UnrealEditor-MassEntity.dll!FMassEntityManager::CheckIfEntityIsValid(FMassEntityHandle Entity) Line 1146	C++
 	[Inline Frame] UnrealEditor-MassEntity.dll!FMassEntityManager::IsEntityBuilt(FMassEntityHandle) Line 1140	C++
 	[Inline Frame] UnrealEditor-MassEntity.dll!FMassEntityManager::CheckIfEntityIsActive(FMassEntityHandle) Line 1152	C++
 	UnrealEditor-MassEntity.dll!FMassEntityManager::RemoveCompositionFromEntity(FMassEntityHandle Entity, const FMassArchetypeCompositionDescriptor & InDescriptor) Line 691	C++
>	UnrealEditor-MassActors.dll!UMassAgentSubsystem::UnregisterAgentComponent(UMassAgentComponent & AgentComp) Line 204	C++
 	[Inline Frame] UnrealEditor-MassActors.dll!UMassAgentSubsystem::ShutdownAgentComponent(UMassAgentComponent &) Line 252	C++
 	UnrealEditor-MassActors.dll!UMassAgentComponent::UnregisterWithAgentSubsystem() Line 126	C++
 	UnrealEditor-MassActors.dll!UMassAgentComponent::OnUnregister() Line 148	C++
 	UnrealEditor-Engine.dll!UActorComponent::ExecuteUnregisterEvents() Line 1707	C++
 	UnrealEditor-Engine.dll!UActorComponent::UnregisterComponent() Line 1423	C++
 	UnrealEditor-Engine.dll!AActor::UnregisterAllComponents(bool bForReregister) Line 5166	C++
 	UnrealEditor-Engine.dll!ULevel::ClearLevelComponents() Line 1376	C++
 	UnrealEditor-Engine.dll!UWorld::ClearWorldComponents() Line 2254	C++
 	UnrealEditor-Engine.dll!UWorld::CleanupWorldInternal(bool bSessionEnded, bool bCleanupResources, bool bWorldChanged) Line 4975	C++
 	UnrealEditor-Engine.dll!UWorld::CleanupWorld(bool bSessionEnded, bool bCleanupResources, UWorld * NewWorld) Line 4914	C++
 	UnrealEditor-UnrealEd.dll!UEditorEngine::TeardownPlaySession(FWorldContext & PieWorldContext) Line 873	C++
 	UnrealEditor-UnrealEd.dll!UEditorEngine::EndPlayMap() Line 339	C++
 	UnrealEditor-UnrealEd.dll!UEditorEngine::Tick(float DeltaSeconds, bool bIdleMode) Line 2210	C++
 	UnrealEditor-UnrealEd.dll!UUnrealEdEngine::Tick(float DeltaSeconds, bool bIdleMode) Line 517	C++
 	UnrealEditor-Win64-DebugGame.exe!FEngineLoop::Tick() Line 5369	C++
 	[Inline Frame] UnrealEditor-Win64-DebugGame.exe!EngineTick() Line 66	C++
 	UnrealEditor-Win64-DebugGame.exe!GuardedMain(const wchar_t * CmdLine) Line 202	C++
 	UnrealEditor-Win64-DebugGame.exe!LaunchWindowsStartup(HINSTANCE__ * hInInstance, HINSTANCE__ * hPrevInstance, char * __formal, int nCmdShow, const wchar_t * CmdLine) Line 233	C++
 	UnrealEditor-Win64-DebugGame.exe!WinMain(HINSTANCE__ * hInInstance, HINSTANCE__ * hPrevInstance, char * pCmdLine, int nCmdShow) Line 282	C++
 	[Inline Frame] UnrealEditor-Win64-DebugGame.exe!invoke_main() Line 102	C++
 	UnrealEditor-Win64-DebugGame.exe!__scrt_common_main_seh() Line 288	C++
 	kernel32.dll!00007ffe3a0926bd()	Unknown
 	ntdll.dll!00007ffe3b06a9f8()	Unknown

Platoon column formation

When ordering a platoon to move somewhere, order them to be spread out instead of all squads on top of each other.

Note there's a bug currently where the unit will always move to the map center. That will be fixed separately.

Work off branch: https://github.com/LeroyTechnologies-Org/ProjectMStarter-Private/tree/platoon-column-formation

To set up this scenario:

  1. Open map L_MediumWithObstacles
  2. Run console command pm.UMassEnemyTargetFinderProcessor_SkipFindingTargets 1 so that soldiers don't engage enemies.
  3. Play the level
  4. "m" to open map
  5. Expand the left tree to select a platoon
  6. Right click map and choose "Order Move to Here"
  7. Run console command slomo 10 so soldiers move faster
  8. Notice how the entire platoon goes to the same location.

Requirements:

  • Check via nav mesh that there's room for each squad at or near the destination location to be in platoon column formation. If there isn't, revert to the existing behavior.
  • We should still project to the nav mesh for each squad's center point, but only allow a small extent away from the point on the x/y axes (z axis can be larger).
  • Make the platoon end up in platoon column formation at the destination if valid
  • You can ignore the platoon leader for now.

Code pointers:

  • When right clicking on the map to order units to move, it calls UProjectMBlueprintFunctionLibrary::SetMoveToCommand. One way to implement this feature would be to add a check in that function if the selected unit is a platoon (SelectedUnit->Depth == 5), and if so, to call MoveToCommandSystem->EnqueueMoveToCommand for each squad with the appropriate coordinates. To handle invalid locations for now we can handle it like the other error checks in that function, just call AddOnScreenDebugMessage and return.
  • FMassNavMeshMoveTask::GetNavigationPath may be useful since it already does some NavMesh projection logic.

Improved ammo HUD

We should have a magazine icon for each magazine with 5 different states based on how full it is: 100%, 75%, 50%, 25%, 0%

In Player_WBP we have a hidden widget with the icons for these ammo states:

Image

Also in that widget we have functions "Get Index_*" for getting the ammo count for each magazine:

Image

Requirements:

  • Update the layout of the ammo HUD to look like:
    Image
  • Logic for which image to use should be based on percent ammo left in magazine. Assume 30 bullets means 100%.
    • 100% ammo left: rifle-magazine-100-percent-white
    • 62.5% <= ammo left < 100%: rifle-magazine-75-percent-white
    • 37.5% <= ammo left < 62.5%: rifle-magazine-50-percent-white
    • 0% < ammo left < 37.5%: rifle-magazine-25-percent-white
    • 0% ammo left: rifle-magazine-0-percent-white
  • The current magazine should always be shown as the right most icon. To get the current magazine index, there's a C++ function GetMagazineIndexFromMass on the PlayerCharacter exposed to Blueprints.
  • Fix white squares on initial render

Show final soldier counts on game over screen

Currently the game over screen looks like this, in BP_GameOverWidget:

Image

We want to add the soldier counts for each team on this widget. To test this more easily, you can run console command pm.ForceGameOver to make it show up.

Requirements:

  • In between the "you won/you lost" text and above the "Play again" button, add the following text:

Final Soldier Counts

Team 1: A
Team 2: B

  • Replace A/B above with the actual soldier counts. You can get these via C++ function GetTeamSoldierCounts which is exposed to Blueprints.

Map: Show threats?

  • We could perhaps show locations of recent threats, or recent enemy sounds the team has heard with some radius, instead of single points.

Fix body sliding during death animation when moving camera

Steps to reproduce:

  • order troops to move somewhere and kill the ones moving.
  • Look away from the dying soldier so they just leave your screen and then look back
  • The soldier will start sliding temporarily while they are dead.

Potential fix: Ensure on death we set FMassMoveTargetFragment with EMassMovementAction::Animate action since UMassSteerToMoveTargetProcessor will set force/velocity to zero in this case.

Improve projectile collisions

Currently projectile collisions are based on 2D obstacle grid, which is fast, but inaccurate. If collision is detected via obstacle grid, then an actual collision check should be performed. This likely would fix the issue where firing a projectile can hit the shooter sometimes currently.

Objectives Widget

We need to show the player their objectives. It should show on a widget with the following text (screenshot below):

Objectives


  • Take control of the city
  • Eliminate enough enemy soldiers until your team's number of soldiers (9,346) is twice as much as the enemy team's number of soldiers (approx. 8,000)

Requirements:

Image

Improve FPS of map widget on large levels

Some options:

  1. If performance is slow because of updating many buttons each frame, and not because of the number of buttons rendered:
    1. Slow tickrate of widget
    2. Variable tickrate based on simulation LOD trait
    3. We may already do this: Only update buttons for a soldier when that soldier moves
  2. If performance is slow because of number of buttons, even when not updating them:
    1. When zoomed out, group soldiers together into circles or polygons and only show buttons for each soldier when at maximum zoom

Map widget is in WBP_MapWidget (which subclasses C++ class UProjectMMapWidget2).

Gameplay debugger doesn't show player's Mass collision capsule

Can verify with gameplay debugger (' key) then shift+u (show mass capsules), then v (show third person).
It's possible that the Mass collision capsule is there but we don't render it in gameplay debugger since player might be missing some fragment we require in that render query.

Enemy target finder: Cull out potential entities based on a max FOV

Setup steps:

  1. Open L_MediumWithTanks level
  2. Run this console command to skip dealing damage: pm.UMassProjectileDamageProcessor_SkipDealingDamage 1
  3. Run this console command to skip assigning a target entity: pm.UMassEnemyTargetFinderProcessor_SkipUpdatingTargetEntity 1
  4. Play in editor
  5. Press ' (quote) key to bring up gameplay debugger
  6. Move around to find an entity you want to debug and find the entity's index in the overlay on top of them after the "i:", for example 25 here:
    image
  7. Run this console command to debug that entity (replace 25 with the index of the entity you want to debug): ai.debug.mass.DebugEntity 25
  8. Press numpad 5 key to hide the Mass debugger. You'll see something like this:
    image
  9. Every cylinder/line is a target entity that was considered. The colors mean:
    1. Red: ignored due to same team
    2. Yellow: ignored due to another entity in the way
    3. Blue: ignored due to out of maximum shooting range
    4. Black: ignored due to no line of sight
    5. Orange: ignored due to inability to damage (e.g. soldier can't damage a tank)
    6. Green: selected target

Now in this task we want to ignore targets that are outside the field of view (FOV) of where the entity is looking. To do so:

  1. Here is where we skip targets because they are out of range. After that check, we should add another check if a target is outside the FOV and if so, call continue.
  2. To find the smallest angle between two headings, here's an example of where we do that.
  3. To add a new color for the gameplay debugger for these entities that are ignored due to FOV, add one here.
  4. After you make your changes, press Ctrl+Alt+F11 to live reload the changes. Just make sure to stop play in editor first as changing the code while you're playing in editor can lead to crashes and other strange issues.

Match default movement speed of player and AI soldiers

Consider a default movement speed like walking speed in Squad.

  • In Human_Character, remove "jog" references
  • In Commandable trait, replace"Movement Speed" with FMassMovementParameters.MaxSpeed and replace "Cautious Movement Speed" with FMassMovementParameters.DefaultDesiredSpeed
  • In DA_MassSoldierBase, in Movement Trait, set MaxSpeed to 450 and DefaultDesiredSpeed to 140.0
  • In Human_Character
    • In Init Character Movement function, delete "Set Max Ground Speed"
    • In "Event On Entity Associated", we should query Mass for the default desired speed of Movement trait and "Set Max Ground Speed" on that. Add C++ function to UMassCharacterBlueprintLibrary.
    • In BP_Human_Character_OnBeginPlay's OnHumanCharacterUnpossessed macro, "Set Max Ground Speed" to the Movement trait's Max Speed. Add C++ function to UMassCharacterBlueprintLibrary.
    • Also in Movement Tick function, for other "Set Max Ground Speed" calls, instead of hard-coding a value, use the 2 helper functions added above in UMassCharacterBlueprintLibrary.
    • In "Event On Aim Change" delete logic related to movement speed

Code pointers for movement speed:

  • UMyCharacterMovementComponent::GetMaxSpeed
  • Human_Character
    • Init Character Movement function calls "Set Max Ground Speed"
    • MovementTick function: If player controlled, then calls "Set Max Ground Speed"
    • "Event On Aim Change"
  • DA_MassSoldierBase
    • Movement trait > Max Speed
    • Commandable trait > Movement Speed / Cautious Movement Speed

Debugging tips:

  • In gameplay debugger, press shift+Z and you can see IsCautious value

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.